net/sfc/base: enable chained multicast on all EF10 cards
[dpdk.git] / drivers / net / sfc / base / ef10_nic.c
index 39ca53f..1d7e6d8 100644 (file)
@@ -10,7 +10,7 @@
 #include "mcdi_mon.h"
 #endif
 
-#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
+#if EFX_OPTS_EF10()
 
 #include "ef10_tlv_layout.h"
 
@@ -24,9 +24,7 @@ efx_mcdi_get_port_assignment(
                MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
        req.emr_in_buf = payload;
@@ -70,9 +68,7 @@ efx_mcdi_get_port_modes(
                MC_CMD_GET_PORT_MODES_OUT_LEN);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        req.emr_cmd = MC_CMD_GET_PORT_MODES;
        req.emr_in_buf = payload;
@@ -308,9 +304,7 @@ efx_mcdi_get_mac_address_pf(
                MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
        req.emr_in_buf = payload;
@@ -366,9 +360,7 @@ efx_mcdi_get_mac_address_vf(
                MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
        req.emr_in_buf = payload;
@@ -430,9 +422,7 @@ efx_mcdi_get_clock(
                MC_CMD_GET_CLOCK_OUT_LEN);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        req.emr_cmd = MC_CMD_GET_CLOCK;
        req.emr_in_buf = payload;
@@ -892,9 +882,7 @@ ef10_nic_pio_alloc(
        uint32_t buf, blk;
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
        EFSYS_ASSERT(bufnump);
        EFSYS_ASSERT(handlep);
        EFSYS_ASSERT(blknump);
@@ -1205,6 +1193,16 @@ ef10_get_datapath_caps(
        else
                encp->enc_no_cont_ev_mode_supported = B_FALSE;
 
+       /*
+        * Check if buffer size may and must be specified on INIT_RXQ.
+        * It may be always specified to efx_rx_qcreate(), but will be
+        * just kept libefx internal if MCDI does not support it.
+        */
+       if (CAP_FLAGS2(req, INIT_RXQ_WITH_BUFFER_SIZE))
+               encp->enc_init_rxq_with_buffer_size = B_TRUE;
+       else
+               encp->enc_init_rxq_with_buffer_size = B_FALSE;
+
        /*
         * Check if firmware-verified NVRAM updates must be used.
         *
@@ -1754,6 +1752,56 @@ fail1:
        return (rc);
 }
 
+static __checkReturn   efx_rc_t
+ef10_set_workaround_bug26807(
+       __in            efx_nic_t *enp)
+{
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       uint32_t flags;
+       efx_rc_t rc;
+
+       /*
+        * If the bug26807 workaround is enabled, then firmware has enabled
+        * support for chained multicast filters. Firmware will reset (FLR)
+        * functions which have filters in the hardware filter table when the
+        * workaround is enabled/disabled.
+        *
+        * We must recheck if the workaround is enabled after inserting the
+        * first hardware filter, in case it has been changed since this check.
+        */
+       rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
+           B_TRUE, &flags);
+       if (rc == 0) {
+               encp->enc_bug26807_workaround = B_TRUE;
+               if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
+                       /*
+                        * Other functions had installed filters before the
+                        * workaround was enabled, and they have been reset
+                        * by firmware.
+                        */
+                       EFSYS_PROBE(bug26807_workaround_flr_done);
+                       /* FIXME: bump MC warm boot count ? */
+               }
+       } else if (rc == EACCES) {
+               /*
+                * Unprivileged functions cannot enable the workaround in older
+                * firmware.
+                */
+               encp->enc_bug26807_workaround = B_FALSE;
+       } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+               encp->enc_bug26807_workaround = B_FALSE;
+       } else {
+               goto fail1;
+       }
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
 static __checkReturn   efx_rc_t
 ef10_nic_board_cfg(
        __in            efx_nic_t *enp)
@@ -1912,13 +1960,18 @@ ef10_nic_board_cfg(
                goto fail10;
        encp->enc_privilege_mask = mask;
 
+       if ((rc = ef10_set_workaround_bug26807(enp)) != 0)
+               goto fail11;
+
        /* Get remaining controller-specific board config */
        if ((rc = enop->eno_board_cfg(enp)) != 0)
                if (rc != EACCES)
-                       goto fail11;
+                       goto fail12;
 
        return (0);
 
+fail12:
+       EFSYS_PROBE(fail12);
 fail11:
        EFSYS_PROBE(fail11);
 fail10:
@@ -1953,9 +2006,7 @@ ef10_nic_probe(
        efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
        efx_rc_t rc;
 
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        /* Read and clear any assertion state */
        if ((rc = efx_mcdi_read_assertion(enp)) != 0)
@@ -2167,9 +2218,7 @@ ef10_nic_init(
        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_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        /* Enable reporting of some events (e.g. link change) */
        if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
@@ -2330,9 +2379,7 @@ ef10_nic_get_vi_pool(
        __in            efx_nic_t *enp,
        __out           uint32_t *vi_countp)
 {
-       EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
-           enp->en_family == EFX_FAMILY_MEDFORD ||
-           enp->en_family == EFX_FAMILY_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        /*
         * Report VIs that the client driver can use.
@@ -2352,9 +2399,7 @@ 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_MEDFORD2);
+       EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
 
        /*
         * TODO: Specify host memory mapping alignment and granularity
@@ -2561,4 +2606,4 @@ fail1:
 
 #endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */
 
-#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
+#endif /* EFX_OPTS_EF10() */