From fdfece024e209f312b2037f6e9faa02e63fb7e63 Mon Sep 17 00:00:00 2001 From: arybchik Date: Wed, 13 Jan 2016 06:42:51 +0000 Subject: [PATCH] sfxge: simplify MCDI request start Submitted by: Andy Moreton Reviewed by: gnn Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D4894 --- sys/dev/sfxge/common/hunt_mcdi.c | 84 ++++++++++++++++++------------- sys/dev/sfxge/common/siena_mcdi.c | 64 +++++++++++++++-------- 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 d23259e7006..f9c73b416dd 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 cb62f6dee3a..5c1aec7baac 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 -- 2.45.2