From: Ivan Malov <ivan.malov@arknetworks.am>
To: Dimon Zhao <dimon.zhao@nebula-matrix.com>
Cc: dev@dpdk.org, Kyo Liu <kyo.liu@nebula-matrix.com>,
Leon Yu <leon.yu@nebula-matrix.com>,
Sam Chen <sam.chen@nebula-matrix.com>
Subject: Re: [PATCH v4 12/16] net/nbl: add nbl device rxtx queue setup and release ops
Date: Wed, 13 Aug 2025 16:00:08 +0400 (+04) [thread overview]
Message-ID: <4f3c8fcf-099b-d148-310e-4ced78d0e846@arknetworks.am> (raw)
In-Reply-To: <20250813064410.3894506-13-dimon.zhao@nebula-matrix.com>
Hi Dimon,
(please see below)
On Tue, 12 Aug 2025, Dimon Zhao wrote:
> Implement NBL device Rx and Tx queue setup & release functions
>
> Signed-off-by: Dimon Zhao <dimon.zhao@nebula-matrix.com>
> ---
> drivers/net/nbl/nbl_dev/nbl_dev.c | 75 +++++
> drivers/net/nbl/nbl_dev/nbl_dev.h | 7 +
> drivers/net/nbl/nbl_ethdev.c | 4 +
> .../nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c | 2 +
> drivers/net/nbl/nbl_hw/nbl_resource.h | 99 ++++++
> drivers/net/nbl/nbl_hw/nbl_txrx.c | 285 ++++++++++++++++--
> drivers/net/nbl/nbl_hw/nbl_txrx.h | 99 ++++++
> drivers/net/nbl/nbl_include/nbl_def_common.h | 5 +
> drivers/net/nbl/nbl_include/nbl_include.h | 1 +
> 9 files changed, 555 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.c b/drivers/net/nbl/nbl_dev/nbl_dev.c
> index 86defd621d..17b9bd2c77 100644
> --- a/drivers/net/nbl/nbl_dev/nbl_dev.c
> +++ b/drivers/net/nbl/nbl_dev/nbl_dev.c
> @@ -57,6 +57,81 @@ int nbl_dev_port_close(struct rte_eth_dev *eth_dev)
> return 0;
> }
>
> +int nbl_tx_queue_setup(struct rte_eth_dev *eth_dev, u16 queue_idx,
> + u16 nb_desc, unsigned int socket_id, const struct rte_eth_txconf *conf)
> +{
> + struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> + struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> + struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> + struct nbl_dev_ring_mgt *ring_mgt = &dev_mgt->net_dev->ring_mgt;
> + struct nbl_dev_ring *tx_ring = &ring_mgt->tx_rings[queue_idx];
> + struct nbl_start_tx_ring_param param = { 0 };
> + int ret;
> +
> + param.queue_idx = queue_idx;
> + param.nb_desc = nb_desc;
> + param.socket_id = socket_id;
> + param.conf = conf;
> + param.product = adapter->caps.product_type;
> + param.bond_broadcast_check = NULL;
> + ret = disp_ops->start_tx_ring(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), ¶m, &tx_ring->dma);
> + if (ret) {
> + NBL_LOG(ERR, "start_tx_ring failed %d", ret);
> + return ret;
> + }
> +
> + tx_ring->desc_num = nb_desc;
> +
> + return ret;
> +}
> +
> +int nbl_rx_queue_setup(struct rte_eth_dev *eth_dev, u16 queue_idx,
> + u16 nb_desc, unsigned int socket_id,
> + const struct rte_eth_rxconf *conf, struct rte_mempool *mempool)
> +{
> + struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> + struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> + struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> + struct nbl_dev_ring_mgt *ring_mgt = &dev_mgt->net_dev->ring_mgt;
> + struct nbl_dev_ring *rx_ring = &ring_mgt->rx_rings[queue_idx];
> + struct nbl_start_rx_ring_param param = { 0 };
> + int ret;
> +
> + param.queue_idx = queue_idx;
> + param.nb_desc = nb_desc;
> + param.socket_id = socket_id;
> + param.conf = conf;
I don't see where this 'conf' is parsed. If the user has requested unsupported
offloads, say, unsupported RSS flow types, then the driver should give an error.
Does the driver actually parse user RSS configuration? User RSS key? RSS types?
Does the patch series allow user to set their own RETA table for RSS?
> + param.mempool = mempool;
> + param.product = adapter->caps.product_type;
> + ret = disp_ops->start_rx_ring(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), ¶m, &rx_ring->dma);
> + if (ret) {
> + NBL_LOG(ERR, "start_rx_ring failed %d", ret);
> + return ret;
> + }
> +
> + rx_ring->desc_num = nb_desc;
> +
> + return ret;
> +}
> +
> +void nbl_tx_queues_release(struct rte_eth_dev *eth_dev, uint16_t queue_id)
> +{
> + struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> + struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> + struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> +
> + disp_ops->release_tx_ring(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), queue_id);
> +}
> +
> +void nbl_rx_queues_release(struct rte_eth_dev *eth_dev, uint16_t queue_id)
> +{
> + struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> + struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> + struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> +
> + disp_ops->release_rx_ring(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), queue_id);
> +}
> +
> struct nbl_dev_ops dev_ops = {
> };
>
> diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.h b/drivers/net/nbl/nbl_dev/nbl_dev.h
> index ecfb6f6ae0..dca2233749 100644
> --- a/drivers/net/nbl/nbl_dev/nbl_dev.h
> +++ b/drivers/net/nbl/nbl_dev/nbl_dev.h
> @@ -56,5 +56,12 @@ int nbl_dev_configure(struct rte_eth_dev *eth_dev);
> int nbl_dev_port_start(struct rte_eth_dev *eth_dev);
> int nbl_dev_port_stop(struct rte_eth_dev *eth_dev);
> int nbl_dev_port_close(struct rte_eth_dev *eth_dev);
> +int nbl_tx_queue_setup(struct rte_eth_dev *eth_dev, u16 queue_idx,
> + u16 nb_desc, unsigned int socket_id, const struct rte_eth_txconf *conf);
> +int nbl_rx_queue_setup(struct rte_eth_dev *eth_dev, u16 queue_idx,
> + u16 nb_desc, unsigned int socket_id,
> + const struct rte_eth_rxconf *conf, struct rte_mempool *mempool);
> +void nbl_tx_queues_release(struct rte_eth_dev *eth_dev, uint16_t queue_id);
> +void nbl_rx_queues_release(struct rte_eth_dev *eth_dev, uint16_t queue_id);
>
> #endif
> diff --git a/drivers/net/nbl/nbl_ethdev.c b/drivers/net/nbl/nbl_ethdev.c
> index b773059306..51416eba91 100644
> --- a/drivers/net/nbl/nbl_ethdev.c
> +++ b/drivers/net/nbl/nbl_ethdev.c
> @@ -33,6 +33,10 @@ const struct eth_dev_ops nbl_eth_dev_ops = {
> .dev_start = nbl_dev_port_start,
> .dev_stop = nbl_dev_port_stop,
> .dev_close = nbl_dev_close,
> + .tx_queue_setup = nbl_tx_queue_setup,
> + .rx_queue_setup = nbl_rx_queue_setup,
> + .tx_queue_release = nbl_tx_queues_release,
> + .rx_queue_release = nbl_rx_queues_release,
> };
>
> static int nbl_eth_dev_init(struct rte_eth_dev *eth_dev)
> diff --git a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
> index 6327aa55b4..b785774f67 100644
> --- a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
> +++ b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
> @@ -53,6 +53,8 @@ static int nbl_res_start(struct nbl_resource_mgt_leonis *res_mgt_leonis)
> struct nbl_resource_mgt *res_mgt = &res_mgt_leonis->res_mgt;
> int ret;
>
> + res_mgt->res_info.base_qid = 0;
> +
> ret = nbl_txrx_mgt_start(res_mgt);
> if (ret)
> goto txrx_failed;
> diff --git a/drivers/net/nbl/nbl_hw/nbl_resource.h b/drivers/net/nbl/nbl_hw/nbl_resource.h
> index 07e6327259..543054a2cb 100644
> --- a/drivers/net/nbl/nbl_hw/nbl_resource.h
> +++ b/drivers/net/nbl/nbl_hw/nbl_resource.h
> @@ -16,12 +16,102 @@
> #define NBL_RES_MGT_TO_CHAN_OPS(res_mgt) (NBL_RES_MGT_TO_CHAN_OPS_TBL(res_mgt)->ops)
> #define NBL_RES_MGT_TO_CHAN_PRIV(res_mgt) (NBL_RES_MGT_TO_CHAN_OPS_TBL(res_mgt)->priv)
> #define NBL_RES_MGT_TO_ETH_DEV(res_mgt) ((res_mgt)->eth_dev)
> +#define NBL_RES_MGT_TO_COMMON(res_mgt) ((res_mgt)->common)
> #define NBL_RES_MGT_TO_TXRX_MGT(res_mgt) ((res_mgt)->txrx_mgt)
> +#define NBL_RES_MGT_TO_TX_RING(res_mgt, index) \
> + (NBL_RES_MGT_TO_TXRX_MGT(res_mgt)->tx_rings[(index)])
> +#define NBL_RES_MGT_TO_RX_RING(res_mgt, index) \
> + (NBL_RES_MGT_TO_TXRX_MGT(res_mgt)->rx_rings[(index)])
> +
> +struct nbl_packed_desc {
> + rte_le64_t addr;
> + rte_le32_t len;
> + rte_le16_t id;
> + rte_le16_t flags;
> +};
> +
> +struct nbl_tx_entry {
> + struct rte_mbuf *mbuf;
> + uint16_t first_id;
> +};
> +
> +struct nbl_rx_entry {
> + struct rte_mbuf *mbuf;
> +};
>
> struct nbl_res_tx_ring {
> + volatile struct nbl_packed_desc *desc;
> + struct nbl_tx_entry *tx_entry;
> + const struct rte_memzone *net_hdr_mz;
> + volatile uint8_t *notify;
> + struct rte_eth_dev *eth_dev;
> + struct nbl_common_info *common;
> + u64 default_hdr[2];
> +
> + enum nbl_product_type product;
> + int dma_limit_msb;
> + bool dma_set_msb;
> + u16 nb_desc;
> + u16 next_to_clean;
> + u16 next_to_use;
> +
> + u16 avail_used_flags;
> + bool used_wrap_counter;
> + u16 notify_qid;
> + u16 exthdr_len;
> +
> + u16 vlan_proto;
> + u16 vlan_tci;
> + u16 lag_id;
> + u16 vq_free_cnt;
> + /* Start freeing TX buffers if there are less free descriptors than this value */
> + u16 tx_free_thresh;
> + /* Number of Tx descriptors to use before RS bit is set */
> + u16 tx_rs_thresh;
> +
> + unsigned int size;
> +
> + u16 queue_id;
> +
> + u64 offloads;
> + u64 ring_phys_addr;
> +
> + u16 (*prep_tx_ehdr)(void *priv, struct rte_mbuf *mbuf);
> };
>
> struct nbl_res_rx_ring {
> + volatile struct nbl_packed_desc *desc;
> + struct nbl_rx_entry *rx_entry;
> + struct rte_mempool *mempool;
> + volatile uint8_t *notify;
> + struct rte_eth_dev *eth_dev;
> + struct nbl_common_info *common;
> + uint64_t mbuf_initializer; /**< value to init mbufs */
> + struct rte_mbuf fake_mbuf;
> +
> + enum nbl_product_type product;
> + int dma_limit_msb;
> + unsigned int size;
> + bool dma_set_msb;
> + u16 nb_desc;
> + u16 next_to_clean;
> + u16 next_to_use;
> +
> + u16 avail_used_flags;
> + bool used_wrap_counter;
> + u16 notify_qid;
> + u16 exthdr_len;
> +
> + u16 vlan_proto;
> + u16 vlan_tci;
> + u16 vq_free_cnt;
> + u16 port_id;
> +
> + u16 queue_id;
> + u16 buf_length;
> +
> + u64 offloads;
> + u64 ring_phys_addr;
> };
>
> struct nbl_txrx_mgt {
> @@ -33,11 +123,20 @@ struct nbl_txrx_mgt {
> u8 rx_ring_num;
> };
>
> +struct nbl_res_info {
> + u16 base_qid;
> + u16 lcore_max;
> + u16 *pf_qid_to_lcore_id;
> + rte_atomic16_t tx_current_queue;
> +};
> +
> struct nbl_resource_mgt {
> struct rte_eth_dev *eth_dev;
> struct nbl_channel_ops_tbl *chan_ops_tbl;
> struct nbl_phy_ops_tbl *phy_ops_tbl;
> struct nbl_txrx_mgt *txrx_mgt;
> + struct nbl_common_info *common;
> + struct nbl_res_info res_info;
> };
>
> struct nbl_resource_mgt_leonis {
> diff --git a/drivers/net/nbl/nbl_hw/nbl_txrx.c b/drivers/net/nbl/nbl_hw/nbl_txrx.c
> index eaa7e4c69d..c51a384445 100644
> --- a/drivers/net/nbl/nbl_hw/nbl_txrx.c
> +++ b/drivers/net/nbl/nbl_hw/nbl_txrx.c
> @@ -39,55 +39,296 @@ static void nbl_res_txrx_remove_rings(void *priv)
> rte_free(txrx_mgt->rx_rings);
> }
>
> -static int nbl_res_txrx_start_tx_ring(void *priv,
> - struct nbl_start_tx_ring_param *param,
> - u64 *dma_addr)
> +static inline u16 nbl_prep_tx_ehdr_leonis(void *priv, struct rte_mbuf *mbuf)
> {
> RTE_SET_USED(priv);
> - RTE_SET_USED(param);
> - RTE_SET_USED(dma_addr);
> + RTE_SET_USED(mbuf);
> return 0;
> }
>
> static void nbl_res_txrx_stop_tx_ring(void *priv, u16 queue_idx)
> {
> - RTE_SET_USED(priv);
> - RTE_SET_USED(queue_idx);
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_res_tx_ring *tx_ring = NBL_RES_MGT_TO_TX_RING(res_mgt, queue_idx);
> + int i;
> +
> + if (!tx_ring)
> + return;
> +
> + for (i = 0; i < tx_ring->nb_desc; i++) {
> + if (tx_ring->tx_entry[i].mbuf != NULL) {
> + rte_pktmbuf_free_seg(tx_ring->tx_entry[i].mbuf);
> + memset(&tx_ring->tx_entry[i], 0, sizeof(*tx_ring->tx_entry));
> + }
> + tx_ring->desc[i].flags = 0;
> + }
> +
> + tx_ring->avail_used_flags = BIT(NBL_PACKED_DESC_F_AVAIL);
> + tx_ring->used_wrap_counter = 1;
> + tx_ring->next_to_clean = NBL_TX_RS_THRESH - 1;
> + tx_ring->next_to_use = 0;
> + tx_ring->vq_free_cnt = tx_ring->nb_desc;
> }
>
> -static void nbl_res_txrx_release_txring(void *priv, u16 queue_idx)
> +static void nbl_res_txrx_release_tx_ring(void *priv, u16 queue_idx)
> {
> - RTE_SET_USED(priv);
> - RTE_SET_USED(queue_idx);
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_txrx_mgt *txrx_mgt = NBL_RES_MGT_TO_TXRX_MGT(res_mgt);
> + struct nbl_res_tx_ring *tx_ring = NBL_RES_MGT_TO_TX_RING(res_mgt, queue_idx);
> + if (!tx_ring)
> + return;
> + rte_free(tx_ring->tx_entry);
> + rte_free(tx_ring);
> + txrx_mgt->tx_rings[queue_idx] = NULL;
> }
>
> -static int nbl_res_txrx_start_rx_ring(void *priv,
> - struct nbl_start_rx_ring_param *param,
> +static int nbl_res_txrx_start_tx_ring(void *priv,
> + struct nbl_start_tx_ring_param *param,
> u64 *dma_addr)
> {
> - RTE_SET_USED(priv);
> - RTE_SET_USED(param);
> - RTE_SET_USED(dma_addr);
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_txrx_mgt *txrx_mgt = NBL_RES_MGT_TO_TXRX_MGT(res_mgt);
> + struct nbl_res_tx_ring *tx_ring = NBL_RES_MGT_TO_TX_RING(res_mgt, param->queue_idx);
> + struct rte_eth_dev *eth_dev = NBL_RES_MGT_TO_ETH_DEV(res_mgt);
> + struct nbl_common_info *common = NBL_RES_MGT_TO_COMMON(res_mgt);
> + struct nbl_phy_ops *phy_ops = NBL_RES_MGT_TO_PHY_OPS(res_mgt);
> + const struct rte_memzone *memzone;
> + const struct rte_memzone *net_hdr_mz;
> + char vq_hdr_name[NBL_VQ_HDR_NAME_MAXSIZE];
> + struct nbl_tx_ehdr_leonis ext_hdr = {0};
> + uint64_t offloads;
> + u32 size;
> +
> + offloads = param->conf->offloads | eth_dev->data->dev_conf.txmode.offloads;
> +
> + if (eth_dev->data->tx_queues[param->queue_idx] != NULL) {
> + NBL_LOG(WARNING, "re-setup an already allocated tx queue");
> + nbl_res_txrx_stop_tx_ring(priv, param->queue_idx);
> + eth_dev->data->tx_queues[param->queue_idx] = NULL;
> + }
> +
> + tx_ring = rte_zmalloc("nbl_txring", sizeof(*tx_ring), RTE_CACHE_LINE_SIZE);
> + if (!tx_ring) {
> + NBL_LOG(ERR, "allocate tx queue data structure failed");
> + return -ENOMEM;
> + }
> + memset(&tx_ring->default_hdr, 0, sizeof(tx_ring->default_hdr));
> + switch (param->product) {
> + case NBL_LEONIS_TYPE:
> + tx_ring->exthdr_len = sizeof(struct nbl_tx_ehdr_leonis);
> + tx_ring->prep_tx_ehdr = nbl_prep_tx_ehdr_leonis;
> + ext_hdr.fwd = NBL_TX_FWD_TYPE_NORMAL;
> + memcpy(&tx_ring->default_hdr, &ext_hdr, sizeof(struct nbl_tx_ehdr_leonis));
> + break;
> + default:
> + tx_ring->exthdr_len = sizeof(union nbl_tx_extend_head);
> + break;
> + };
> +
> + tx_ring->tx_entry = rte_calloc("nbl_tx_entry",
> + param->nb_desc, sizeof(*tx_ring->tx_entry), 0);
> + if (!tx_ring->tx_entry) {
> + NBL_LOG(ERR, "allocate tx queue %d software ring failed", param->queue_idx);
> + goto alloc_tx_entry_failed;
> + }
> +
> + /* Alloc twice memory, and second half is used to back up the desc for desc checking */
> + size = RTE_ALIGN_CEIL(sizeof(tx_ring->desc[0]) * param->nb_desc, 4096);
> + memzone = rte_eth_dma_zone_reserve(eth_dev, "tx_ring", param->queue_idx,
> + size, RTE_CACHE_LINE_SIZE,
> + param->socket_id);
> + if (memzone == NULL) {
> + NBL_LOG(ERR, "reserve dma zone for tx ring failed");
> + goto alloc_dma_zone_failed;
> + }
> +
> + /* if has no memory to put extend header, apply for new memory */
> + size = param->nb_desc * NBL_TX_HEADER_LEN;
> + snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
> + eth_dev->data->port_id, param->queue_idx);
> + net_hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, size,
> + param->socket_id,
> + RTE_MEMZONE_IOVA_CONTIG,
> + RTE_CACHE_LINE_SIZE);
> + if (net_hdr_mz == NULL) {
> + if (rte_errno == EEXIST)
> + net_hdr_mz = rte_memzone_lookup(vq_hdr_name);
> + if (net_hdr_mz == NULL) {
> + NBL_LOG(ERR, "reserve net_hdr_mz dma zone for tx ring failed");
> + goto reserve_net_hdr_mz_failed;
> + }
> + }
> +
> + tx_ring->product = param->product;
> + tx_ring->nb_desc = param->nb_desc;
> + tx_ring->vq_free_cnt = param->nb_desc;
> + tx_ring->queue_id = param->queue_idx;
> + tx_ring->notify_qid =
> + (res_mgt->res_info.base_qid + txrx_mgt->queue_offset + param->queue_idx) * 2 + 1;
> + tx_ring->ring_phys_addr = (u64)NBL_DMA_ADDERSS_FULL_TRANSLATE(common, memzone->iova);
> + tx_ring->avail_used_flags = BIT(NBL_PACKED_DESC_F_AVAIL);
> + tx_ring->used_wrap_counter = 1;
> + tx_ring->next_to_clean = NBL_TX_RS_THRESH - 1;
> + tx_ring->next_to_use = 0;
> + tx_ring->desc = (struct nbl_packed_desc *)memzone->addr;
> + tx_ring->net_hdr_mz = net_hdr_mz;
> + tx_ring->eth_dev = eth_dev;
> + tx_ring->dma_set_msb = common->dma_set_msb;
> + tx_ring->dma_limit_msb = common->dma_limit_msb;
> + tx_ring->notify = phy_ops->get_tail_ptr(NBL_RES_MGT_TO_PHY_PRIV(res_mgt));
> + tx_ring->offloads = offloads;
> + tx_ring->common = common;
> +
> + eth_dev->data->tx_queues[param->queue_idx] = tx_ring;
> +
> + txrx_mgt->tx_rings[param->queue_idx] = tx_ring;
> + txrx_mgt->tx_ring_num++;
> +
> + *dma_addr = tx_ring->ring_phys_addr;
> +
> return 0;
> +
> +reserve_net_hdr_mz_failed:
> + rte_memzone_free(memzone);
> +alloc_dma_zone_failed:
> + rte_free(tx_ring->tx_entry);
> + tx_ring->tx_entry = NULL;
> + tx_ring->size = 0;
> +alloc_tx_entry_failed:
> + rte_free(tx_ring);
> + return -ENOMEM;
> }
>
> -static int nbl_res_alloc_rx_bufs(void *priv, u16 queue_idx)
> +static void nbl_res_txrx_stop_rx_ring(void *priv, u16 queue_idx)
> {
> - RTE_SET_USED(priv);
> - RTE_SET_USED(queue_idx);
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_res_rx_ring *rx_ring =
> + NBL_RES_MGT_TO_RX_RING(res_mgt, queue_idx);
> + u16 i;
> +
> + if (!rx_ring)
> + return;
> + if (rx_ring->rx_entry != NULL) {
> + for (i = 0; i < rx_ring->nb_desc; i++) {
> + if (rx_ring->rx_entry[i].mbuf != NULL) {
> + rte_pktmbuf_free_seg(rx_ring->rx_entry[i].mbuf);
> + rx_ring->rx_entry[i].mbuf = NULL;
> + }
> + rx_ring->desc[i].flags = 0;
> + }
> +
> + for (i = rx_ring->nb_desc; i < rx_ring->nb_desc + NBL_DESC_PER_LOOP_VEC_MAX; i++)
> + rx_ring->desc[i].flags = 0;
> + }
> +
> + rx_ring->next_to_clean = 0;
> + rx_ring->next_to_use = 0;
> +}
> +
> +static int nbl_res_txrx_start_rx_ring(void *priv,
> + struct nbl_start_rx_ring_param *param,
> + u64 *dma_addr)
> +{
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_txrx_mgt *txrx_mgt = NBL_RES_MGT_TO_TXRX_MGT(res_mgt);
> + struct nbl_res_rx_ring *rx_ring = NBL_RES_MGT_TO_RX_RING(res_mgt, param->queue_idx);
> + struct rte_eth_dev *eth_dev = NBL_RES_MGT_TO_ETH_DEV(res_mgt);
> + struct nbl_phy_ops *phy_ops = NBL_RES_MGT_TO_PHY_OPS(res_mgt);
> + struct nbl_common_info *common = NBL_RES_MGT_TO_COMMON(res_mgt);
> + const struct rte_memzone *memzone;
> + u32 size;
> +
> + if (eth_dev->data->rx_queues[param->queue_idx] != NULL) {
> + NBL_LOG(WARNING, "re-setup an already allocated rx queue");
> + nbl_res_txrx_stop_rx_ring(priv, param->queue_idx);
> + eth_dev->data->rx_queues[param->queue_idx] = NULL;
> + }
> +
> + rx_ring = rte_zmalloc_socket("nbl_rxring", sizeof(*rx_ring),
> + RTE_CACHE_LINE_SIZE, param->socket_id);
> + if (rx_ring == NULL) {
> + NBL_LOG(ERR, "allocate rx queue data structure failed");
> + return -ENOMEM;
> + }
> +
> + size = sizeof(rx_ring->rx_entry[0]) * (param->nb_desc + NBL_DESC_PER_LOOP_VEC_MAX);
> + rx_ring->rx_entry = rte_zmalloc_socket("rxq rx_entry", size,
> + RTE_CACHE_LINE_SIZE,
> + param->socket_id);
> + if (rx_ring->rx_entry == NULL) {
> + NBL_LOG(ERR, "allocate rx queue %d software ring failed", param->queue_idx);
> + goto alloc_rx_entry_failed;
> + }
> +
> + size = sizeof(rx_ring->desc[0]) * (param->nb_desc + NBL_DESC_PER_LOOP_VEC_MAX);
> + memzone = rte_eth_dma_zone_reserve(eth_dev, "rx_ring", param->queue_idx,
> + size, RTE_CACHE_LINE_SIZE,
> + param->socket_id);
> + if (memzone == NULL) {
> + NBL_LOG(ERR, "reserve dma zone for rx ring failed");
> + goto alloc_dma_zone_failed;
> + }
> +
> + rx_ring->product = param->product;
> + rx_ring->mempool = param->mempool;
> + rx_ring->nb_desc = param->nb_desc;
> + rx_ring->queue_id = param->queue_idx;
> + rx_ring->notify_qid =
> + (res_mgt->res_info.base_qid + txrx_mgt->queue_offset + param->queue_idx) * 2;
> + rx_ring->ring_phys_addr = NBL_DMA_ADDERSS_FULL_TRANSLATE(common, memzone->iova);
> + rx_ring->desc = (struct nbl_packed_desc *)memzone->addr;
> + rx_ring->port_id = eth_dev->data->port_id;
> + rx_ring->eth_dev = eth_dev;
> + rx_ring->dma_set_msb = common->dma_set_msb;
> + rx_ring->dma_limit_msb = common->dma_limit_msb;
> + rx_ring->common = common;
> + rx_ring->notify = phy_ops->get_tail_ptr(NBL_RES_MGT_TO_PHY_PRIV(res_mgt));
> +
> + switch (param->product) {
> + case NBL_LEONIS_TYPE:
> + rx_ring->exthdr_len = sizeof(struct nbl_rx_ehdr_leonis);
> + break;
> + default:
> + rx_ring->exthdr_len = sizeof(union nbl_rx_extend_head);
> + };
> +
> + eth_dev->data->rx_queues[param->queue_idx] = rx_ring;
> +
> + txrx_mgt->rx_rings[param->queue_idx] = rx_ring;
> + txrx_mgt->rx_ring_num++;
> +
> + *dma_addr = rx_ring->ring_phys_addr;
> +
> return 0;
> +
> +alloc_dma_zone_failed:
> + rte_free(rx_ring->rx_entry);
> + rx_ring->rx_entry = NULL;
> + rx_ring->size = 0;
> +alloc_rx_entry_failed:
> + rte_free(rx_ring);
> + return -ENOMEM;
> }
>
> -static void nbl_res_txrx_stop_rx_ring(void *priv, u16 queue_idx)
> +static int nbl_res_alloc_rx_bufs(void *priv, u16 queue_idx)
> {
> RTE_SET_USED(priv);
> RTE_SET_USED(queue_idx);
> + return 0;
> }
>
> static void nbl_res_txrx_release_rx_ring(void *priv, u16 queue_idx)
> {
> - RTE_SET_USED(priv);
> - RTE_SET_USED(queue_idx);
> + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
> + struct nbl_txrx_mgt *txrx_mgt = NBL_RES_MGT_TO_TXRX_MGT(res_mgt);
> + struct nbl_res_rx_ring *rx_ring =
> + NBL_RES_MGT_TO_RX_RING(res_mgt, queue_idx);
> + if (!rx_ring)
> + return;
> +
> + rte_free(rx_ring->rx_entry);
> + rte_free(rx_ring);
> + txrx_mgt->rx_rings[queue_idx] = NULL;
> }
>
> static void nbl_res_txrx_update_rx_ring(void *priv, u16 index)
> @@ -106,7 +347,7 @@ do { \
> NBL_TXRX_SET_OPS(remove_rings, nbl_res_txrx_remove_rings); \
> NBL_TXRX_SET_OPS(start_tx_ring, nbl_res_txrx_start_tx_ring); \
> NBL_TXRX_SET_OPS(stop_tx_ring, nbl_res_txrx_stop_tx_ring); \
> - NBL_TXRX_SET_OPS(release_tx_ring, nbl_res_txrx_release_txring); \
> + NBL_TXRX_SET_OPS(release_tx_ring, nbl_res_txrx_release_tx_ring); \
> NBL_TXRX_SET_OPS(start_rx_ring, nbl_res_txrx_start_rx_ring); \
> NBL_TXRX_SET_OPS(alloc_rx_bufs, nbl_res_alloc_rx_bufs); \
> NBL_TXRX_SET_OPS(stop_rx_ring, nbl_res_txrx_stop_rx_ring); \
> diff --git a/drivers/net/nbl/nbl_hw/nbl_txrx.h b/drivers/net/nbl/nbl_hw/nbl_txrx.h
> index 56dbd3c587..83696dbc72 100644
> --- a/drivers/net/nbl/nbl_hw/nbl_txrx.h
> +++ b/drivers/net/nbl/nbl_hw/nbl_txrx.h
> @@ -7,4 +7,103 @@
>
> #include "nbl_resource.h"
>
> +#define NBL_PACKED_DESC_F_AVAIL (7)
> +#define NBL_PACKED_DESC_F_USED (15)
> +#define NBL_VRING_DESC_F_NEXT (1 << 0)
> +#define NBL_VRING_DESC_F_WRITE (1 << 1)
> +
> +#define NBL_TX_RS_THRESH (32)
> +#define NBL_TX_HEADER_LEN (32)
> +#define NBL_VQ_HDR_NAME_MAXSIZE (32)
> +
> +#define NBL_DESC_PER_LOOP_VEC_MAX (8)
> +
> +union nbl_tx_extend_head {
> + struct nbl_tx_ehdr_leonis {
> + /* DW0 */
> + u32 mac_len :5;
> + u32 ip_len :5;
> + u32 l4_len :4;
> + u32 l4_type :2;
> + u32 inner_ip_type :2;
> + u32 external_ip_type :2;
> + u32 external_ip_len :5;
> + u32 l4_tunnel_type :2;
> + u32 l4_tunnel_len :5;
> + /* DW1 */
> + u32 l4s_sid :10;
> + u32 l4s_sync_ind :1;
> + u32 l4s_redun_ind :1;
> + u32 l4s_redun_head_ind :1;
> + u32 l4s_hdl_ind :1;
> + u32 l4s_pbrac_mode :1;
> + u32 rsv0 :2;
> + u32 mss :14;
> + u32 tso :1;
> + /* DW2 */
> + /* if dport = NBL_TX_DPORT_ETH; dport_info = 0
> + * if dport = NBL_TX_DPORT_HOST; dport_info = host queue id
> + * if dport = NBL_TX_DPORT_ECPU; dport_info = ecpu queue_id
> + */
> + u32 dport_info :11;
> + /* if dport = NBL_TX_DPORT_ETH; dport_id[3:0] = eth port id, dport_id[9:4] = lag id
> + * if dport = NBL_TX_DPORT_HOST; dport_id[9:0] = host vsi_id
> + * if dport = NBL_TX_DPORT_ECPU; dport_id[9:0] = ecpu vsi_id
> + */
> + u32 dport_id :10;
> +#define NBL_TX_DPORT_ID_LAG_OFT_LEONIS (4)
> + u32 dport :3;
> +#define NBL_TX_DPORT_ETH (0)
> +#define NBL_TX_DPORT_HOST (1)
> +#define NBL_TX_DPORT_ECPU (2)
> +#define NBL_TX_DPORT_EMP (3)
> +#define NBL_TX_DPORT_BMC (4)
> +#define NBL_TX_DPORT_EMP_DRACO (2)
> +#define NBL_TX_DPORT_BMC_DRACO (3)
> + u32 fwd :2;
> +#define NBL_TX_FWD_TYPE_DROP (0)
> +#define NBL_TX_FWD_TYPE_NORMAL (1)
> +#define NBL_TX_FWD_TYPE_RSV (2)
> +#define NBL_TX_FWD_TYPE_CPU_ASSIGNED (3)
> + u32 rss_lag_en :1;
> + u32 l4_csum_en :1;
> + u32 l3_csum_en :1;
> + u32 rsv1 :3;
> + } leonis;
> +};
> +
> +union nbl_rx_extend_head {
> + struct nbl_rx_ehdr_leonis {
> + /* DW0 */
> + /* 0x0:eth, 0x1:host, 0x2:ecpu, 0x3:emp, 0x4:bcm */
> + u32 sport :3;
> + u32 dport_info :11;
> + /* sport = 0, sport_id[3:0] = eth id,
> + * sport = 1, sport_id[9:0] = host vsi_id,
> + * sport = 2, sport_id[9:0] = ecpu vsi_id,
> + */
> + u32 sport_id :10;
> + /* 0x0:drop, 0x1:normal, 0x2:cpu upcall */
> + u32 fwd :2;
> + u32 rsv0 :6;
> + /* DW1 */
> + u32 error_code :6;
> + u32 ptype :10;
> + u32 profile_id :4;
> + u32 checksum_status :1;
> + u32 rsv1 :1;
> + u32 l4s_sid :10;
> + /* DW2 */
> + u32 rsv3 :2;
> + u32 l4s_hdl_ind :1;
> + u32 l4s_tcp_offset :14;
> + u32 l4s_resync_ind :1;
> + u32 l4s_check_ind :1;
> + u32 l4s_dec_ind :1;
> + u32 rsv2 :4;
> + u32 num_buffers :8;
> + u32 hash_value;
> + } leonis;
> +};
> +
> #endif
> diff --git a/drivers/net/nbl/nbl_include/nbl_def_common.h b/drivers/net/nbl/nbl_include/nbl_def_common.h
> index f774afba00..25919330df 100644
> --- a/drivers/net/nbl/nbl_include/nbl_def_common.h
> +++ b/drivers/net/nbl/nbl_include/nbl_def_common.h
> @@ -79,6 +79,11 @@ struct nbl_dev_user_link_stat {
> #define NBL_DEV_USER_SET_PROMISC_MODE _IO(NBL_DEV_USER_TYPE, 10)
> #define NBL_DEV_USER_SET_MCAST_MODE _IO(NBL_DEV_USER_TYPE, 11)
>
> +#define NBL_DMA_ADDERSS_FULL_TRANSLATE(hw, address) \
Typo: ADDERSS -> ADDRESS?
Thank you.
> + ({ typeof(hw) _hw = (hw); \
> + ((((u64)((_hw)->dma_set_msb)) << ((u64)((_hw)->dma_limit_msb))) | (address)); \
> + })
> +
> struct nbl_dma_mem {
> void *va;
> uint64_t pa;
> diff --git a/drivers/net/nbl/nbl_include/nbl_include.h b/drivers/net/nbl/nbl_include/nbl_include.h
> index e10fcc9254..974a79835a 100644
> --- a/drivers/net/nbl/nbl_include/nbl_include.h
> +++ b/drivers/net/nbl/nbl_include/nbl_include.h
> @@ -91,6 +91,7 @@ struct nbl_start_tx_ring_param {
> u32 socket_id;
> enum nbl_product_type product;
> const struct rte_eth_txconf *conf;
> + bool (*bond_broadcast_check)(struct rte_mbuf *mbuf);
> };
>
> struct nbl_txrx_queue_param {
> --
> 2.34.1
>
>
next prev parent reply other threads:[~2025-08-13 12:00 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-27 1:40 [PATCH v3 00/16] NBL PMD for Nebulamatrix NICs dimon.zhao
2025-06-27 1:40 ` [PATCH v3 01/16] net/nbl: add doc and minimum nbl build framework dimon.zhao
2025-06-27 1:40 ` [PATCH v3 02/16] net/nbl: add simple probe/remove and log module dimon.zhao
2025-06-27 1:40 ` [PATCH v3 03/16] net/nbl: add PHY layer definitions and implementation dimon.zhao
2025-06-27 1:40 ` [PATCH v3 04/16] net/nbl: add Channel " dimon.zhao
2025-06-27 1:40 ` [PATCH v3 05/16] net/nbl: add Resource " dimon.zhao
2025-06-27 1:40 ` [PATCH v3 06/16] net/nbl: add Dispatch " dimon.zhao
2025-06-27 1:40 ` [PATCH v3 07/16] net/nbl: add Dev " dimon.zhao
2025-06-27 1:40 ` [PATCH v3 08/16] net/nbl: add complete device init and uninit functionality dimon.zhao
2025-06-27 1:40 ` [PATCH v3 09/16] net/nbl: add UIO and VFIO mode for nbl dimon.zhao
2025-06-27 1:40 ` [PATCH v3 10/16] net/nbl: add nbl coexistence " dimon.zhao
2025-06-27 1:40 ` [PATCH v3 11/16] net/nbl: add nbl ethdev configuration dimon.zhao
2025-06-27 1:40 ` [PATCH v3 12/16] net/nbl: add nbl device rxtx queue setup and release ops dimon.zhao
2025-06-27 1:40 ` [PATCH v3 13/16] net/nbl: add nbl device start and stop ops dimon.zhao
2025-06-27 1:40 ` [PATCH v3 14/16] net/nbl: add nbl device Tx and Rx burst dimon.zhao
2025-06-27 1:40 ` [PATCH v3 15/16] net/nbl: add nbl device xstats and stats dimon.zhao
2025-06-27 1:40 ` [PATCH v3 16/16] net/nbl: nbl device support set MTU and promisc dimon.zhao
2025-06-27 21:07 ` [PATCH v3 00/16] NBL PMD for Nebulamatrix NICs Stephen Hemminger
2025-06-27 21:40 ` Thomas Monjalon
2025-08-13 6:43 ` [PATCH v4 " Dimon Zhao
2025-08-13 6:43 ` [PATCH v4 01/16] net/nbl: add doc and minimum nbl build framework Dimon Zhao
2025-08-13 14:43 ` Stephen Hemminger
2025-08-13 6:43 ` [PATCH v4 02/16] net/nbl: add simple probe/remove and log module Dimon Zhao
2025-08-13 6:43 ` [PATCH v4 03/16] net/nbl: add PHY layer definitions and implementation Dimon Zhao
2025-08-13 9:30 ` Ivan Malov
2025-08-13 14:19 ` Stephen Hemminger
2025-08-13 6:43 ` [PATCH v4 04/16] net/nbl: add Channel " Dimon Zhao
2025-08-13 9:54 ` Ivan Malov
2025-08-13 14:21 ` Stephen Hemminger
2025-08-13 14:22 ` Stephen Hemminger
2025-08-13 14:25 ` Stephen Hemminger
2025-08-13 14:28 ` Stephen Hemminger
2025-08-13 6:43 ` [PATCH v4 05/16] net/nbl: add Resource " Dimon Zhao
2025-08-13 6:44 ` [PATCH v4 06/16] net/nbl: add Dispatch " Dimon Zhao
2025-08-13 6:44 ` [PATCH v4 07/16] net/nbl: add Dev " Dimon Zhao
2025-08-13 10:12 ` Ivan Malov
2025-08-13 6:44 ` [PATCH v4 08/16] net/nbl: add complete device init and uninit functionality Dimon Zhao
2025-08-13 6:44 ` [PATCH v4 09/16] net/nbl: add UIO and VFIO mode for nbl Dimon Zhao
2025-08-13 6:44 ` [PATCH v4 10/16] net/nbl: add nbl coexistence " Dimon Zhao
2025-08-13 10:35 ` Ivan Malov
2025-08-13 6:44 ` [PATCH v4 11/16] net/nbl: add nbl ethdev configuration Dimon Zhao
2025-08-13 10:40 ` Ivan Malov
2025-08-13 6:44 ` [PATCH v4 12/16] net/nbl: add nbl device rxtx queue setup and release ops Dimon Zhao
2025-08-13 12:00 ` Ivan Malov [this message]
2025-08-13 6:44 ` [PATCH v4 13/16] net/nbl: add nbl device start and stop ops Dimon Zhao
2025-08-13 6:44 ` [PATCH v4 14/16] net/nbl: add nbl device Tx and Rx burst Dimon Zhao
2025-08-13 11:31 ` Ivan Malov
2025-08-13 6:44 ` [PATCH v4 15/16] net/nbl: add nbl device xstats and stats Dimon Zhao
2025-08-13 11:48 ` Ivan Malov
2025-08-13 14:27 ` Stephen Hemminger
2025-08-13 6:44 ` [PATCH v4 16/16] net/nbl: nbl device support set MTU and promisc Dimon Zhao
2025-08-13 12:06 ` Ivan Malov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4f3c8fcf-099b-d148-310e-4ced78d0e846@arknetworks.am \
--to=ivan.malov@arknetworks.am \
--cc=dev@dpdk.org \
--cc=dimon.zhao@nebula-matrix.com \
--cc=kyo.liu@nebula-matrix.com \
--cc=leon.yu@nebula-matrix.com \
--cc=sam.chen@nebula-matrix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).