From 4fd0181f6c00785ba4e2ed211ad27661d70587ad Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Thu, 24 Sep 2020 13:12:08 +0100 Subject: [PATCH] common/sfc_efx/base: implement Tx control path for Riverhead 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 Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx_impl.h | 6 +- drivers/common/sfc_efx/base/efx_mcdi.c | 6 +- drivers/common/sfc_efx/base/efx_tx.c | 33 ++++ drivers/common/sfc_efx/base/meson.build | 1 + drivers/common/sfc_efx/base/rhead_impl.h | 83 ++++++++++ drivers/common/sfc_efx/base/rhead_tx.c | 192 +++++++++++++++++++++++ 6 files changed, 311 insertions(+), 10 deletions(-) create mode 100644 drivers/common/sfc_efx/base/rhead_tx.c diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index fac2815f25..d7e11c6323 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -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 */ diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index 6a227858e6..278c5e2a64 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -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 */ diff --git a/drivers/common/sfc_efx/base/efx_tx.c b/drivers/common/sfc_efx/base/efx_tx.c index 38c64e028b..d7f31fd46d 100644 --- a/drivers/common/sfc_efx/base/efx_tx.c +++ b/drivers/common/sfc_efx/base/efx_tx.c @@ -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; diff --git a/drivers/common/sfc_efx/base/meson.build b/drivers/common/sfc_efx/base/meson.build index aff5017cff..8f944bb45b 100644 --- a/drivers/common/sfc_efx/base/meson.build +++ b/drivers/common/sfc_efx/base/meson.build @@ -56,6 +56,7 @@ sources = [ 'rhead_intr.c', 'rhead_nic.c', 'rhead_rx.c', + 'rhead_tx.c', ] extra_flags = [ diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index 0ba663653b..c3ffad7208 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -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 index 0000000000..4c60f329d1 --- /dev/null +++ b/drivers/common/sfc_efx/base/rhead_tx.c @@ -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 */ -- 2.20.1