common/sfc_efx/base: implement Tx control path for Riverhead
authorAndrew Rybchenko <arybchenko@solarflare.com>
Thu, 24 Sep 2020 12:12:08 +0000 (13:12 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 30 Sep 2020 17:19:12 +0000 (19:19 +0200)
Tx control path on Riverhead is very similar to EF10, but datapath
differs a lot since Tx descriptor size is 16 bytes (vs 8 bytes on EF10).

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/common/sfc_efx/base/efx_impl.h
drivers/common/sfc_efx/base/efx_mcdi.c
drivers/common/sfc_efx/base/efx_tx.c
drivers/common/sfc_efx/base/meson.build
drivers/common/sfc_efx/base/rhead_impl.h
drivers/common/sfc_efx/base/rhead_tx.c [new file with mode: 0644]

index fac2815..d7e11c6 100644 (file)
@@ -1452,10 +1452,6 @@ efx_mcdi_fini_rxq(
        __in            efx_nic_t *enp,
        __in            uint32_t instance);
 
-#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
-
-#if EFX_OPTS_EF10()
-
 LIBEFX_INTERNAL
 extern __checkReturn   efx_rc_t
 efx_mcdi_init_txq(
@@ -1473,7 +1469,7 @@ efx_mcdi_fini_txq(
        __in            efx_nic_t *enp,
        __in            uint32_t instance);
 
-#endif /* EFX_OPTS_EF10() */
+#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
 
 #endif /* EFSYS_OPT_MCDI */
 
index 6a22785..278c5e2 100644 (file)
@@ -2863,10 +2863,6 @@ fail1:
        return (rc);
 }
 
-#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
-
-#if EFX_OPTS_EF10()
-
        __checkReturn   efx_rc_t
 efx_mcdi_init_txq(
        __in            efx_nic_t *enp,
@@ -2999,6 +2995,6 @@ fail1:
        return (rc);
 }
 
-#endif /* EFX_OPTS_EF10() */
+#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
 
 #endif /* EFSYS_OPT_MCDI */
index 38c64e0..d7f31fd 100644 (file)
@@ -205,6 +205,33 @@ static const efx_tx_ops_t  __efx_tx_medford2_ops = {
 };
 #endif /* EFSYS_OPT_MEDFORD2 */
 
+#if EFSYS_OPT_RIVERHEAD
+static const efx_tx_ops_t      __efx_tx_rhead_ops = {
+       rhead_tx_init,                          /* etxo_init */
+       rhead_tx_fini,                          /* etxo_fini */
+       rhead_tx_qcreate,                       /* etxo_qcreate */
+       rhead_tx_qdestroy,                      /* etxo_qdestroy */
+       rhead_tx_qpost,                         /* etxo_qpost */
+       rhead_tx_qpush,                         /* etxo_qpush */
+       rhead_tx_qpace,                         /* etxo_qpace */
+       rhead_tx_qflush,                        /* etxo_qflush */
+       rhead_tx_qenable,                       /* etxo_qenable */
+       NULL,                                   /* etxo_qpio_enable */
+       NULL,                                   /* etxo_qpio_disable */
+       NULL,                                   /* etxo_qpio_write */
+       NULL,                                   /* etxo_qpio_post */
+       rhead_tx_qdesc_post,                    /* etxo_qdesc_post */
+       NULL,                                   /* etxo_qdesc_dma_create */
+       NULL,                                   /* etxo_qdesc_tso_create */
+       NULL,                                   /* etxo_qdesc_tso2_create */
+       NULL,                                   /* etxo_qdesc_vlantci_create */
+       NULL,                                   /* etxo_qdesc_checksum_create */
+#if EFSYS_OPT_QSTATS
+       rhead_tx_qstats_update,                 /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_RIVERHEAD */
+
 
        __checkReturn   efx_rc_t
 efx_tx_init(
@@ -251,6 +278,12 @@ efx_tx_init(
                break;
 #endif /* EFSYS_OPT_MEDFORD2 */
 
+#if EFSYS_OPT_RIVERHEAD
+       case EFX_FAMILY_RIVERHEAD:
+               etxop = &__efx_tx_rhead_ops;
+               break;
+#endif /* EFSYS_OPT_RIVERHEAD */
+
        default:
                EFSYS_ASSERT(0);
                rc = ENOTSUP;
index aff5017..8f944bb 100644 (file)
@@ -56,6 +56,7 @@ sources = [
        'rhead_intr.c',
        'rhead_nic.c',
        'rhead_rx.c',
+       'rhead_tx.c',
 ]
 
 extra_flags = [
index 0ba6636..c3ffad7 100644 (file)
@@ -355,6 +355,89 @@ rhead_rx_qdestroy(
        __in            efx_rxq_t *erp);
 
 
+/* TX */
+
+LIBEFX_INTERNAL
+extern __checkReturn   efx_rc_t
+rhead_tx_init(
+       __in            efx_nic_t *enp);
+
+LIBEFX_INTERNAL
+extern                 void
+rhead_tx_fini(
+       __in            efx_nic_t *enp);
+
+LIBEFX_INTERNAL
+extern __checkReturn   efx_rc_t
+rhead_tx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efsys_mem_t *esmp,
+       __in            size_t ndescs,
+       __in            uint32_t id,
+       __in            uint16_t flags,
+       __in            efx_evq_t *eep,
+       __in            efx_txq_t *etp,
+       __out           unsigned int *addedp);
+
+LIBEFX_INTERNAL
+extern         void
+rhead_tx_qdestroy(
+       __in            efx_txq_t *etp);
+
+LIBEFX_INTERNAL
+extern __checkReturn           efx_rc_t
+rhead_tx_qpost(
+       __in                    efx_txq_t *etp,
+       __in_ecount(ndescs)     efx_buffer_t *ebp,
+       __in                    unsigned int ndescs,
+       __in                    unsigned int completed,
+       __inout                 unsigned int *addedp);
+
+LIBEFX_INTERNAL
+extern                 void
+rhead_tx_qpush(
+       __in            efx_txq_t *etp,
+       __in            unsigned int added,
+       __in            unsigned int pushed);
+
+LIBEFX_INTERNAL
+extern __checkReturn   efx_rc_t
+rhead_tx_qpace(
+       __in            efx_txq_t *etp,
+       __in            unsigned int ns);
+
+LIBEFX_INTERNAL
+extern __checkReturn   efx_rc_t
+rhead_tx_qflush(
+       __in            efx_txq_t *etp);
+
+LIBEFX_INTERNAL
+extern                 void
+rhead_tx_qenable(
+       __in            efx_txq_t *etp);
+
+LIBEFX_INTERNAL
+extern __checkReturn   efx_rc_t
+rhead_tx_qdesc_post(
+       __in            efx_txq_t *etp,
+       __in_ecount(n)  efx_desc_t *ed,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __inout         unsigned int *addedp);
+
+#if EFSYS_OPT_QSTATS
+
+LIBEFX_INTERNAL
+extern                 void
+rhead_tx_qstats_update(
+       __in                            efx_txq_t *etp,
+       __inout_ecount(TX_NQSTATS)      efsys_stat_t *stat);
+
+#endif /* EFSYS_OPT_QSTATS */
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/common/sfc_efx/base/rhead_tx.c b/drivers/common/sfc_efx/base/rhead_tx.c
new file mode 100644 (file)
index 0000000..4c60f32
--- /dev/null
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright(c) 2019-2020 Xilinx, Inc.
+ * Copyright(c) 2018-2019 Solarflare Communications Inc.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_RIVERHEAD
+
+       __checkReturn   efx_rc_t
+rhead_tx_init(
+       __in            efx_nic_t *enp)
+{
+       _NOTE(ARGUNUSED(enp))
+       /* Nothing to do here */
+       return (0);
+}
+
+                       void
+rhead_tx_fini(
+       __in            efx_nic_t *enp)
+{
+       _NOTE(ARGUNUSED(enp))
+       /* Nothing to do here */
+}
+
+       __checkReturn   efx_rc_t
+rhead_tx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efsys_mem_t *esmp,
+       __in            size_t ndescs,
+       __in            uint32_t id,
+       __in            uint16_t flags,
+       __in            efx_evq_t *eep,
+       __in            efx_txq_t *etp,
+       __out           unsigned int *addedp)
+{
+       efx_rc_t rc;
+
+       /*
+        * NMC manages the NMMU entries, and so buffer table IDs are
+        * ignored here
+        */
+       _NOTE(ARGUNUSED(id))
+
+       if ((rc = efx_mcdi_init_txq(enp, ndescs, eep->ee_index, label, index,
+           flags, esmp)) != 0)
+               goto fail1;
+
+       /*
+        * Return the initial queue index which is zero since no option
+        * descriptors are sent at start of day.
+        */
+       *addedp = 0;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+               void
+rhead_tx_qdestroy(
+       __in    efx_txq_t *etp)
+{
+       _NOTE(ARGUNUSED(etp))
+       /* Nothing to do here */
+}
+
+       __checkReturn           efx_rc_t
+rhead_tx_qpost(
+       __in                    efx_txq_t *etp,
+       __in_ecount(ndescs)     efx_buffer_t *eb,
+       __in                    unsigned int ndescs,
+       __in                    unsigned int completed,
+       __inout                 unsigned int *addedp)
+{
+       _NOTE(ARGUNUSED(etp))
+       _NOTE(ARGUNUSED(eb))
+       _NOTE(ARGUNUSED(ndescs))
+       _NOTE(ARGUNUSED(completed))
+       _NOTE(ARGUNUSED(addedp))
+
+       /* FIXME Implement the method for Riverhead */
+
+       return (ENOTSUP);
+}
+
+                       void
+rhead_tx_qpush(
+       __in            efx_txq_t *etp,
+       __in            unsigned int added,
+       __in            unsigned int pushed)
+{
+       _NOTE(ARGUNUSED(etp, added, pushed))
+
+       /* FIXME Implement the method for Riverhead */
+       EFSYS_ASSERT(B_FALSE);
+}
+
+       __checkReturn   efx_rc_t
+rhead_tx_qpace(
+       __in            efx_txq_t *etp,
+       __in            unsigned int ns)
+{
+       _NOTE(ARGUNUSED(etp))
+       _NOTE(ARGUNUSED(ns))
+
+       /* FIXME Implement the method for Riverhead */
+
+       return (ENOTSUP);
+}
+
+       __checkReturn   efx_rc_t
+rhead_tx_qflush(
+       __in            efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       efx_rc_t rc;
+
+       if ((rc = efx_mcdi_fini_txq(enp, etp->et_index)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       /*
+        * EALREADY is not an error, but indicates that the MC has rebooted and
+        * that the TXQ has already been destroyed. Callers need to know that
+        * the TXQ flush has completed to avoid waiting until timeout for a
+        * flush done event that will not be delivered.
+        */
+       if (rc != EALREADY)
+               EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+rhead_tx_qenable(
+       __in            efx_txq_t *etp)
+{
+       _NOTE(ARGUNUSED(etp))
+       /* Nothing to do here */
+}
+
+       __checkReturn           efx_rc_t
+rhead_tx_qdesc_post(
+       __in                    efx_txq_t *etp,
+       __in_ecount(ndescs)     efx_desc_t *ed,
+       __in                    unsigned int ndescs,
+       __in                    unsigned int completed,
+       __inout                 unsigned int *addedp)
+{
+       _NOTE(ARGUNUSED(etp))
+       _NOTE(ARGUNUSED(ed))
+       _NOTE(ARGUNUSED(ndescs))
+       _NOTE(ARGUNUSED(completed))
+       _NOTE(ARGUNUSED(addedp))
+
+       /* FIXME Implement the method for Riverhead */
+
+       return (ENOTSUP);
+}
+
+#if EFSYS_OPT_QSTATS
+
+                       void
+rhead_tx_qstats_update(
+       __in                            efx_txq_t *etp,
+       __inout_ecount(TX_NQSTATS)      efsys_stat_t *stat)
+{
+       unsigned int id;
+
+       for (id = 0; id < TX_NQSTATS; id++) {
+               efsys_stat_t *essp = &stat[id];
+
+               EFSYS_STAT_INCR(essp, etp->et_stat[id]);
+               etp->et_stat[id] = 0;
+       }
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
+#endif /* EFSYS_OPT_RIVERHEAD */