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

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
Loading
Loading
Loading
Loading
+30 −19
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ void efx_mcdi_fini(struct efx_nic *efx)
	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)
{
	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
@@ -80,6 +80,11 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,

	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 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
	}

	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 @@ static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno,
		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 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
		       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;
}