net/sfc/base: support choosing firmware variant
[dpdk.git] / drivers / net / sfc / base / efx_impl.h
index 8bd667c..b1d4f57 100644 (file)
@@ -1,31 +1,7 @@
-/*
- * Copyright (c) 2007-2016 Solarflare Communications Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
  *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of the FreeBSD Project.
+ * Copyright (c) 2007-2018 Solarflare Communications Inc.
+ * All rights reserved.
  */
 
 #ifndef        _SYS_EFX_IMPL_H
 #include "medford_impl.h"
 #endif /* EFSYS_OPT_MEDFORD */
 
-#if (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#if EFSYS_OPT_MEDFORD2
+#include "medford2_impl.h"
+#endif /* EFSYS_OPT_MEDFORD2 */
+
+#if (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2)
 #include "ef10_impl.h"
-#endif /* (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD) */
+#endif /* (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2) */
 
 #ifdef __cplusplus
 extern "C" {
@@ -74,6 +54,7 @@ extern "C" {
 #define        EFX_MOD_MON             0x00000400
 #define        EFX_MOD_FILTER          0x00001000
 #define        EFX_MOD_LIC             0x00002000
+#define        EFX_MOD_TUNNEL          0x00004000
 
 #define        EFX_RESET_PHY           0x00000001
 #define        EFX_RESET_RXQ_ERR       0x00000002
@@ -84,6 +65,7 @@ typedef enum efx_mac_type_e {
        EFX_MAC_SIENA,
        EFX_MAC_HUNTINGTON,
        EFX_MAC_MEDFORD,
+       EFX_MAC_MEDFORD2,
        EFX_MAC_NTYPES
 } efx_mac_type_t;
 
@@ -135,10 +117,12 @@ typedef struct efx_tx_ops_s {
                                                uint32_t, uint8_t,
                                                efx_desc_t *);
        void            (*etxo_qdesc_tso2_create)(efx_txq_t *, uint16_t,
-                                               uint32_t, uint16_t,
+                                               uint16_t, uint32_t, uint16_t,
                                                efx_desc_t *, int);
        void            (*etxo_qdesc_vlantci_create)(efx_txq_t *, uint16_t,
                                                efx_desc_t *);
+       void            (*etxo_qdesc_checksum_create)(efx_txq_t *, uint16_t,
+                                               efx_desc_t *);
 #if EFSYS_OPT_QSTATS
        void            (*etxo_qstats_update)(efx_txq_t *,
                                              efsys_stat_t *);
@@ -181,7 +165,7 @@ typedef struct efx_rx_ops_s {
        efx_rc_t        (*erxo_qflush)(efx_rxq_t *);
        void            (*erxo_qenable)(efx_rxq_t *);
        efx_rc_t        (*erxo_qcreate)(efx_nic_t *enp, unsigned int,
-                                       unsigned int, efx_rxq_type_t,
+                                       unsigned int, efx_rxq_type_t, uint32_t,
                                        efsys_mem_t *, size_t, uint32_t,
                                        unsigned int,
                                        efx_evq_t *, efx_rxq_t *);
@@ -262,6 +246,12 @@ efx_filter_reconfigure(
 
 #endif /* EFSYS_OPT_FILTER */
 
+#if EFSYS_OPT_TUNNEL
+typedef struct efx_tunnel_ops_s {
+       boolean_t       (*eto_udp_encap_supported)(efx_nic_t *);
+       efx_rc_t        (*eto_reconfigure)(efx_nic_t *);
+} efx_tunnel_ops_t;
+#endif /* EFSYS_OPT_TUNNEL */
 
 typedef struct efx_port_s {
        efx_mac_type_t          ep_mac_type;
@@ -415,9 +405,9 @@ typedef struct efx_filter_s {
 #if EFSYS_OPT_SIENA
        siena_filter_t          *ef_siena_filter;
 #endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
        ef10_filter_table_t     *ef_ef10_filter_table;
-#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
 } efx_filter_t;
 
 #if EFSYS_OPT_SIENA
@@ -433,6 +423,22 @@ siena_filter_tbl_clear(
 
 #if EFSYS_OPT_MCDI
 
+#define        EFX_TUNNEL_MAXNENTRIES  (16)
+
+#if EFSYS_OPT_TUNNEL
+
+typedef struct efx_tunnel_udp_entry_s {
+       uint16_t                        etue_port; /* host/cpu-endian */
+       uint16_t                        etue_protocol;
+} efx_tunnel_udp_entry_t;
+
+typedef struct efx_tunnel_cfg_s {
+       efx_tunnel_udp_entry_t  etc_udp_entries[EFX_TUNNEL_MAXNENTRIES];
+       unsigned int            etc_udp_entries_num;
+} efx_tunnel_cfg_t;
+
+#endif /* EFSYS_OPT_TUNNEL */
+
 typedef struct efx_mcdi_ops_s {
        efx_rc_t        (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
        void            (*emco_send_request)(efx_nic_t *, void *, size_t,
@@ -641,10 +647,15 @@ struct efx_nic_s {
        const efx_ev_ops_t      *en_eevop;
        const efx_tx_ops_t      *en_etxop;
        const efx_rx_ops_t      *en_erxop;
+       efx_fw_variant_t        efv;
 #if EFSYS_OPT_FILTER
        efx_filter_t            en_filter;
        const efx_filter_ops_t  *en_efop;
 #endif /* EFSYS_OPT_FILTER */
+#if EFSYS_OPT_TUNNEL
+       efx_tunnel_cfg_t        en_tunnel_cfg;
+       const efx_tunnel_ops_t  *en_etop;
+#endif /* EFSYS_OPT_TUNNEL */
 #if EFSYS_OPT_MCDI
        efx_mcdi_t              en_mcdi;
 #endif /* EFSYS_OPT_MCDI */
@@ -680,7 +691,7 @@ struct efx_nic_s {
 #endif /* EFSYS_OPT_SIENA */
                int     enu_unused;
        } en_u;
-#if (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#if (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2)
        union en_arch {
                struct {
                        int                     ena_vi_base;
@@ -701,7 +712,7 @@ struct efx_nic_s {
                        size_t                  ena_wc_mem_map_size;
                } ef10;
        } en_arch;
-#endif /* (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD) */
+#endif /* (EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2) */
 };
 
 
@@ -822,6 +833,10 @@ struct efx_txq_s {
                        rev = 'E';                                      \
                        break;                                          \
                                                                        \
+               case EFX_FAMILY_MEDFORD2:                               \
+                       rev = 'F';                                      \
+                       break;                                          \
+                                                                       \
                default:                                                \
                        rev = '?';                                      \
                        break;                                          \
@@ -912,6 +927,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));                          \
@@ -938,21 +962,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));                          \
@@ -1029,16 +1038,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,                            \
@@ -1047,7 +1106,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)