net/sfc/base: support runtime VI window size
[dpdk.git] / drivers / net / sfc / base / ef10_nic.c
index aac2679..a48f2ac 100644 (file)
@@ -1,31 +1,7 @@
-/*
- * Copyright (c) 2012-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:
+/* SPDX-License-Identifier: BSD-3-Clause
  *
- * 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.
- *
- * 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) 2012-2018 Solarflare Communications Inc.
+ * All rights reserved.
  */
 
 #include "efx.h"
@@ -34,7 +10,7 @@
 #include "mcdi_mon.h"
 #endif
 
-#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
 
 #include "ef10_tlv_layout.h"
 
@@ -49,7 +25,8 @@ efx_mcdi_get_port_assignment(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
@@ -94,7 +71,8 @@ efx_mcdi_get_port_modes(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_PORT_MODES;
@@ -274,7 +252,8 @@ efx_mcdi_get_mac_address_pf(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
@@ -332,7 +311,8 @@ efx_mcdi_get_mac_address_vf(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
@@ -396,7 +376,8 @@ efx_mcdi_get_clock(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_CLOCK;
@@ -439,6 +420,64 @@ fail2:
 fail1:
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_mcdi_get_rxdp_config(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *end_paddingp)
+{
+       efx_mcdi_req_t req;
+       uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+                           MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+       uint32_t end_padding;
+       efx_rc_t rc;
+
+       memset(payload, 0, sizeof (payload));
+       req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN;
+
+       efx_mcdi_execute(enp, &req);
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               goto fail1;
+       }
+
+       if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+                                   GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) {
+               /* RX DMA end padding is disabled */
+               end_padding = 0;
+       } else {
+               switch (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+                                           GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) {
+               case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64:
+                       end_padding = 64;
+                       break;
+               case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128:
+                       end_padding = 128;
+                       break;
+               case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256:
+                       end_padding = 256;
+                       break;
+               default:
+                       rc = ENOTSUP;
+                       goto fail2;
+               }
+       }
+
+       *end_paddingp = end_padding;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
        return (rc);
 }
 
@@ -807,7 +846,8 @@ ef10_nic_pio_alloc(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
        EFSYS_ASSERT(bufnump);
        EFSYS_ASSERT(handlep);
        EFSYS_ASSERT(blknump);
@@ -1054,7 +1094,7 @@ ef10_get_datapath_caps(
         * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated
         * partition and report the result).
         */
-       encp->enc_fw_verified_nvram_update_required =
+       encp->enc_nvram_update_verify_result_supported =
            CAP_FLAG2(flags2, NVRAM_UPDATE_REPORT_VERIFY_RESULT) ?
            B_TRUE : B_FALSE;
 
@@ -1072,6 +1112,24 @@ ef10_get_datapath_caps(
        encp->enc_mac_stats_40g_tx_size_bins =
            CAP_FLAG2(flags2, MAC_STATS_40G_TX_SIZE_BINS) ? B_TRUE : B_FALSE;
 
+       /*
+        * Check if firmware supports VXLAN and NVGRE tunnels.
+        * The capability indicates Geneve protocol support as well.
+        */
+       if (CAP_FLAG(flags, VXLAN_NVGRE)) {
+               encp->enc_tunnel_encapsulations_supported =
+                   (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
+                   (1u << EFX_TUNNEL_PROTOCOL_GENEVE) |
+                   (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
+
+               EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES ==
+                   MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
+               encp->enc_tunnel_config_udp_entries_max =
+                   EFX_TUNNEL_MAXNENTRIES;
+       } else {
+               encp->enc_tunnel_config_udp_entries_max = 0;
+       }
+
 #undef CAP_FLAG
 #undef CAP_FLAG2
 
@@ -1085,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                     |       \
@@ -1149,7 +1272,7 @@ fail1:
  * For the Huntington family, the current port mode cannot be discovered,
  * so the mapping used is instead the last match in the table to the full
  * set of port modes to which the NIC can be configured. Therefore the
- * ordering of entries in the the mapping table is significant.
+ * ordering of entries in the mapping table is significant.
  */
 static struct {
        efx_family_t    family;
@@ -1289,7 +1412,8 @@ ef10_nic_probe(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        /* Read and clear any assertion state */
        if ((rc = efx_mcdi_read_assertion(enp)) != 0)
@@ -1500,10 +1624,12 @@ 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 ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        /* Enable reporting of some events (e.g. link change) */
        if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
@@ -1561,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);
        }
 
@@ -1579,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 */
@@ -1659,7 +1791,8 @@ ef10_nic_get_vi_pool(
        __out           uint32_t *vi_countp)
 {
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        /*
         * Report VIs that the client driver can use.
@@ -1680,7 +1813,8 @@ ef10_nic_get_bar_region(
        efx_rc_t rc;
 
        EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-                   enp->en_family == EFX_FAMILY_MEDFORD);
+           enp->en_family == EFX_FAMILY_MEDFORD ||
+           enp->en_family == EFX_FAMILY_MEDFORD2);
 
        /*
         * TODO: Specify host memory mapping alignment and granularity
@@ -1777,4 +1911,4 @@ fail1:
 #endif /* EFSYS_OPT_DIAG */
 
 
-#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */