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 <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
This commit is contained in:
Andrew Rybchenko 2020-09-24 13:12:08 +01:00 committed by Ferruh Yigit
parent b6b29352f0
commit 4fd0181f6c
6 changed files with 311 additions and 10 deletions

View 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 */

View 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 */

View 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;

View File

@ -56,6 +56,7 @@ sources = [
'rhead_intr.c',
'rhead_nic.c',
'rhead_rx.c',
'rhead_tx.c',
]
extra_flags = [

View 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

View File

@ -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 */