sfxge(4): 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).

Submitted by:   Andy Moreton <amoreton at solarflare.com>
Sponsored by:   Solarflare Communications, Inc.
Differential Revision:  https://reviews.freebsd.org/D18158
This commit is contained in:
Andrew Rybchenko 2018-11-27 12:22:37 +00:00
parent bbefcb4c11
commit c63c836960
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=341036
11 changed files with 199 additions and 34 deletions

View File

@ -604,7 +604,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,
@ -612,11 +612,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);
}
@ -729,13 +729,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);
}
}

View File

@ -1186,6 +1186,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,

View File

@ -1170,6 +1170,71 @@ ef10_get_datapath_caps(
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 | \
@ -1586,6 +1651,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 ||
@ -1648,15 +1714,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);
}
@ -1666,7 +1738,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 */

View File

@ -822,8 +822,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
@ -854,7 +854,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;

View File

@ -538,8 +538,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;
@ -554,8 +554,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);
}
}

View File

@ -1115,6 +1115,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;
@ -1128,6 +1135,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;

View File

@ -952,6 +952,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)); \
@ -978,21 +987,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)); \
@ -1069,16 +1063,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, \
@ -1087,7 +1131,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)

View File

@ -119,6 +119,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;

View File

@ -91,6 +91,7 @@ medford2_board_cfg(
uint32_t base, nvec;
uint32_t end_padding;
uint32_t bandwidth;
uint32_t vi_window_shift;
efx_rc_t rc;
/*
@ -98,6 +99,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;

View File

@ -94,6 +94,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;

View File

@ -95,6 +95,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;