net/sfc/base: support runtime VI window size
authorAndy Moreton <amoreton@solarflare.com>
Tue, 20 Feb 2018 07:33:41 +0000 (07:33 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 30 Mar 2018 12:08:42 +0000 (14:08 +0200)
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 <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
drivers/net/sfc/base/ef10_ev.c
drivers/net/sfc/base/ef10_impl.h
drivers/net/sfc/base/ef10_nic.c
drivers/net/sfc/base/ef10_rx.c
drivers/net/sfc/base/ef10_tx.c
drivers/net/sfc/base/efx.h
drivers/net/sfc/base/efx_impl.h
drivers/net/sfc/base/hunt_nic.c
drivers/net/sfc/base/medford2_nic.c
drivers/net/sfc/base/medford_nic.c
drivers/net/sfc/base/siena_nic.c

index a05a35a..36ff2cb 100644 (file)
@@ -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);
                }
        }
index e004d15..08e2f9f 100644 (file)
@@ -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,
index 8b9ef15..a48f2ac 100644 (file)
@@ -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 */
index ea3df21..79f2587 100644 (file)
@@ -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;
index ab11749..18877d4 100644 (file)
@@ -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);
        }
 }
 
index 5135673..c0ba5e9 100644 (file)
@@ -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;
index 76214fb..e202b10 100644 (file)
@@ -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)
index fb39850..903c669 100644 (file)
@@ -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;
 
index 4faf786..327fcaa 100644 (file)
@@ -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;
 
index 9a92153..9b8da99 100644 (file)
@@ -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;
 
index f223c9b..c051c59 100644 (file)
@@ -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;