From owner-svn-src-all@freebsd.org Thu Dec 10 07:16:35 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D9ADE9D523D; Thu, 10 Dec 2015 07:16:35 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B252E1852; Thu, 10 Dec 2015 07:16:35 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tBA7GLKi005473; Thu, 10 Dec 2015 07:16:21 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tBA7GLLl005469; Thu, 10 Dec 2015 07:16:21 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201512100716.tBA7GLLl005469@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Thu, 10 Dec 2015 07:16:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292051 - head/sys/dev/sfxge/common X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Dec 2015 07:16:36 -0000 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 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;