Commit 2f4bcdcc authored by Ben Hutchings's avatar Ben Hutchings

sfc: Refactor efx_mcdi_rpc_start() and efx_mcdi_copyin()

Preparation for asynchronous MCDI requests.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 38589cdc
...@@ -70,7 +70,7 @@ void efx_mcdi_fini(struct efx_nic *efx) ...@@ -70,7 +70,7 @@ void efx_mcdi_fini(struct efx_nic *efx)
kfree(efx->mcdi); kfree(efx->mcdi);
} }
static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen) const efx_dword_t *inbuf, size_t inlen)
{ {
struct efx_mcdi_iface *mcdi = efx_mcdi(efx); struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
...@@ -80,6 +80,11 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, ...@@ -80,6 +80,11 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
/* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
spin_lock_bh(&mcdi->iface_lock);
++mcdi->seqno;
spin_unlock_bh(&mcdi->iface_lock);
seqno = mcdi->seqno & SEQ_MASK; seqno = mcdi->seqno & SEQ_MASK;
xflags = 0; xflags = 0;
if (mcdi->mode == MCDI_MODE_EVENTS) if (mcdi->mode == MCDI_MODE_EVENTS)
...@@ -114,6 +119,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, ...@@ -114,6 +119,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
} }
efx->type->mcdi_request(efx, hdr, hdr_len, inbuf, inlen); efx->type->mcdi_request(efx, hdr, hdr_len, inbuf, inlen);
mcdi->new_epoch = false;
} }
static int efx_mcdi_errno(unsigned int mcdi_err) static int efx_mcdi_errno(unsigned int mcdi_err)
...@@ -340,6 +347,22 @@ static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno, ...@@ -340,6 +347,22 @@ static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno,
efx_mcdi_complete(mcdi); efx_mcdi_complete(mcdi);
} }
static int
efx_mcdi_check_supported(struct efx_nic *efx, unsigned int cmd, size_t inlen)
{
if (efx->type->mcdi_max_ver < 0 ||
(efx->type->mcdi_max_ver < 2 &&
cmd > MC_CMD_CMD_SPACE_ESCAPE_7))
return -EINVAL;
if (inlen > MCDI_CTL_SDU_LEN_MAX_V2 ||
(efx->type->mcdi_max_ver < 2 &&
inlen > MCDI_CTL_SDU_LEN_MAX_V1))
return -EMSGSIZE;
return 0;
}
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen, const efx_dword_t *inbuf, size_t inlen,
efx_dword_t *outbuf, size_t outlen, efx_dword_t *outbuf, size_t outlen,
...@@ -358,26 +381,14 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, ...@@ -358,26 +381,14 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen) const efx_dword_t *inbuf, size_t inlen)
{ {
struct efx_mcdi_iface *mcdi = efx_mcdi(efx); struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
int rc;
if (efx->type->mcdi_max_ver < 0 || rc = efx_mcdi_check_supported(efx, cmd, inlen);
(efx->type->mcdi_max_ver < 2 && if (rc)
cmd > MC_CMD_CMD_SPACE_ESCAPE_7)) return rc;
return -EINVAL;
if (inlen > MCDI_CTL_SDU_LEN_MAX_V2 ||
(efx->type->mcdi_max_ver < 2 &&
inlen > MCDI_CTL_SDU_LEN_MAX_V1))
return -EMSGSIZE;
efx_mcdi_acquire(mcdi); efx_mcdi_acquire(mcdi);
efx_mcdi_send_request(efx, cmd, inbuf, inlen);
/* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
spin_lock_bh(&mcdi->iface_lock);
++mcdi->seqno;
spin_unlock_bh(&mcdi->iface_lock);
efx_mcdi_copyin(efx, cmd, inbuf, inlen);
mcdi->new_epoch = false;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment