summaryrefslogtreecommitdiffstats
path: root/sys/dev/sfxge
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2016-01-14 16:21:58 +0000
committerarybchik <arybchik@FreeBSD.org>2016-01-14 16:21:58 +0000
commit434136afdbd094ca9adaf26e5c1034502e447f39 (patch)
tree9e7f6406d6de6b1e60908e5d6e0feb8e81a0f308 /sys/dev/sfxge
parent2284ae3cdc0efdca84b0315130e21f558f8710b1 (diff)
downloadFreeBSD-src-434136afdbd094ca9adaf26e5c1034502e447f39.zip
FreeBSD-src-434136afdbd094ca9adaf26e5c1034502e447f39.tar.gz
MFC r293809
sfxge: simplify MCDI request start Submitted by: Andy Moreton <amoreton at solarflare.com> Reviewed by: gnn Sponsored by: Solarflare Communications, Inc.
Diffstat (limited to 'sys/dev/sfxge')
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c84
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c64
2 files changed, 92 insertions, 56 deletions
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
index d23259e..f9c73b4 100644
--- a/sys/dev/sfxge/common/hunt_mcdi.c
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -140,6 +140,48 @@ ef10_mcdi_fini(
emip->emi_new_epoch = B_FALSE;
}
+static void
+ef10_mcdi_send_request(
+ __in efx_nic_t *enp,
+ __in void *hdrp,
+ __in size_t hdr_len,
+ __in void *sdup,
+ __in size_t sdu_len)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_dword_t dword;
+ unsigned int pos;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ /* Write the header */
+ for (pos = 0; pos < hdr_len; pos += sizeof (efx_dword_t)) {
+ dword = *(efx_dword_t *)((uint8_t *)hdrp + pos);
+ EFSYS_MEM_WRITED(esmp, pos, &dword);
+ }
+
+ /* Write the payload */
+ for (pos = 0; pos < sdu_len; pos += sizeof (efx_dword_t)) {
+ dword = *(efx_dword_t *)((uint8_t *)sdup + pos);
+ EFSYS_MEM_WRITED(esmp, hdr_len + pos, &dword);
+ }
+
+ /* Guarantee ordering of memory (MCDI request) and PIO (MC doorbell) */
+ EFSYS_DMA_SYNC_FOR_DEVICE(esmp, 0, hdr_len + sdu_len);
+ EFSYS_PIO_WRITE_BARRIER();
+
+ /* Ring the doorbell to post the command DMA address to the MC */
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0,
+ EFSYS_MEM_ADDR(esmp) >> 32);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_LWRD_REG, &dword, B_FALSE);
+
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0,
+ EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+}
+
void
ef10_mcdi_request_copyin(
__in efx_nic_t *enp,
@@ -148,14 +190,13 @@ ef10_mcdi_request_copyin(
__in boolean_t ev_cpl,
__in boolean_t new_epoch)
{
+#if EFSYS_OPT_MCDI_LOGGING
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
- efsys_mem_t *esmp = emtp->emt_dma_mem;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
efx_mcdi_header_type_t hdr_type;
- efx_dword_t dword;
efx_dword_t hdr[2];
+ size_t hdr_len;
unsigned int xflags;
- unsigned int pos;
- size_t offset;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
@@ -164,13 +205,12 @@ ef10_mcdi_request_copyin(
if (ev_cpl)
xflags |= MCDI_HEADER_XFLAGS_EVREQ;
- offset = 0;
-
hdr_type = EFX_MCDI_HEADER_TYPE(emrp->emr_cmd,
MAX(emrp->emr_in_length, emrp->emr_out_length));
if (hdr_type == EFX_MCDI_HEADER_TYPE_V2) {
/* Construct MCDI v2 header */
+ hdr_len = sizeof (hdr);
EFX_POPULATE_DWORD_8(hdr[0],
MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
MCDI_HEADER_RESYNC, 1,
@@ -180,16 +220,13 @@ ef10_mcdi_request_copyin(
MCDI_HEADER_ERROR, 0,
MCDI_HEADER_RESPONSE, 0,
MCDI_HEADER_XFLAGS, xflags);
- EFSYS_MEM_WRITED(esmp, offset, &hdr[0]);
- offset += sizeof (efx_dword_t);
EFX_POPULATE_DWORD_2(hdr[1],
MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
- EFSYS_MEM_WRITED(esmp, offset, &hdr[1]);
- offset += sizeof (efx_dword_t);
} else {
/* Construct MCDI v1 header */
+ hdr_len = sizeof (hdr[0]);
EFX_POPULATE_DWORD_8(hdr[0],
MCDI_HEADER_CODE, emrp->emr_cmd,
MCDI_HEADER_RESYNC, 1,
@@ -199,39 +236,18 @@ ef10_mcdi_request_copyin(
MCDI_HEADER_ERROR, 0,
MCDI_HEADER_RESPONSE, 0,
MCDI_HEADER_XFLAGS, xflags);
- EFSYS_MEM_WRITED(esmp, 0, &hdr[0]);
- offset += sizeof (efx_dword_t);
}
#if EFSYS_OPT_MCDI_LOGGING
if (emtp->emt_logger != NULL) {
emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
- &hdr, offset,
+ &hdr, hdr_len,
emrp->emr_in_buf, emrp->emr_in_length);
}
#endif /* EFSYS_OPT_MCDI_LOGGING */
- /* Construct the payload */
- for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
- memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
- MIN(sizeof (dword), emrp->emr_in_length - pos));
- EFSYS_MEM_WRITED(esmp, offset + pos, &dword);
- }
-
- /* Ring the doorbell to post the command DMA address to the MC */
- EFSYS_ASSERT((EFSYS_MEM_ADDR(esmp) & 0xFF) == 0);
-
- /* Guarantee ordering of memory (MCDI request) and PIO (MC doorbell) */
- EFSYS_DMA_SYNC_FOR_DEVICE(esmp, 0, offset + emrp->emr_in_length);
- EFSYS_PIO_WRITE_BARRIER();
-
- EFX_POPULATE_DWORD_1(dword,
- EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) >> 32);
- EFX_BAR_WRITED(enp, ER_DZ_MC_DB_LWRD_REG, &dword, B_FALSE);
-
- EFX_POPULATE_DWORD_1(dword,
- EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+ ef10_mcdi_send_request(enp, &hdr[0], hdr_len,
+ emrp->emr_in_buf, emrp->emr_in_length);
}
void
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
index cb62f6d..5c1aec7 100644
--- a/sys/dev/sfxge/common/siena_mcdi.c
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -53,6 +53,43 @@ __FBSDID("$FreeBSD$");
: MC_SMEM_P1_STATUS_OFST >> 2)
+static void
+siena_mcdi_send_request(
+ __in efx_nic_t *enp,
+ __in void *hdrp,
+ __in size_t hdr_len,
+ __in void *sdup,
+ __in size_t sdu_len)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t dword;
+ unsigned int pdur;
+ unsigned int dbr;
+ unsigned int pos;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ pdur = SIENA_MCDI_PDU(emip);
+ dbr = SIENA_MCDI_DOORBELL(emip);
+
+ /* Write the header */
+ EFSYS_ASSERT3U(hdr_len, ==, sizeof (efx_dword_t));
+ dword = *(efx_dword_t *)hdrp;
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
+
+ /* Write the payload */
+ for (pos = 0; pos < sdu_len; pos += sizeof (efx_dword_t)) {
+ dword = *(efx_dword_t *)((uint8_t *)sdup + pos);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (pos >> 2), &dword, B_FALSE);
+ }
+
+ /* Ring the doorbell */
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+}
+
void
siena_mcdi_request_copyin(
__in efx_nic_t *enp,
@@ -64,26 +101,19 @@ siena_mcdi_request_copyin(
#if EFSYS_OPT_MCDI_LOGGING
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
#endif
- efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
efx_dword_t hdr;
- efx_dword_t dword;
+ size_t hdr_len;
unsigned int xflags;
- unsigned int pdur;
- unsigned int dbr;
- unsigned int pos;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
_NOTE(ARGUNUSED(new_epoch))
- EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
- pdur = SIENA_MCDI_PDU(emip);
- dbr = SIENA_MCDI_DOORBELL(emip);
-
xflags = 0;
if (ev_cpl)
xflags |= MCDI_HEADER_XFLAGS_EVREQ;
- /* Construct the header in shared memory */
+ /* Construct the header */
+ hdr_len = sizeof (hdr);
EFX_POPULATE_DWORD_6(hdr,
MCDI_HEADER_CODE, emrp->emr_cmd,
MCDI_HEADER_RESYNC, 1,
@@ -91,7 +121,6 @@ siena_mcdi_request_copyin(
MCDI_HEADER_SEQ, seq,
MCDI_HEADER_RESPONSE, 0,
MCDI_HEADER_XFLAGS, xflags);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_TRUE);
#if EFSYS_OPT_MCDI_LOGGING
if (emtp->emt_logger != NULL) {
@@ -101,17 +130,8 @@ siena_mcdi_request_copyin(
}
#endif /* EFSYS_OPT_MCDI_LOGGING */
- /* Construct the payload */
- for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
- memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
- MIN(sizeof (dword), emrp->emr_in_length - pos));
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (pos >> 2), &dword, B_FALSE);
- }
-
- /* Ring the doorbell */
- EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+ siena_mcdi_send_request(enp, &hdr, hdr_len,
+ emrp->emr_in_buf, emrp->emr_in_length);
}
void
OpenPOWER on IntegriCloud