From: Andy Moreton Date: Tue, 20 Feb 2018 07:33:41 +0000 (+0000) Subject: net/sfc/base: support runtime VI window size X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=b9673329e1df716edb019eca0f05b45d6663ef38;p=dpdk.git net/sfc/base: support runtime VI window size Medford2 uses a configurable VI window size, and requires updates to register accesses to use a runtime VI window size rather than the *_STEP register constants used for earlier controllers. Update the common code to query the VI window size via MCDI, and add new EFX_BAR_VI_* accessor macros for per-VI registers. The existing EFX_BAR_TBL_* macros can be used for non-VI register tables (and for code that can never be called for a Medford2 controller e.g. Siena-only code). Signed-off-by: Andy Moreton Signed-off-by: Andrew Rybchenko --- diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c index a05a35aa68..36ff2cbc23 100644 --- a/drivers/net/sfc/base/ef10_ev.c +++ b/drivers/net/sfc/base/ef10_ev.c @@ -577,7 +577,7 @@ ef10_ev_qprime( EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH, ERF_DD_EVQ_IND_RPTR, (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH)); - EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index, + EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index, &dword, B_FALSE); EFX_POPULATE_DWORD_2(dword, @@ -585,11 +585,11 @@ ef10_ev_qprime( EFE_DD_EVQ_IND_RPTR_FLAGS_LOW, ERF_DD_EVQ_IND_RPTR, rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1)); - EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index, + EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index, &dword, B_FALSE); } else { EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr); - EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index, + EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index, &dword, B_FALSE); } @@ -702,13 +702,13 @@ ef10_ev_qmoderate( EFE_DD_EVQ_IND_TIMER_FLAGS, ERF_DD_EVQ_IND_TIMER_MODE, mode, ERF_DD_EVQ_IND_TIMER_VAL, ticks); - EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, + EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index, &dword, 0); } else { EFX_POPULATE_DWORD_2(dword, ERF_DZ_TC_TIMER_MODE, mode, ERF_DZ_TC_TIMER_VAL, ticks); - EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_TMR_REG, + EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_TMR_REG, eep->ee_index, &dword, 0); } } diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h index e004d15775..08e2f9f966 100644 --- a/drivers/net/sfc/base/ef10_impl.h +++ b/drivers/net/sfc/base/ef10_impl.h @@ -1160,6 +1160,11 @@ extern __checkReturn efx_rc_t ef10_get_datapath_caps( __in efx_nic_t *enp); +extern __checkReturn efx_rc_t +ef10_get_vi_window_shift( + __in efx_nic_t *enp, + __out uint32_t *vi_window_shiftp); + extern __checkReturn efx_rc_t ef10_get_privilege_mask( __in efx_nic_t *enp, diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index 8b9ef15c98..a48f2ac2b5 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1143,6 +1143,71 @@ fail1: return (rc); } + __checkReturn efx_rc_t +ef10_get_vi_window_shift( + __in efx_nic_t *enp, + __out uint32_t *vi_window_shiftp) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN, + MC_CMD_GET_CAPABILITIES_V3_OUT_LEN)]; + uint32_t mode; + efx_rc_t rc; + + (void) memset(payload, 0, sizeof (payload)); + req.emr_cmd = MC_CMD_GET_CAPABILITIES; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_GET_CAPABILITIES_V3_OUT_LEN; + + efx_mcdi_execute_quiet(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + mode = MCDI_OUT_BYTE(req, GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); + + switch (mode) { + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8 * 1024); + *vi_window_shiftp = EFX_VI_WINDOW_SHIFT_8K; + break; + + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_16K == 16 * 1024); + *vi_window_shiftp = EFX_VI_WINDOW_SHIFT_16K; + break; + + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_64K == 64 * 1024); + *vi_window_shiftp = EFX_VI_WINDOW_SHIFT_64K; + break; + + default: + *vi_window_shiftp = EFX_VI_WINDOW_SHIFT_INVALID; + rc = EINVAL; + goto fail3; + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #define EF10_LEGACY_PF_PRIVILEGE_MASK \ (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ @@ -1559,6 +1624,7 @@ ef10_nic_init( uint32_t i; uint32_t retry; uint32_t delay_us; + uint32_t vi_window_size; efx_rc_t rc; EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || @@ -1621,15 +1687,21 @@ ef10_nic_init( enp->en_arch.ef10.ena_pio_write_vi_base = vi_count - enp->en_arch.ef10.ena_piobuf_count; + EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=, + EFX_VI_WINDOW_SHIFT_INVALID); + EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=, + EFX_VI_WINDOW_SHIFT_64K); + vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift; + /* Save UC memory mapping details */ enp->en_arch.ef10.ena_uc_mem_map_offset = 0; if (enp->en_arch.ef10.ena_piobuf_count > 0) { enp->en_arch.ef10.ena_uc_mem_map_size = - (ER_DZ_TX_PIOBUF_STEP * + (vi_window_size * enp->en_arch.ef10.ena_pio_write_vi_base); } else { enp->en_arch.ef10.ena_uc_mem_map_size = - (ER_DZ_TX_PIOBUF_STEP * + (vi_window_size * enp->en_arch.ef10.ena_vi_count); } @@ -1639,7 +1711,7 @@ ef10_nic_init( enp->en_arch.ef10.ena_uc_mem_map_size; enp->en_arch.ef10.ena_wc_mem_map_size = - (ER_DZ_TX_PIOBUF_STEP * + (vi_window_size * enp->en_arch.ef10.ena_piobuf_count); /* Link piobufs to extra VIs in WC mapping */ diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index ea3df21663..79f2587864 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -795,8 +795,8 @@ ef10_rx_qpush( EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1, wptr, pushed & erp->er_mask); EFSYS_PIO_WRITE_BARRIER(); - EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, - erp->er_index, &dword, B_FALSE); + EFX_BAR_VI_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, + erp->er_index, &dword, B_FALSE); } #if EFSYS_OPT_RX_PACKED_STREAM @@ -827,7 +827,7 @@ ef10_rx_qpush_ps_credits( ERF_DZ_RX_DESC_MAGIC_CMD, ERE_DZ_RX_DESC_MAGIC_CMD_PS_CREDITS, ERF_DZ_RX_DESC_MAGIC_DATA, credits); - EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, + EFX_BAR_VI_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, erp->er_index, &dword, B_FALSE); rxq_state->eers_rx_packed_stream_credits = 0; diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c index ab11749c48..18877d4595 100644 --- a/drivers/net/sfc/base/ef10_tx.c +++ b/drivers/net/sfc/base/ef10_tx.c @@ -511,8 +511,8 @@ ef10_tx_qpush( EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1, wptr, id); EFSYS_PIO_WRITE_BARRIER(); - EFX_BAR_TBL_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG, - etp->et_index, &oword); + EFX_BAR_VI_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG, + etp->et_index, &oword); } else { efx_dword_t dword; @@ -527,8 +527,8 @@ ef10_tx_qpush( EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1, wptr, id); EFSYS_PIO_WRITE_BARRIER(); - EFX_BAR_TBL_WRITED2(enp, ER_DZ_TX_DESC_UPD_REG, - etp->et_index, &dword, B_FALSE); + EFX_BAR_VI_WRITED2(enp, ER_DZ_TX_DESC_UPD_REG, + etp->et_index, &dword, B_FALSE); } } diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 51356735ee..c0ba5e99f1 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1087,6 +1087,13 @@ typedef enum efx_tunnel_protocol_e { EFX_TUNNEL_NPROTOS } efx_tunnel_protocol_t; +typedef enum efx_vi_window_shift_e { + EFX_VI_WINDOW_SHIFT_INVALID = 0, + EFX_VI_WINDOW_SHIFT_8K = 13, + EFX_VI_WINDOW_SHIFT_16K = 14, + EFX_VI_WINDOW_SHIFT_64K = 16, +} efx_vi_window_shift_t; + typedef struct efx_nic_cfg_s { uint32_t enc_board_type; uint32_t enc_phy_type; @@ -1100,6 +1107,7 @@ typedef struct efx_nic_cfg_s { uint32_t enc_mon_stat_mask[(EFX_MON_NSTATS + 31) / 32]; #endif unsigned int enc_features; + efx_vi_window_shift_t enc_vi_window_shift; uint8_t enc_mac_addr[6]; uint8_t enc_port; /* PHY port number */ uint32_t enc_intr_vec_base; diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h index 76214fb3ff..e202b106f1 100644 --- a/drivers/net/sfc/base/efx_impl.h +++ b/drivers/net/sfc/base/efx_impl.h @@ -924,6 +924,15 @@ struct efx_txq_s { _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) +/* + * Accessors for memory BAR non-VI tables. + * + * Code used on EF10 *must* use EFX_BAR_VI_*() macros for per-VI registers, + * to ensure the correct runtime VI window size is used on Medford2. + * + * Siena-only code may continue using EFX_BAR_TBL_*() macros for VI registers. + */ + #define EFX_BAR_TBL_READD(_enp, _reg, _index, _edp, _lock) \ do { \ EFX_CHECK_REG((_enp), (_reg)); \ @@ -950,21 +959,6 @@ struct efx_txq_s { _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) -#define EFX_BAR_TBL_WRITED2(_enp, _reg, _index, _edp, _lock) \ - do { \ - EFX_CHECK_REG((_enp), (_reg)); \ - EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg, \ - uint32_t, (_index), \ - uint32_t, _reg ## _OFST, \ - uint32_t, (_edp)->ed_u32[0]); \ - EFSYS_BAR_WRITED((_enp)->en_esbp, \ - (_reg ## _OFST + \ - (2 * sizeof (efx_dword_t)) + \ - ((_index) * _reg ## _STEP)), \ - (_edp), (_lock)); \ - _NOTE(CONSTANTCONDITION) \ - } while (B_FALSE) - #define EFX_BAR_TBL_WRITED3(_enp, _reg, _index, _edp, _lock) \ do { \ EFX_CHECK_REG((_enp), (_reg)); \ @@ -1041,16 +1035,66 @@ struct efx_txq_s { } while (B_FALSE) /* - * Allow drivers to perform optimised 128-bit doorbell writes. + * Accessors for memory BAR per-VI registers. + * + * The VI window size is 8KB for Medford and all earlier controllers. + * For Medford2, the VI window size can be 8KB, 16KB or 64KB. + */ + +#define EFX_BAR_VI_READD(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READD((_enp)->en_esbp, \ + ((_reg ## _OFST) + \ + ((_index) << (_enp)->en_nic_cfg.enc_vi_window_shift)), \ + (_edp), (_lock)); \ + EFSYS_PROBE4(efx_bar_vi_readd, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_VI_WRITED(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE4(efx_bar_vi_writed, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, \ + ((_reg ## _OFST) + \ + ((_index) << (_enp)->en_nic_cfg.enc_vi_window_shift)), \ + (_edp), (_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_VI_WRITED2(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE4(efx_bar_vi_writed, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, \ + ((_reg ## _OFST) + \ + (2 * sizeof (efx_dword_t)) + \ + ((_index) << (_enp)->en_nic_cfg.enc_vi_window_shift)), \ + (_edp), (_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* + * Allow drivers to perform optimised 128-bit VI doorbell writes. * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are * special-cased in the BIU on the Falcon/Siena and EF10 architectures to avoid * the need for locking in the host, and are the only ones known to be safe to * use 128-bites write with. */ -#define EFX_BAR_TBL_DOORBELL_WRITEO(_enp, _reg, _index, _eop) \ +#define EFX_BAR_VI_DOORBELL_WRITEO(_enp, _reg, _index, _eop) \ do { \ EFX_CHECK_REG((_enp), (_reg)); \ - EFSYS_PROBE7(efx_bar_tbl_doorbell_writeo, \ + EFSYS_PROBE7(efx_bar_vi_doorbell_writeo, \ const char *, #_reg, \ uint32_t, (_index), \ uint32_t, _reg ## _OFST, \ @@ -1059,7 +1103,8 @@ struct efx_txq_s { uint32_t, (_eop)->eo_u32[1], \ uint32_t, (_eop)->eo_u32[0]); \ EFSYS_BAR_DOORBELL_WRITEO((_enp)->en_esbp, \ - (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_reg ## _OFST + \ + ((_index) << (_enp)->en_nic_cfg.enc_vi_window_shift)), \ (_eop)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) diff --git a/drivers/net/sfc/base/hunt_nic.c b/drivers/net/sfc/base/hunt_nic.c index fb39850d3f..903c669d62 100644 --- a/drivers/net/sfc/base/hunt_nic.c +++ b/drivers/net/sfc/base/hunt_nic.c @@ -92,6 +92,17 @@ hunt_board_cfg( uint32_t bandwidth; efx_rc_t rc; + /* Huntington has a fixed 8Kbyte VI window size */ + EFX_STATIC_ASSERT(ER_DZ_EVQ_RPTR_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_EVQ_TMR_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_RX_DESC_UPD_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_TX_DESC_UPD_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_TX_PIOBUF_STEP == 8192); + + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192); + encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; + + if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) goto fail1; diff --git a/drivers/net/sfc/base/medford2_nic.c b/drivers/net/sfc/base/medford2_nic.c index 4faf786783..327fcaa872 100644 --- a/drivers/net/sfc/base/medford2_nic.c +++ b/drivers/net/sfc/base/medford2_nic.c @@ -62,6 +62,7 @@ medford2_board_cfg( uint32_t base, nvec; uint32_t end_padding; uint32_t bandwidth; + uint32_t vi_window_shift; efx_rc_t rc; /* @@ -69,6 +70,14 @@ medford2_board_cfg( * Parts of this should be shared with Huntington. */ + /* Medford2 has a variable VI window size (8K, 16K or 64K) */ + if ((rc = ef10_get_vi_window_shift(enp, &vi_window_shift)) != 0) + goto fail1; + + EFSYS_ASSERT3U(vi_window_shift, <=, EFX_VI_WINDOW_SHIFT_64K); + encp->enc_vi_window_shift = vi_window_shift; + + if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) goto fail1; diff --git a/drivers/net/sfc/base/medford_nic.c b/drivers/net/sfc/base/medford_nic.c index 9a92153686..9b8da9940a 100644 --- a/drivers/net/sfc/base/medford_nic.c +++ b/drivers/net/sfc/base/medford_nic.c @@ -67,6 +67,17 @@ medford_board_cfg( * Parts of this should be shared with Huntington. */ + /* Medford has a fixed 8Kbyte VI window size */ + EFX_STATIC_ASSERT(ER_DZ_EVQ_RPTR_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_EVQ_TMR_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_RX_DESC_UPD_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_TX_DESC_UPD_REG_STEP == 8192); + EFX_STATIC_ASSERT(ER_DZ_TX_PIOBUF_STEP == 8192); + + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192); + encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; + + if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) goto fail1; diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index f223c9be34..c051c59bf3 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -66,6 +66,10 @@ siena_board_cfg( uint32_t nevq, nrxq, ntxq; efx_rc_t rc; + /* Siena has a fixed 8Kbyte VI window size */ + EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192); + encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; + /* External port identifier using one-based port numbering */ encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;