svn commit: r292051 - head/sys/dev/sfxge/common

Andrew Rybchenko arybchik at FreeBSD.org
Thu Dec 10 07:16:36 UTC 2015


Author: arybchik
Date: Thu Dec 10 07:16:21 2015
New Revision: 292051
URL: https://svnweb.freebsd.org/changeset/base/292051

Log:
  sfxge: [6/6] support for MCDI proxy authorization in common code
  
  Submitted by:   Andy Moreton <amoreton at solarflare.com>
  Sponsored by:   Solarflare Communications, Inc.
  MFC after:      1 week
  Differential Revision: https://reviews.freebsd.org/D4454

Modified:
  head/sys/dev/sfxge/common/efx.h
  head/sys/dev/sfxge/common/efx_mcdi.c
  head/sys/dev/sfxge/common/efx_mcdi.h
  head/sys/dev/sfxge/common/hunt_ev.c

Modified: head/sys/dev/sfxge/common/efx.h
==============================================================================
--- head/sys/dev/sfxge/common/efx.h	Thu Dec 10 07:15:09 2015	(r292050)
+++ head/sys/dev/sfxge/common/efx.h	Thu Dec 10 07:16:21 2015	(r292051)
@@ -218,6 +218,9 @@ typedef struct efx_mcdi_transport_s {
 	void		(*emt_logger)(void *, efx_log_msg_t,
 					void *, size_t, void *, size_t);
 #endif /* EFSYS_OPT_MCDI_LOGGING */
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	void		(*emt_ev_proxy_response)(void *, uint32_t, efx_rc_t);
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
 } efx_mcdi_transport_t;
 
 extern	__checkReturn	efx_rc_t

Modified: head/sys/dev/sfxge/common/efx_mcdi.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_mcdi.c	Thu Dec 10 07:15:09 2015	(r292050)
+++ head/sys/dev/sfxge/common/efx_mcdi.c	Thu Dec 10 07:16:21 2015	(r292051)
@@ -302,6 +302,21 @@ efx_mcdi_read_response_header(
 		emrp->emr_err_code = err_code;
 		emrp->emr_err_arg = err_arg;
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+		if ((err_code == MC_CMD_ERR_PROXY_PENDING) &&
+		    (err_len == sizeof (err))) {
+			/*
+			 * The MCDI request would normally fail with EPERM, but
+			 * firmware has forwarded it to an authorization agent
+			 * attached to a privileged PF.
+			 *
+			 * Save the authorization request handle. The client
+			 * must wait for a PROXY_RESPONSE event, or timeout.
+			 */
+			emrp->emr_proxy_handle = err_arg;
+		}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 #if EFSYS_OPT_MCDI_LOGGING
 		if (emtp->emt_logger != NULL) {
 			emtp->emt_logger(emtp->emt_context,
@@ -322,6 +337,9 @@ efx_mcdi_read_response_header(
 
 	emrp->emr_rc = 0;
 	emrp->emr_out_length_used = data_len;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	emrp->emr_proxy_handle = 0;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
 	return;
 
 fail3:
@@ -463,6 +481,9 @@ efx_mcdi_request_errcode(
 	case MC_CMD_ERR_MAC_EXIST:
 		return (EEXIST);
 
+	case MC_CMD_ERR_PROXY_PENDING:
+		return (EAGAIN);
+
 	default:
 		EFSYS_PROBE1(mc_pcol_error, int, err);
 		return (EIO);
@@ -584,11 +605,70 @@ efx_mcdi_ev_cpl(
 			emrp->emr_rc = 0;
 		}
 	}
-	emcop->emco_request_copyout(enp, emrp);
+	if (errcode == 0) {
+		emcop->emco_request_copyout(enp, emrp);
+	}
 
 	emtp->emt_ev_cpl(emtp->emt_context);
 }
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+
+	__checkReturn	efx_rc_t
+efx_mcdi_get_proxy_handle(
+	__in		efx_nic_t *enp,
+	__in		efx_mcdi_req_t *emrp,
+	__out		uint32_t *handlep)
+{
+	efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+	efx_rc_t rc;
+
+	/*
+	 * Return proxy handle from MCDI request that returned with error
+	 * MC_MCD_ERR_PROXY_PENDING. This handle is used to wait for a matching
+	 * PROXY_RESPONSE event.
+	 */
+	if ((emrp == NULL) || (handlep == NULL)) {
+		rc = EINVAL;
+		goto fail1;
+	}
+	if ((emrp->emr_rc != 0) &&
+	    (emrp->emr_err_code == MC_CMD_ERR_PROXY_PENDING)) {
+		*handlep = emrp->emr_proxy_handle;
+		rc = 0;
+	} else {
+		*handlep = 0;
+		rc = ENOENT;
+	}
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+			void
+efx_mcdi_ev_proxy_response(
+	__in		efx_nic_t *enp,
+	__in		unsigned int handle,
+	__in		unsigned int status)
+{
+	const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+	efx_rc_t rc;
+
+	/*
+	 * Handle results of an authorization request for a privileged MCDI
+	 * command. If authorization was granted then we must re-issue the
+	 * original MCDI request. If authorization failed or timed out,
+	 * then the original MCDI request should be completed with the
+	 * result code from this event.
+	 */
+	rc = (status == 0) ? 0 : efx_mcdi_request_errcode(status);
+
+	emtp->emt_ev_proxy_response(emtp->emt_context, handle, rc);
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 			void
 efx_mcdi_ev_death(
 	__in		efx_nic_t *enp,

Modified: head/sys/dev/sfxge/common/efx_mcdi.h
==============================================================================
--- head/sys/dev/sfxge/common/efx_mcdi.h	Thu Dec 10 07:15:09 2015	(r292050)
+++ head/sys/dev/sfxge/common/efx_mcdi.h	Thu Dec 10 07:16:21 2015	(r292051)
@@ -62,6 +62,9 @@ struct efx_mcdi_req_s {
 	/* Internals: low level transport details */
 	unsigned int	emr_err_code;
 	unsigned int	emr_err_arg;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	uint32_t	emr_proxy_handle;
+#endif
 };
 
 typedef struct efx_mcdi_iface_s {
@@ -97,6 +100,20 @@ efx_mcdi_ev_cpl(
 	__in		unsigned int outlen,
 	__in		int errcode);
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	__checkReturn	efx_rc_t
+efx_mcdi_get_proxy_handle(
+	__in		efx_nic_t *enp,
+	__in		efx_mcdi_req_t *emrp,
+	__out		uint32_t *handlep);
+
+extern			void
+efx_mcdi_ev_proxy_response(
+	__in		efx_nic_t *enp,
+	__in		unsigned int handle,
+	__in		unsigned int status);
+#endif
+
 extern			void
 efx_mcdi_ev_death(
 	__in		efx_nic_t *enp,

Modified: head/sys/dev/sfxge/common/hunt_ev.c
==============================================================================
--- head/sys/dev/sfxge/common/hunt_ev.c	Thu Dec 10 07:15:09 2015	(r292050)
+++ head/sys/dev/sfxge/common/hunt_ev.c	Thu Dec 10 07:16:21 2015	(r292051)
@@ -829,6 +829,20 @@ hunt_ev_mcdi(
 		    MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
 		break;
 
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+	case MCDI_EVENT_CODE_PROXY_RESPONSE:
+		/*
+		 * This event notifies a function that an authorization request
+		 * has been processed. If the request was authorized then the
+		 * function can now re-send the original MCDI request.
+		 * See SF-113652-SW "SR-IOV Proxied Network Access Control".
+		 */
+		efx_mcdi_ev_proxy_response(enp,
+		    MCDI_EV_FIELD(eqp, PROXY_RESPONSE_HANDLE),
+		    MCDI_EV_FIELD(eqp, PROXY_RESPONSE_RC));
+		break;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
 	case MCDI_EVENT_CODE_LINKCHANGE: {
 		efx_link_mode_t link_mode;
 


More information about the svn-src-head mailing list