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.
This commit is contained in:
parent
aec7138125
commit
c98bc0b5ee
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user