sfc: Refactor efx_mcdi_rpc_start() and efx_mcdi_copyin()
Preparation for asynchronous MCDI requests.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 63121ad..89bc194 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -70,8 +70,8 @@
kfree(efx->mcdi);
}
-static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
- const efx_dword_t *inbuf, size_t inlen)
+static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
+ const efx_dword_t *inbuf, size_t inlen)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
efx_dword_t hdr[2];
@@ -80,6 +80,11 @@
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;
xflags = 0;
if (mcdi->mode == MCDI_MODE_EVENTS)
@@ -114,6 +119,8 @@
}
efx->type->mcdi_request(efx, hdr, hdr_len, inbuf, inlen);
+
+ mcdi->new_epoch = false;
}
static int efx_mcdi_errno(unsigned int mcdi_err)
@@ -340,6 +347,22 @@
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,
const efx_dword_t *inbuf, size_t inlen,
efx_dword_t *outbuf, size_t outlen,
@@ -358,26 +381,14 @@
const efx_dword_t *inbuf, size_t inlen)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+ int rc;
- 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;
+ rc = efx_mcdi_check_supported(efx, cmd, inlen);
+ if (rc)
+ return rc;
efx_mcdi_acquire(mcdi);
-
- /* 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;
+ efx_mcdi_send_request(efx, cmd, inbuf, inlen);
return 0;
}