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;
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to