Date: Thu, 14 Jan 2016 15:27:50 +0000 (UTC) From: Andrew Rybchenko <arybchik@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r293963 - stable/10/sys/dev/sfxge/common Message-ID: <201601141527.u0EFRooh043324@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: arybchik Date: Thu Jan 14 15:27:49 2016 New Revision: 293963 URL: https://svnweb.freebsd.org/changeset/base/293963 Log: MFC r292051 sfxge: [6/6] support for MCDI proxy authorization in common code Submitted by: Andy Moreton <amoreton at solarflare.com> Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/efx.h stable/10/sys/dev/sfxge/common/efx_mcdi.c stable/10/sys/dev/sfxge/common/efx_mcdi.h stable/10/sys/dev/sfxge/common/hunt_ev.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/efx.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efx.h Thu Jan 14 15:26:58 2016 (r293962) +++ stable/10/sys/dev/sfxge/common/efx.h Thu Jan 14 15:27:49 2016 (r293963) @@ -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: stable/10/sys/dev/sfxge/common/efx_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:26:58 2016 (r293962) +++ stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:27:49 2016 (r293963) @@ -299,6 +299,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, @@ -319,6 +334,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: @@ -460,6 +478,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); @@ -581,11 +602,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: stable/10/sys/dev/sfxge/common/efx_mcdi.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_mcdi.h Thu Jan 14 15:26:58 2016 (r293962) +++ stable/10/sys/dev/sfxge/common/efx_mcdi.h Thu Jan 14 15:27:49 2016 (r293963) @@ -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: stable/10/sys/dev/sfxge/common/hunt_ev.c ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_ev.c Thu Jan 14 15:26:58 2016 (r293962) +++ stable/10/sys/dev/sfxge/common/hunt_ev.c Thu Jan 14 15:27:49 2016 (r293963) @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601141527.u0EFRooh043324>