From: Wenbo Cao <caowenbo@mucse.com>
To: thomas@monjalon.net, Wenbo Cao <caowenbo@mucse.com>
Cc: stephen@networkplumber.org, dev@dpdk.org, ferruh.yigit@amd.com,
andrew.rybchenko@oktetlabs.ru, yaojun@mucse.com
Subject: [PATCH v7 08/28] net/rnp: add queue setup and release operations
Date: Sat, 8 Feb 2025 10:43:45 +0800 [thread overview]
Message-ID: <1738982645-34550-9-git-send-email-caowenbo@mucse.com> (raw)
In-Reply-To: <1738982645-34550-1-git-send-email-caowenbo@mucse.com>
support tx/rx queue setup and release add hw bd
queue reset,sw queue reset.
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
doc/guides/nics/rnp.rst | 1 +
drivers/net/rnp/base/meson.build | 1 +
drivers/net/rnp/base/rnp_bdq_if.c | 397 ++++++++++++++++++++++++++++++
drivers/net/rnp/base/rnp_bdq_if.h | 149 +++++++++++
drivers/net/rnp/base/rnp_common.h | 4 +
drivers/net/rnp/base/rnp_dma_regs.h | 45 ++++
drivers/net/rnp/base/rnp_eth_regs.h | 4 +
drivers/net/rnp/base/rnp_hw.h | 3 +
drivers/net/rnp/base/rnp_osdep.h | 13 +
drivers/net/rnp/meson.build | 1 +
drivers/net/rnp/rnp.h | 2 +
drivers/net/rnp/rnp_ethdev.c | 29 +++
drivers/net/rnp/rnp_rxtx.c | 476 ++++++++++++++++++++++++++++++++++++
drivers/net/rnp/rnp_rxtx.h | 123 ++++++++++
14 files changed, 1248 insertions(+)
create mode 100644 drivers/net/rnp/base/rnp_bdq_if.c
create mode 100644 drivers/net/rnp/base/rnp_bdq_if.h
create mode 100644 drivers/net/rnp/rnp_rxtx.c
create mode 100644 drivers/net/rnp/rnp_rxtx.h
diff --git a/doc/guides/nics/rnp.rst b/doc/guides/nics/rnp.rst
index 62585ac..5417593 100644
--- a/doc/guides/nics/rnp.rst
+++ b/doc/guides/nics/rnp.rst
@@ -10,6 +10,7 @@ driver support for the inbuilt network device found in the **Mucse RNP**
Features
--------
+- Multiple queues for TX and RX
- Promiscuous mode
Prerequisites
diff --git a/drivers/net/rnp/base/meson.build b/drivers/net/rnp/base/meson.build
index b9db033..c2ef0d0 100644
--- a/drivers/net/rnp/base/meson.build
+++ b/drivers/net/rnp/base/meson.build
@@ -7,6 +7,7 @@ sources = [
'rnp_mbx_fw.c',
'rnp_common.c',
'rnp_mac.c',
+ 'rnp_bdq_if.c',
]
error_cflags = ['-Wno-unused-value',
diff --git a/drivers/net/rnp/base/rnp_bdq_if.c b/drivers/net/rnp/base/rnp_bdq_if.c
new file mode 100644
index 0000000..cc3fe51
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_bdq_if.c
@@ -0,0 +1,397 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include "rnp_osdep.h"
+
+#include "../rnp.h"
+#include "rnp_dma_regs.h"
+#include "rnp_eth_regs.h"
+#include "rnp_bdq_if.h"
+#include "rnp_common.h"
+#include "../rnp_rxtx.h"
+
+static void
+rnp_read_mac_veb(struct rnp_hw *hw,
+ u16 nr_lane,
+ u16 vf_id,
+ struct rnp_veb_cfg *cfg)
+{
+ cfg->mac_lo = RNP_E_REG_RD(hw, RNP_VEB_MAC_LO(nr_lane, vf_id));
+ cfg->mac_hi = RNP_E_REG_RD(hw, RNP_VEB_MAC_HI(nr_lane, vf_id));
+ cfg->ring = RNP_E_REG_RD(hw, RNP_VEB_VF_RING(nr_lane, vf_id));
+}
+
+static void
+rnp_update_mac_veb(struct rnp_hw *hw,
+ u16 nr_lane,
+ u16 vf_id,
+ struct rnp_veb_cfg *cfg)
+{
+ u32 reg = cfg->ring;
+ u16 idx = 0;
+
+ idx = nr_lane;
+ wmb();
+ RNP_E_REG_WR(hw, RNP_VEB_MAC_LO(idx, vf_id), cfg->mac_lo);
+ RNP_E_REG_WR(hw, RNP_VEB_MAC_HI(idx, vf_id), cfg->mac_hi);
+ reg |= ((RNP_VEB_SWITCH_VF_EN | vf_id) << 8);
+ RNP_E_REG_WR(hw, RNP_VEB_VF_RING(idx, vf_id), reg);
+}
+
+void
+rnp_rxq_flow_disable(struct rnp_hw *hw,
+ u16 hw_idx)
+{
+ u32 fc_ctrl;
+
+ spin_lock(&hw->rxq_reset_lock);
+ fc_ctrl = RNP_E_REG_RD(hw, RNP_RING_FC_EN(hw_idx));
+ wmb();
+ RNP_E_REG_WR(hw, RNP_RING_FC_THRESH(hw_idx), 0);
+ fc_ctrl |= 1 << (hw_idx % 32);
+ wmb();
+ RNP_E_REG_WR(hw, RNP_RING_FC_EN(hw_idx), fc_ctrl);
+}
+
+void
+rnp_rxq_flow_enable(struct rnp_hw *hw,
+ u16 hw_idx)
+{
+ u32 fc_ctrl;
+
+
+ fc_ctrl = RNP_E_REG_RD(hw, RNP_RING_FC_EN(hw_idx));
+ fc_ctrl &= ~(1 << (hw_idx % 32));
+ wmb();
+ RNP_E_REG_WR(hw, RNP_RING_FC_EN(hw_idx), fc_ctrl);
+
+ spin_unlock(&hw->rxq_reset_lock);
+}
+
+#define RNP_RXQ_RESET_PKT_LEN (64)
+
+static void
+rnp_reset_xmit(struct rnp_tx_queue *txq, u64 pkt_addr)
+{
+ volatile struct rnp_tx_desc *txbd;
+ struct rnp_txsw_entry *tx_entry;
+ u16 timeout = 0;
+ u16 tx_id;
+
+ tx_id = txq->tx_tail;
+ txbd = &txq->tx_bdr[tx_id];
+ tx_entry = &txq->sw_ring[tx_id];
+ memset(tx_entry, 0, sizeof(*tx_entry));
+
+ txbd->d.addr = pkt_addr;
+ txbd->d.blen = RNP_RXQ_RESET_PKT_LEN;
+ wmb();
+ txbd->d.cmd = cpu_to_le16(RNP_CMD_EOP | RNP_CMD_RS);
+ tx_id = (tx_id + 1) & txq->attr.nb_desc_mask;
+ wmb();
+ RNP_REG_WR(txq->tx_tailreg, 0, tx_id);
+ do {
+ if (txbd->d.cmd & RNP_CMD_DD)
+ break;
+ if (timeout == 1000)
+ RNP_PMD_ERR("rx queue %u reset send pkt is hang\n",
+ txq->attr.index);
+ timeout++;
+ udelay(10);
+ } while (1);
+}
+
+void
+rnp_reset_hw_rxq_op(struct rnp_hw *hw,
+ struct rnp_rx_queue *rxq,
+ struct rnp_tx_queue *txq,
+ struct rnp_rxq_reset_res *res)
+{
+ u8 reset_pcap[RNP_RXQ_RESET_PKT_LEN] = {
+ 0x01, 0x02, 0x27, 0xe2, 0x9f, 0xa6, 0x08, 0x00,
+ 0x27, 0xfc, 0x6a, 0xc9, 0x08, 0x00, 0x45, 0x00,
+ 0x01, 0xc4, 0xb5, 0xd0, 0x00, 0x7a, 0x40, 0x01,
+ 0xbc, 0xea, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01,
+ 0x01, 0x01, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
+ 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5,
+ 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd,
+ 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5};
+ struct rnp_veb_cfg veb_bak_cfg[RNP_MAX_PORT_OF_PF];
+ struct rnp_veb_cfg reset_cfg = {0};
+ volatile struct rnp_rx_desc *rxbd;
+ u16 index = rxq->attr.index;
+ u16 vf_num = hw->mbx.vf_num;
+ u8 *macaddr = res->eth_hdr;
+ u16 timeout = 0;
+ u16 vf_id = 0;
+ u16 head = 0;
+ u16 idx = 0;
+
+ memcpy(macaddr, reset_pcap, RNP_RXQ_RESET_PKT_LEN);
+ macaddr[5] = index;
+ reset_cfg.mac_hi = RNP_GET_MAC_HI(macaddr);
+ reset_cfg.mac_lo = RNP_GET_MAC_LO(macaddr);
+ reset_cfg.ring = index;
+ vf_id = (vf_num != UINT16_MAX) ? vf_num : index / 2;
+ if (hw->mbx.vf_num == UINT16_MAX) {
+ for (idx = 0; idx < RNP_MAX_PORT_OF_PF; idx++) {
+ rnp_read_mac_veb(hw, idx, vf_id, &veb_bak_cfg[idx]);
+ rnp_update_mac_veb(hw, idx, vf_id, &reset_cfg);
+ }
+ } else {
+ idx = rxq->attr.lane_id;
+ rnp_read_mac_veb(hw, idx, vf_id, &veb_bak_cfg[idx]);
+ rnp_update_mac_veb(hw, idx, vf_id, &reset_cfg);
+ }
+ wmb();
+ timeout = 0;
+ do {
+ if (!RNP_E_REG_RD(hw, RNP_RXQ_READY(index)))
+ break;
+ udelay(5);
+ timeout++;
+ } while (timeout < 100);
+ timeout = 0;
+ do {
+ if (RNP_E_REG_RD(hw, RNP_TXQ_READY(index)))
+ break;
+ udelay(10);
+ timeout++;
+ } while (timeout < 100);
+ rxq->rx_tail = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(index));
+ rxbd = &rxq->rx_bdr[rxq->rx_tail];
+ rxbd->d.pkt_addr = res->rx_pkt_addr;
+ if (rxq->rx_tail != rxq->attr.nb_desc_mask)
+ RNP_E_REG_WR(hw, RNP_RXQ_LEN(index), rxq->rx_tail + 1);
+ wmb();
+ RNP_REG_WR(rxq->rx_tailreg, 0, 0);
+ RNP_E_REG_WR(hw, RNP_RXQ_START(index), TRUE);
+ rnp_reset_xmit(txq, res->tx_pkt_addr);
+ timeout = 0;
+ do {
+ if (rxbd->wb.qword1.cmd & cpu_to_le32(RNP_CMD_DD))
+ break;
+ if (timeout == 1000)
+ RNP_PMD_LOG(ERR, "rx_queue[%d] reset queue hang\n",
+ index);
+ udelay(10);
+ timeout++;
+ } while (1);
+ timeout = 0;
+ do {
+ head = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(index));
+ if (head == 0)
+ break;
+ timeout++;
+ if (timeout == 1000)
+ RNP_PMD_LOG(ERR, "rx_queue[%d] reset head to 0 failed",
+ index);
+ udelay(10);
+ } while (1);
+ RNP_E_REG_WR(hw, RNP_RXQ_START(index), FALSE);
+ rxbd->d.pkt_addr = 0;
+ rxbd->d.cmd = 0;
+ if (hw->mbx.vf_num == UINT16_MAX) {
+ for (idx = 0; idx < 4; idx++)
+ rnp_update_mac_veb(hw, idx, vf_id, &veb_bak_cfg[idx]);
+ } else {
+ idx = rxq->attr.lane_id;
+ rnp_update_mac_veb(hw, idx, vf_id, &veb_bak_cfg[idx]);
+ }
+ rxq->rx_tail = head;
+}
+
+void rnp_setup_rxbdr(struct rnp_hw *hw,
+ struct rnp_rx_queue *rxq)
+{
+ u16 max_desc = rxq->attr.nb_desc;
+ u16 idx = rxq->attr.index;
+ phys_addr_t bd_address;
+ u32 dmah, dmal;
+ u32 desc_ctrl;
+
+ RNP_E_REG_WR(hw, RNP_RXQ_START(idx), FALSE);
+ bd_address = (phys_addr_t)rxq->ring_phys_addr;
+ dmah = upper_32_bits((uint64_t)bd_address);
+ dmal = lower_32_bits((uint64_t)bd_address);
+ desc_ctrl = rxq->pburst << RNQ_DESC_FETCH_BURST_S | rxq->pthresh;
+ if (hw->mbx.sriov_st)
+ dmah |= (hw->mbx.sriov_st << 24);
+ /* we must set sriov_state to hi dma_address high 8bit for vf isolation
+ * |---8bit-----|----------24bit--------|
+ * |sriov_state-|-------high dma address|
+ * |---------------8bit-----------------|
+ * |7bit | 6bit |5-0bit-----------------|
+ * |vf_en|pf_num|-------vf_num----------|
+ */
+ RNP_E_REG_WR(hw, RNP_RXQ_BASE_ADDR_LO(idx), dmal);
+ RNP_E_REG_WR(hw, RNP_RXQ_BASE_ADDR_HI(idx), dmah);
+ RNP_E_REG_WR(hw, RNP_RXQ_LEN(idx), max_desc);
+ rxq->rx_tailreg = (u32 *)((u8 *)hw->e_ctrl + RNP_RXQ_TAIL(idx));
+ rxq->rx_headreg = (u32 *)((u8 *)hw->e_ctrl + RNP_RXQ_HEAD(idx));
+ rxq->rx_tail = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(idx));
+ RNP_E_REG_WR(hw, RNP_RXQ_DESC_FETCH_CTRL(idx), desc_ctrl);
+ RNP_E_REG_WR(hw, RNP_RXQ_DROP_TIMEOUT_TH(idx),
+ rxq->nodesc_tm_thresh);
+}
+
+int rnp_get_dma_ring_index(struct rnp_eth_port *port, u16 queue_idx)
+{
+ struct rnp_hw *hw = port->hw;
+ u16 lane = port->attr.nr_lane;
+ u16 hwrid = 0;
+
+ switch (hw->nic_mode) {
+ case RNP_DUAL_10G:
+ hwrid = 2 * (queue_idx + lane) - queue_idx % 2;
+ break;
+ case RNP_QUAD_10G:
+ hwrid = 4 * (queue_idx) + lane;
+ break;
+ default:
+ hwrid = queue_idx;
+ }
+
+ return hwrid;
+}
+
+void rnp_setup_txbdr(struct rnp_hw *hw, struct rnp_tx_queue *txq)
+{
+ u16 max_desc = txq->attr.nb_desc;
+ u16 idx = txq->attr.index;
+ phys_addr_t bd_address;
+ u32 desc_ctrl = 0;
+ u32 dmah, dmal;
+
+ bd_address = (phys_addr_t)txq->ring_phys_addr;
+ desc_ctrl = txq->pburst << RNQ_DESC_FETCH_BURST_S | txq->pthresh;
+ dmah = upper_32_bits((u64)bd_address);
+ dmal = lower_32_bits((u64)bd_address);
+ if (hw->mbx.sriov_st)
+ dmah |= (hw->mbx.sriov_st << 24);
+ /* We must set sriov_state to hi dma_address high 8bit for vf isolation
+ * |---8bit-----|----------24bit--------|
+ * |sriov_state-|-------high dma address|
+ * |---------------8bit-----------------|
+ * |7bit | 6bit |5-0bit-----------------|
+ * |vf_en|pf_num|-------vf_num----------|
+ */
+ RNP_E_REG_WR(hw, RNP_TXQ_BASE_ADDR_LO(idx), dmal);
+ RNP_E_REG_WR(hw, RNP_TXQ_BASE_ADDR_HI(idx), dmah);
+ RNP_E_REG_WR(hw, RNP_TXQ_LEN(idx), max_desc);
+ RNP_E_REG_WR(hw, RNP_TXQ_DESC_FETCH_CTRL(idx), desc_ctrl);
+ RNP_E_REG_WR(hw, RNP_RXTX_IRQ_MASK(idx), RNP_RXTX_IRQ_MASK_ALL);
+ txq->tx_headreg = (void *)((u8 *)hw->e_ctrl + RNP_TXQ_HEAD(idx));
+ txq->tx_tailreg = (void *)((u8 *)hw->e_ctrl + RNP_TXQ_TAIL(idx));
+
+ txq->tx_tail = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(idx));
+ RNP_E_REG_WR(hw, RNP_TXQ_TAIL(idx), 0);
+}
+
+static void
+rnp_txq_reset_pre(struct rnp_hw *hw)
+{
+ u16 i = 0;
+
+ spin_lock(&hw->txq_reset_lock);
+ for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
+ wmb();
+ RNP_E_REG_WR(hw, RNP_RXQ_START(i), 0);
+ }
+}
+
+static void
+rnp_txq_reset_fin(struct rnp_hw *hw)
+{
+ u16 i = 0;
+
+ for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
+ wmb();
+ RNP_E_REG_WR(hw, RNP_RXQ_START(i), 1);
+ }
+ spin_unlock(&hw->txq_reset_lock);
+}
+
+static void
+rnp_xmit_nop_frame_ring(struct rnp_hw *hw,
+ struct rnp_tx_queue *txq,
+ u16 head)
+{
+ volatile struct rnp_tx_desc *tx_desc;
+ u16 check_head = 0;
+ u16 timeout = 0;
+ u16 index = 0;
+ u16 tx_id;
+
+ tx_id = head;
+ index = txq->attr.index;
+ tx_desc = &txq->tx_bdr[tx_id];
+
+ /* set length to 0 */
+ tx_desc->d.blen = 0;
+ tx_desc->d.addr = 0;
+ wmb();
+ tx_desc->d.cmd = cpu_to_le16(RNP_CMD_EOP);
+ wmb();
+ /* update tail */
+ RNP_REG_WR(txq->tx_tailreg, 0, 0);
+ do {
+ check_head = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
+ if (check_head == 0)
+ break;
+ if (timeout == 1000)
+ RNP_PMD_ERR("tx_queue[%d] reset may be hang "
+ "check_head %d base head %d\n",
+ index, check_head, head);
+ timeout++;
+ udelay(10);
+ } while (1);
+ /* restore the origin right state */
+ wmb();
+ RNP_E_REG_WR(hw, RNP_TXQ_LEN(index), txq->attr.nb_desc);
+}
+
+void rnp_reset_hw_txq_op(struct rnp_hw *hw,
+ struct rnp_tx_queue *txq)
+{
+ u16 timeout = 0;
+ u16 index = 0;
+ u16 head;
+ u16 tail;
+
+ timeout = 0;
+ /* Disable Tx Queue */
+ index = txq->attr.index;
+ rnp_txq_reset_pre(hw);
+ rmb();
+ tail = RNP_E_REG_RD(hw, RNP_TXQ_TAIL(index));
+ txq->tx_tail = tail;
+ do {
+ /* wait for hw head is stopped */
+ head = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
+ if (head == txq->tx_tail)
+ break;
+ if (timeout > 1000) {
+ RNP_PMD_ERR("txq[%u] 1000*10us can't "
+ "wait for hw head == tail\n", index);
+ break;
+ }
+ udelay(10);
+ } while (1);
+ rmb();
+ head = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
+ /* head is zero no need to reset */
+ if (head == 0)
+ goto tx_reset_fin;
+ wmb();
+ if (head != txq->attr.nb_desc_mask)
+ RNP_E_REG_WR(hw, RNP_TXQ_LEN(index), head + 1);
+ wmb();
+ /* reset hw head */
+ rnp_xmit_nop_frame_ring(hw, txq, head);
+ rmb();
+ txq->tx_tail = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
+tx_reset_fin:
+ rnp_txq_reset_fin(hw);
+}
diff --git a/drivers/net/rnp/base/rnp_bdq_if.h b/drivers/net/rnp/base/rnp_bdq_if.h
new file mode 100644
index 0000000..61a3832
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_bdq_if.h
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_BDQ_IF_H_
+#define _RNP_BDQ_IF_H_
+
+#include "rnp_hw.h"
+
+struct rnp_rx_queue;
+struct rnp_tx_queue;
+#pragma pack(push)
+#pragma pack(1)
+/* receive descriptor */
+struct rnp_rx_desc {
+ /* rx buffer descriptor */
+ union {
+ struct {
+ u64 pkt_addr;
+ u16 rsvd[3];
+ u16 cmd;
+ } d;
+ struct {
+ struct {
+ u32 rss_hash;
+ u32 mark_data;
+ } qword0;
+ struct {
+ u32 lens;
+ u16 vlan_tci;
+ u16 cmd;
+ } qword1;
+ } wb;
+ };
+};
+/* tx buffer descriptors (BD) */
+struct rnp_tx_desc {
+ union {
+ struct {
+ u64 addr; /* pkt dma address */
+ u16 blen; /* pkt data Len */
+ u16 mac_ip_len; /* mac ip header len */
+ u16 vlan_tci; /* vlan_tci */
+ u16 cmd; /* ctrl command */
+ } d;
+ struct {
+ struct {
+ u16 mss; /* tso sz */
+ u8 vf_num; /* vf num */
+ u8 l4_len; /* l4 header size */
+ u8 tunnel_len; /* tunnel header size */
+ u16 vlan_tci; /* vlan_tci */
+ u8 veb_tran; /* mark pkt is transmit by veb */
+ } qword0;
+ struct {
+ u16 rsvd[3];
+ u16 cmd; /* ctrl command */
+ } qword1;
+ } c;
+ };
+};
+#pragma pack(pop)
+/* common command */
+#define RNP_CMD_EOP RTE_BIT32(0) /* End Of Packet */
+#define RNP_CMD_DD RTE_BIT32(1)
+#define RNP_CMD_RS RTE_BIT32(2)
+#define RNP_DESC_TYPE_S (3)
+#define RNP_DATA_DESC (0x00UL << RNP_DESC_TYPE_S)
+#define RNP_CTRL_DESC (0x01UL << RNP_DESC_TYPE_S)
+/* rx data cmd */
+#define RNP_RX_PTYPE_PTP RTE_BIT32(4)
+#define RNP_RX_L3TYPE_S (5)
+#define RNP_RX_L3TYPE_IPV4 (0x00UL << RNP_RX_L3TYPE_S)
+#define RNP_RX_L3TYPE_IPV6 (0x01UL << RNP_RX_L3TYPE_S)
+#define RNP_RX_L4TYPE_S (6)
+#define RNP_RX_L4TYPE_TCP (0x01UL << RNP_RX_L4TYPE_S)
+#define RNP_RX_L4TYPE_SCTP (0x02UL << RNP_RX_L4TYPE_S)
+#define RNP_RX_L4TYPE_UDP (0x03UL << RNP_RX_L4TYPE_S)
+#define RNP_RX_ERR_MASK RTE_GENMASK32(12, 8)
+#define RNP_RX_L3_ERR RTE_BIT32(8)
+#define RNP_RX_L4_ERR RTE_BIT32(9)
+#define RNP_RX_SCTP_ERR RTE_BIT32(10)
+#define RNP_RX_IN_L3_ERR RTE_BIT32(11)
+#define RNP_RX_IN_L4_ERR RTE_BIT32(12)
+#define RNP_RX_TUNNEL_TYPE_S (13)
+#define RNP_RX_PTYPE_VXLAN (0x01UL << RNP_RX_TUNNEL_TYPE_S)
+#define RNP_RX_PTYPE_NVGRE (0x02UL << RNP_RX_TUNNEL_TYPE_S)
+#define RNP_RX_PTYPE_VLAN RTE_BIT32(15)
+/* tx data cmd */
+#define RNP_TX_TSO_EN RTE_BIT32(4)
+#define RNP_TX_L3TYPE_S (5)
+#define RNP_TX_L3TYPE_IPV6 (0x01UL << RNP_TX_L3TYPE_S)
+#define RNP_TX_L3TYPE_IPV4 (0x00UL << RNP_TX_L3TYPE_S)
+#define RNP_TX_L4TYPE_S (6)
+#define RNP_TX_L4TYPE_TCP (0x01UL << RNP_TX_L4TYPE_S)
+#define RNP_TX_L4TYPE_SCTP (0x02UL << RNP_TX_L4TYPE_S)
+#define RNP_TX_L4TYPE_UDP (0x03UL << RNP_TX_L4TYPE_S)
+#define RNP_TX_TUNNEL_TYPE_S (8)
+#define RNP_TX_VXLAN_TUNNEL (0x01UL << RNP_TX_TUNNEL_TYPE_S)
+#define RNP_TX_NVGRE_TUNNEL (0x02UL << RNP_TX_TUNNEL_TYPE_S)
+#define RNP_TX_PTP_EN RTE_BIT32(10)
+#define RNP_TX_IP_CKSUM_EN RTE_BIT32(11)
+#define RNP_TX_L4CKSUM_EN RTE_BIT32(12)
+#define RNP_TX_VLAN_CTRL_S (13)
+#define RNP_TX_VLAN_STRIP (0x01UL << RNP_TX_VLAN_CTRL_S)
+#define RNP_TX_VLAN_INSERT (0x02UL << RNP_TX_VLAN_CTRL_S)
+#define RNP_TX_VLAN_VALID RTE_BIT32(15)
+/* tx data mac_ip len */
+#define RNP_TX_MAC_LEN_S (9)
+/* tx ctrl cmd */
+#define RNP_TX_LEN_PAD_S (8)
+#define RNP_TX_OFF_MAC_PAD (0x01UL << RNP_TX_LEN_PAD_S)
+#define RNP_TX_QINQ_CTRL_S (10)
+#define RNP_TX_QINQ_INSERT (0x02UL << RNP_TX_QINQ_CTRL_S)
+#define RNP_TX_QINQ_STRIP (0x01UL << RNP_TX_QINQ_CTRL_S)
+#define RNP_TX_TO_NPU_EN RTE_BIT32(15)
+/* descript op end */
+struct rnp_rxq_reset_res {
+ u64 rx_pkt_addr;
+ u64 tx_pkt_addr;
+ u8 *eth_hdr;
+};
+struct rnp_veb_cfg {
+ uint32_t mac_hi;
+ uint32_t mac_lo;
+ uint32_t vid;
+ uint16_t vf_id;
+ uint16_t ring;
+};
+void
+rnp_rxq_flow_enable(struct rnp_hw *hw,
+ u16 hw_idx);
+void
+rnp_rxq_flow_disable(struct rnp_hw *hw,
+ u16 hw_idx);
+void
+rnp_reset_hw_rxq_op(struct rnp_hw *hw,
+ struct rnp_rx_queue *rxq,
+ struct rnp_tx_queue *txq,
+ struct rnp_rxq_reset_res *res);
+void rnp_reset_hw_txq_op(struct rnp_hw *hw,
+ struct rnp_tx_queue *txq);
+void rnp_setup_rxbdr(struct rnp_hw *hw,
+ struct rnp_rx_queue *rxq);
+void rnp_setup_txbdr(struct rnp_hw *hw,
+ struct rnp_tx_queue *txq);
+int rnp_get_dma_ring_index(struct rnp_eth_port *port, u16 queue_idx);
+
+#endif /* _RNP_BDQ_IF_H_ */
diff --git a/drivers/net/rnp/base/rnp_common.h b/drivers/net/rnp/base/rnp_common.h
index aaf77a6..bd00708 100644
--- a/drivers/net/rnp/base/rnp_common.h
+++ b/drivers/net/rnp/base/rnp_common.h
@@ -6,6 +6,10 @@
#define _RNP_COMMON_H_
#define RNP_NIC_RESET _NIC_(0x0010)
+#define RNP_GET_MAC_HI(mac_addr) (((macaddr[0]) << 8) | (macaddr[1]))
+#define RNP_GET_MAC_LO(mac_addr) \
+ ((macaddr[2] << 24) | (macaddr[3] << 16) | \
+ ((macaddr[4] << 8)) | (macaddr[5]))
int rnp_init_hw(struct rnp_hw *hw);
int rnp_setup_common_ops(struct rnp_hw *hw);
diff --git a/drivers/net/rnp/base/rnp_dma_regs.h b/drivers/net/rnp/base/rnp_dma_regs.h
index 00f8aff..3664c0a 100644
--- a/drivers/net/rnp/base/rnp_dma_regs.h
+++ b/drivers/net/rnp/base/rnp_dma_regs.h
@@ -9,5 +9,50 @@
#define RNP_DMA_HW_EN (0x10)
#define RNP_DMA_EN_ALL (0b1111)
#define RNP_DMA_HW_STATE (0x14)
+/* --- queue register --- */
+/* queue enable */
+#define RNP_RXQ_START(qid) _RING_(0x0010 + 0x100 * (qid))
+#define RNP_RXQ_READY(qid) _RING_(0x0014 + 0x100 * (qid))
+#define RNP_TXQ_START(qid) _RING_(0x0018 + 0x100 * (qid))
+#define RNP_TXQ_READY(qid) _RING_(0x001c + 0x100 * (qid))
+/* queue irq generate ctrl */
+#define RNP_RXTX_IRQ_STAT(qid) _RING_(0x0020 + 0x100 * (qid))
+#define RNP_RXTX_IRQ_MASK(qid) _RING_(0x0024 + 0x100 * (qid))
+#define RNP_TX_IRQ_MASK RTE_BIT32(1)
+#define RNP_RX_IRQ_MASK RTE_BIT32(0)
+#define RNP_RXTX_IRQ_MASK_ALL (RNP_RX_IRQ_MASK | RNP_TX_IRQ_MASK)
+#define RNP_RXTX_IRQ_CLER(qid) _RING_(0x0028 + 0x100 * (qid))
+/* rx-queue setup */
+#define RNP_RXQ_BASE_ADDR_HI(qid) _RING_(0x0030 + 0x100 * (qid))
+#define RNP_RXQ_BASE_ADDR_LO(qid) _RING_(0x0034 + 0x100 * (qid))
+#define RNP_RXQ_LEN(qid) _RING_(0x0038 + 0x100 * (qid))
+#define RNP_RXQ_HEAD(qid) _RING_(0x003c + 0x100 * (qid))
+#define RNP_RXQ_TAIL(qid) _RING_(0x0040 + 0x100 * (qid))
+#define RNP_RXQ_DESC_FETCH_CTRL(qid) _RING_(0x0044 + 0x100 * (qid))
+/* rx queue interrupt generate pararm */
+#define RNP_RXQ_INT_DELAY_TIMER(qid) _RING_(0x0048 + 0x100 * (qid))
+#define RNP_RXQ_INT_DELAY_PKTCNT(qidx) _RING_(0x004c + 0x100 * (qid))
+#define RNP_RXQ_RX_PRI_LVL(qid) _RING_(0x0050 + 0x100 * (qid))
+#define RNP_RXQ_DROP_TIMEOUT_TH(qid) _RING_(0x0054 + 0x100 * (qid))
+/* tx queue setup */
+#define RNP_TXQ_BASE_ADDR_HI(qid) _RING_(0x0060 + 0x100 * (qid))
+#define RNP_TXQ_BASE_ADDR_LO(qid) _RING_(0x0064 + 0x100 * (qid))
+#define RNP_TXQ_LEN(qid) _RING_(0x0068 + 0x100 * (qid))
+#define RNP_TXQ_HEAD(qid) _RING_(0x006c + 0x100 * (qid))
+#define RNP_TXQ_TAIL(qid) _RING_(0x0070 + 0x100 * (qid))
+#define RNP_TXQ_DESC_FETCH_CTRL(qid) _RING_(0x0074 + 0x100 * (qid))
+#define RNQ_DESC_FETCH_BURST_S (16)
+/* tx queue interrupt generate pararm */
+#define RNP_TXQ_INT_DELAY_TIMER(qid) _RING_(0x0078 + 0x100 * (qid))
+#define RNP_TXQ_INT_DELAY_PKTCNT(qid) _RING_(0x007c + 0x100 * (qid))
+/* veb ctrl register */
+#define RNP_VEB_MAC_LO(p, n) _RING_(0x00a0 + (4 * (p)) + (0x100 * (n)))
+#define RNP_VEB_MAC_HI(p, n) _RING_(0x00b0 + (4 * (p)) + (0x100 * (n)))
+#define RNP_VEB_VID_CFG(p, n) _RING_(0x00c0 + (4 * (p)) + (0x100 * (n)))
+#define RNP_VEB_VF_RING(p, n) _RING_(0x00d0 + (4 * (p)) + (0x100 * (n)))
+#define RNP_MAX_VEB_TB (64)
+#define RNP_VEB_RING_CFG_S (8)
+#define RNP_VEB_SWITCH_VF_EN RTE_BIT32(7)
+#define MAX_VEB_TABLES_NUM (4)
#endif /* _RNP_DMA_REGS_H_ */
diff --git a/drivers/net/rnp/base/rnp_eth_regs.h b/drivers/net/rnp/base/rnp_eth_regs.h
index c4519ba..10e3d95 100644
--- a/drivers/net/rnp/base/rnp_eth_regs.h
+++ b/drivers/net/rnp/base/rnp_eth_regs.h
@@ -10,6 +10,10 @@
#define RNP_E_FILTER_EN _ETH_(0x801c)
#define RNP_E_REDIR_EN _ETH_(0x8030)
+/* rx queue flow ctrl */
+#define RNP_RX_FC_ENABLE _ETH_(0x8520)
+#define RNP_RING_FC_EN(n) _ETH_(0x8524 + ((0x4) * ((n) / 32)))
+#define RNP_RING_FC_THRESH(n) _ETH_(0x8a00 + ((0x4) * (n)))
/* Mac Host Filter */
#define RNP_MAC_FCTRL _ETH_(0x9110)
#define RNP_MAC_FCTRL_MPE RTE_BIT32(8) /* Multicast Promiscuous En */
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
index 1b31362..4f5a73e 100644
--- a/drivers/net/rnp/base/rnp_hw.h
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -120,6 +120,9 @@ struct rnp_hw {
bool lane_is_sgmii[RNP_MAX_PORT_OF_PF];
struct rnp_mbx_info mbx;
struct rnp_fw_info fw_info;
+
+ spinlock_t rxq_reset_lock;
+ spinlock_t txq_reset_lock;
};
#endif /* __RNP_H__*/
diff --git a/drivers/net/rnp/base/rnp_osdep.h b/drivers/net/rnp/base/rnp_osdep.h
index 03f6c51..137e0e8 100644
--- a/drivers/net/rnp/base/rnp_osdep.h
+++ b/drivers/net/rnp/base/rnp_osdep.h
@@ -14,6 +14,7 @@
#include <rte_bitops.h>
#include <rte_cycles.h>
#include <rte_byteorder.h>
+#include <rte_spinlock.h>
#include <rte_common.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
@@ -32,16 +33,28 @@
#define mb() rte_mb()
#define wmb() rte_wmb()
+#define rmb() rte_rmb()
#define udelay(x) rte_delay_us(x)
#define mdelay(x) rte_delay_ms(x)
#define memcpy rte_memcpy
+#ifndef upper_32_bits
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
+#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
+#endif
+
+#ifndef cpu_to_le32
+#define cpu_to_le16(v) rte_cpu_to_le_16((u16)(v))
+#define cpu_to_le32(v) rte_cpu_to_le_32((u32)(v))
+#endif
+
#define spinlock_t rte_spinlock_t
#define spin_lock_init(spinlock_v) rte_spinlock_init(spinlock_v)
#define spin_lock(spinlock_v) rte_spinlock_lock(spinlock_v)
#define spin_unlock(spinlock_v) rte_spinlock_unlock(spinlock_v)
+#define _RING_(off) ((off) + (0x08000))
#define _ETH_(off) ((off) + (0x10000))
#define _NIC_(off) ((off) + (0x30000))
#define _MAC_(off) ((off) + (0x60000))
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index 29e6d49..ff3dc41 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -14,4 +14,5 @@ includes += include_directories('base')
sources = files(
'rnp_ethdev.c',
+ 'rnp_rxtx.c',
)
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index 19ef493..ab7bd60 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -105,6 +105,7 @@ struct rnp_eth_port {
struct rte_ether_addr mac_addr;
struct rte_eth_dev *eth_dev;
struct rnp_port_attr attr;
+ struct rnp_tx_queue *tx_queues[RNP_MAX_RX_QUEUE_NUM];
struct rnp_hw *hw;
};
@@ -113,6 +114,7 @@ struct rnp_eth_adapter {
struct rte_pci_device *pdev;
struct rte_eth_dev *eth_dev; /* alloc eth_dev by platform */
+ struct rte_mempool *reset_pool;
struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF];
uint16_t closed_ports;
uint16_t inited_ports;
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 13d949a..d5e5ef7 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -14,6 +14,7 @@
#include "base/rnp_mbx_fw.h"
#include "base/rnp_mac.h"
#include "base/rnp_common.h"
+#include "rnp_rxtx.h"
static struct rte_eth_dev *
rnp_alloc_eth_port(struct rte_pci_device *pci, char *name)
@@ -237,6 +238,11 @@ static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev)
.promiscuous_disable = rnp_promiscuous_disable,
.allmulticast_enable = rnp_allmulticast_enable,
.allmulticast_disable = rnp_allmulticast_disable,
+
+ .rx_queue_setup = rnp_rx_queue_setup,
+ .rx_queue_release = rnp_dev_rx_queue_release,
+ .tx_queue_setup = rnp_tx_queue_setup,
+ .tx_queue_release = rnp_dev_tx_queue_release,
};
static void
@@ -330,6 +336,26 @@ static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev)
}
static int
+rnp_rx_reset_pool_setup(struct rnp_eth_adapter *adapter)
+{
+ struct rte_eth_dev *eth_dev = adapter->eth_dev;
+ char name[RTE_MEMPOOL_NAMESIZE];
+
+ snprintf(name, sizeof(name), "rx_reset_pool_%d:%d",
+ eth_dev->data->port_id, eth_dev->device->numa_node);
+
+ adapter->reset_pool = rte_pktmbuf_pool_create(name, 2,
+ 0, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
+ eth_dev->device->numa_node);
+ if (adapter->reset_pool == NULL) {
+ RNP_PMD_ERR("mempool %s create failed", name);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int
rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
@@ -424,6 +450,9 @@ static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev)
rte_eth_dev_probing_finish(sub_eth_dev);
}
}
+ ret = rnp_rx_reset_pool_setup(adapter);
+ if (ret)
+ goto eth_alloc_error;
/* enable link update event interrupt */
rte_intr_callback_register(intr_handle,
rnp_dev_interrupt_handler, adapter);
diff --git a/drivers/net/rnp/rnp_rxtx.c b/drivers/net/rnp/rnp_rxtx.c
new file mode 100644
index 0000000..3c34f23
--- /dev/null
+++ b/drivers/net/rnp/rnp_rxtx.c
@@ -0,0 +1,476 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include <stdint.h>
+
+#include <rte_ethdev.h>
+#include <rte_memzone.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+
+#include "base/rnp_bdq_if.h"
+#include "base/rnp_dma_regs.h"
+#include "rnp_rxtx.h"
+#include "rnp_logs.h"
+#include "rnp.h"
+
+static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq);
+static void rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq);
+static void rnp_tx_queue_release(void *_txq);
+
+static __rte_always_inline phys_addr_t
+rnp_get_dma_addr(struct rnp_queue_attr *attr, struct rte_mbuf *mbuf)
+{
+ phys_addr_t dma_addr;
+
+ dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova(mbuf));
+ if (attr->sriov_st)
+ dma_addr |= (attr->sriov_st << 56);
+
+ return dma_addr;
+}
+
+static void rnp_rx_queue_release_mbuf(struct rnp_rx_queue *rxq)
+{
+ uint16_t i;
+
+ if (!rxq)
+ return;
+
+ if (rxq->sw_ring) {
+ for (i = 0; i < rxq->attr.nb_desc; i++) {
+ if (rxq->sw_ring[i].mbuf)
+ rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
+ }
+ memset(rxq->sw_ring, 0,
+ sizeof(rxq->sw_ring[0]) * rxq->attr.nb_desc);
+ }
+}
+
+static void rnp_rx_queue_release(void *_rxq)
+{
+ struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)_rxq;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rxq) {
+ rnp_rx_queue_release_mbuf(rxq);
+ if (rxq->rz)
+ rte_memzone_free(rxq->rz);
+ if (rxq->sw_ring)
+ rte_free(rxq->sw_ring);
+ rte_free(rxq);
+ }
+}
+
+static int
+rnp_tx_queue_reset(struct rnp_eth_port *port,
+ struct rnp_tx_queue *txq)
+{
+ struct rnp_hw *hw = port->hw;
+
+ rnp_reset_hw_txq_op(hw, txq);
+
+ return 0;
+}
+
+static int
+rnp_rx_queue_reset(struct rnp_eth_port *port,
+ struct rnp_rx_queue *rxq)
+{
+ struct rte_eth_dev_data *data = port->eth_dev->data;
+ struct rnp_eth_adapter *adapter = port->hw->back;
+ struct rte_eth_dev *dev = port->eth_dev;
+ struct rnp_rxq_reset_res res = {0};
+ uint16_t qidx = rxq->attr.queue_id;
+ struct rnp_tx_queue *txq = NULL;
+ struct rte_eth_txconf def_conf;
+ struct rnp_hw *hw = port->hw;
+ struct rte_mbuf *m_mbuf[2];
+ bool tx_new = false;
+ uint16_t index;
+ int err = 0;
+
+ index = rxq->attr.index;
+ /* disable eth send pkts to this ring */
+ rxq->rx_tail = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(index));
+ if (!rxq->rx_tail)
+ return 0;
+ if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
+ txq = (struct rnp_tx_queue *)data->tx_queues[qidx];
+ } else {
+ /* tx queues has been release or txq num less than rxq num */
+ def_conf.tx_deferred_start = true;
+ def_conf.tx_free_thresh = 32;
+ def_conf.tx_rs_thresh = 32;
+ if (dev->dev_ops->tx_queue_setup)
+ err = dev->dev_ops->tx_queue_setup(dev, qidx,
+ rxq->attr.nb_desc,
+ dev->data->numa_node, &def_conf);
+ if (err) {
+ RNP_PMD_ERR("rxq[%d] reset pair txq setup fail", qidx);
+ return err;
+ }
+ txq = port->tx_queues[qidx];
+ tx_new = true;
+ }
+ if (unlikely(rte_mempool_get_bulk(adapter->reset_pool, (void *)m_mbuf,
+ 2) < 0)) {
+ RNP_PMD_LOG(WARNING, "port[%d] reset rx queue[%d] failed "
+ "because mbuf alloc failed\n",
+ data->port_id, qidx);
+ return -ENOMEM;
+ }
+ rnp_rxq_flow_disable(hw, index);
+ rte_mbuf_refcnt_set(m_mbuf[0], 1);
+ rte_mbuf_refcnt_set(m_mbuf[1], 1);
+ m_mbuf[0]->data_off = RTE_PKTMBUF_HEADROOM;
+ m_mbuf[1]->data_off = RTE_PKTMBUF_HEADROOM;
+ res.eth_hdr = rte_pktmbuf_mtod(m_mbuf[0], uint8_t *);
+ res.rx_pkt_addr = rnp_get_dma_addr(&rxq->attr, m_mbuf[1]);
+ res.tx_pkt_addr = rnp_get_dma_addr(&txq->attr, m_mbuf[0]);
+ rnp_reset_hw_rxq_op(hw, rxq, txq, &res);
+ if (tx_new)
+ rnp_tx_queue_release(txq);
+ else
+ txq->tx_tail = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
+ if (!tx_new) {
+ if (txq->tx_tail) {
+ rnp_tx_queue_release_mbuf(txq);
+ rnp_tx_queue_reset(port, txq);
+ rnp_tx_queue_sw_reset(txq);
+ }
+ }
+ rte_mempool_put_bulk(adapter->reset_pool, (void **)m_mbuf, 2);
+ rnp_rxq_flow_enable(hw, index);
+ rte_io_wmb();
+ RNP_E_REG_WR(hw, RNP_RXQ_LEN(index), rxq->attr.nb_desc);
+
+ return 0;
+}
+
+static int
+rnp_alloc_rxbdr(struct rte_eth_dev *dev,
+ struct rnp_rx_queue *rxq,
+ uint16_t nb_rx_desc, int socket_id)
+{
+ const struct rte_memzone *rz = NULL;
+ uint32_t size = 0;
+
+ size = (nb_rx_desc + RNP_RX_MAX_BURST_SIZE) *
+ sizeof(struct rnp_rxsw_entry);
+ rxq->sw_ring = rte_zmalloc_socket("rx_swring", size,
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (rxq->sw_ring == NULL)
+ return -ENOMEM;
+ rz = rte_eth_dma_zone_reserve(dev, "rx_ring", rxq->attr.queue_id,
+ RNP_RX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
+ if (rz == NULL) {
+ rte_free(rxq->sw_ring);
+ rxq->sw_ring = NULL;
+ return -ENOMEM;
+ }
+ memset(rz->addr, 0, RNP_RX_MAX_RING_SZ);
+ rxq->rx_bdr = (struct rnp_rx_desc *)rz->addr;
+ rxq->ring_phys_addr = rz->iova;
+ rxq->rz = rz;
+
+ return 0;
+}
+
+static void
+rnp_rx_queue_sw_reset(struct rnp_rx_queue *rxq)
+{
+ uint32_t size = 0;
+ uint32_t idx = 0;
+
+ rxq->nb_rx_free = rxq->attr.nb_desc - 1;
+ rxq->rx_tail = 0;
+
+ size = rxq->attr.nb_desc + RNP_RX_MAX_BURST_SIZE;
+ for (idx = 0; idx < size * sizeof(struct rnp_rx_desc); idx++)
+ ((volatile char *)rxq->rx_bdr)[idx] = 0;
+}
+
+
+int rnp_rx_queue_setup(struct rte_eth_dev *eth_dev,
+ uint16_t qidx,
+ uint16_t nb_rx_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mb_pool)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
+ struct rte_eth_dev_data *data = eth_dev->data;
+ struct rnp_hw *hw = port->hw;
+ struct rnp_rx_queue *rxq = NULL;
+ uint64_t offloads;
+ int err = 0;
+
+ RNP_PMD_LOG(INFO, "RXQ[%d] setup nb-desc %d\n", qidx, nb_rx_desc);
+ offloads = rx_conf->offloads | data->dev_conf.rxmode.offloads;
+ if (rte_is_power_of_2(nb_rx_desc) == 0) {
+ RNP_PMD_ERR("Rxq Desc Num Must power of 2\n");
+ return -EINVAL;
+ }
+ if (nb_rx_desc > RNP_MAX_BD_COUNT)
+ return -EINVAL;
+ /* check whether queue has been created if so release it */
+ if (qidx < data->nb_rx_queues &&
+ data->rx_queues[qidx] != NULL) {
+ rnp_rx_queue_release(data->rx_queues[qidx]);
+ data->rx_queues[qidx] = NULL;
+ }
+ rxq = rte_zmalloc_socket("rnp_rxq", sizeof(struct rnp_rx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (rxq == NULL) {
+ RNP_PMD_ERR("Failed to allocate rx ring memory");
+ return -ENOMEM;
+ }
+ rxq->rx_offloads = offloads;
+ /* queue hw info */
+ rxq->attr.index = rnp_get_dma_ring_index(port, qidx);
+ rxq->attr.nb_desc_mask = nb_rx_desc - 1;
+ rxq->attr.nb_desc = nb_rx_desc;
+ rxq->attr.queue_id = qidx;
+ /* queue map to port hw info */
+ rxq->attr.vf_num = hw->mbx.vf_num;
+ rxq->attr.sriov_st = hw->mbx.sriov_st;
+ rxq->attr.lane_id = port->attr.nr_lane;
+ rxq->attr.port_id = data->port_id;
+#define RNP_RXQ_BD_TIMEOUT (5000000)
+ rxq->nodesc_tm_thresh = RNP_RXQ_BD_TIMEOUT;
+ rxq->rx_buf_len = (uint16_t)(rte_pktmbuf_data_room_size(mb_pool) -
+ RTE_PKTMBUF_HEADROOM);
+ rxq->mb_pool = mb_pool;
+ err = rnp_alloc_rxbdr(eth_dev, rxq, nb_rx_desc, socket_id);
+ if (err)
+ goto fail;
+ RNP_PMD_LOG(INFO, "PF[%d] dev:[%d] hw-lane[%d] rx_qid[%d] "
+ "hw_ridx %d socket %d\n",
+ hw->mbx.pf_num, rxq->attr.port_id,
+ rxq->attr.lane_id, qidx,
+ rxq->attr.index, socket_id);
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh) ?
+ rx_conf->rx_free_thresh : RNP_DEFAULT_RX_FREE_THRESH;
+ rxq->pthresh = (rx_conf->rx_thresh.pthresh) ?
+ rx_conf->rx_thresh.pthresh : RNP_RX_DESC_FETCH_TH;
+ rxq->pburst = (rx_conf->rx_thresh.hthresh) ?
+ rx_conf->rx_thresh.hthresh : RNP_RX_DESC_FETCH_BURST;
+ rnp_setup_rxbdr(hw, rxq);
+ if (rxq->rx_tail) {
+ err = rnp_rx_queue_reset(port, rxq);
+ if (err) {
+ RNP_PMD_ERR("PF[%d] dev:[%d] lane[%d] rx_qid[%d] "
+ "hw_ridx[%d] bdr setup failed",
+ hw->mbx.pf_num, rxq->attr.port_id,
+ rxq->attr.lane_id, qidx, rxq->attr.index);
+ goto rxbd_setup_failed;
+ }
+ }
+ rnp_rx_queue_sw_reset(rxq);
+ data->rx_queues[qidx] = rxq;
+
+ return 0;
+rxbd_setup_failed:
+ if (rxq->rz)
+ rte_memzone_free(rxq->rz);
+fail:
+ rte_free(rxq);
+
+ return err;
+}
+
+static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq)
+{
+ uint16_t i;
+
+ if (!txq)
+ return;
+ if (txq->sw_ring) {
+ for (i = 0; i < txq->attr.nb_desc; i++) {
+ if (txq->sw_ring[i].mbuf) {
+ rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
+ txq->sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+}
+
+static void rnp_tx_queue_release(void *_txq)
+{
+ struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (txq) {
+ rnp_tx_queue_release_mbuf(txq);
+
+ if (txq->rz)
+ rte_memzone_free(txq->rz);
+ if (txq->sw_ring)
+ rte_free(txq->sw_ring);
+ rte_free(txq);
+ }
+}
+
+void
+rnp_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
+{
+ rnp_rx_queue_release(dev->data->rx_queues[qid]);
+}
+
+void
+rnp_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
+{
+ rnp_tx_queue_release(dev->data->tx_queues[qid]);
+}
+
+static int rnp_alloc_txbdr(struct rte_eth_dev *dev,
+ struct rnp_tx_queue *txq,
+ uint16_t nb_desc, int socket_id)
+{
+ const struct rte_memzone *rz = NULL;
+ int size;
+
+ size = nb_desc * sizeof(struct rnp_txsw_entry);
+ txq->sw_ring = rte_zmalloc_socket("tx_swq", size,
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (txq->sw_ring == NULL)
+ return -ENOMEM;
+
+ rz = rte_eth_dma_zone_reserve(dev, "tx_ring", txq->attr.queue_id,
+ RNP_TX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
+ if (rz == NULL) {
+ rte_free(txq->sw_ring);
+ txq->sw_ring = NULL;
+ return -ENOMEM;
+ }
+ memset(rz->addr, 0, RNP_TX_MAX_RING_SZ);
+ txq->ring_phys_addr = rz->iova;
+ txq->tx_bdr = rz->addr;
+ txq->rz = rz;
+
+ return 0;
+}
+
+static void
+rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq)
+{
+ struct rnp_txsw_entry *sw_ring = txq->sw_ring;
+ uint32_t idx = 0, prev = 0;
+ uint32_t size = 0;
+
+ prev = (uint16_t)(txq->attr.nb_desc - 1);
+ for (idx = 0; idx < txq->attr.nb_desc; idx++) {
+ sw_ring[idx].mbuf = NULL;
+ sw_ring[idx].last_id = idx;
+ sw_ring[prev].next_id = idx;
+ prev = idx;
+ }
+ txq->nb_tx_free = txq->attr.nb_desc - 1;
+ txq->tx_next_dd = txq->tx_rs_thresh - 1;
+ txq->tx_next_rs = txq->tx_rs_thresh - 1;
+
+ size = (txq->attr.nb_desc + RNP_TX_MAX_BURST_SIZE);
+ for (idx = 0; idx < size * sizeof(struct rnp_tx_desc); idx++)
+ ((volatile char *)txq->tx_bdr)[idx] = 0;
+}
+
+int
+rnp_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t qidx, uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+ struct rte_eth_dev_data *data = dev->data;
+ struct rnp_hw *hw = port->hw;
+ struct rnp_tx_queue *txq;
+ uint64_t offloads = 0;
+ int err = 0;
+
+ PMD_INIT_FUNC_TRACE();
+ offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+ RNP_PMD_INFO("TXQ[%d] setup nb-desc %d\n", qidx, nb_desc);
+ if (rte_is_power_of_2(nb_desc) == 0) {
+ RNP_PMD_ERR("txq Desc num must power of 2\n");
+ return -EINVAL;
+ }
+ if (nb_desc > RNP_MAX_BD_COUNT)
+ return -EINVAL;
+ /* check whether queue Has been create if so release it */
+ if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
+ rnp_tx_queue_release(data->tx_queues[qidx]);
+ data->tx_queues[qidx] = NULL;
+ }
+ txq = rte_zmalloc_socket("rnp_txq", sizeof(struct rnp_tx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (!txq) {
+ RNP_PMD_ERR("Failed to allocate TX ring memory");
+ return -ENOMEM;
+ }
+ txq->tx_rs_thresh = tx_conf->tx_rs_thresh ?
+ tx_conf->tx_rs_thresh : RNP_DEFAULT_TX_RS_THRESH;
+ txq->tx_free_thresh = tx_conf->tx_free_thresh ?
+ tx_conf->tx_free_thresh : RNP_DEFAULT_TX_FREE_THRESH;
+ if (txq->tx_rs_thresh > txq->tx_free_thresh) {
+ RNP_PMD_ERR("tx_rs_thresh must be less than or "
+ "equal to tx_free_thresh. (tx_free_thresh=%u"
+ " tx_rs_thresh=%u port=%d queue=%d)",
+ (unsigned int)tx_conf->tx_free_thresh,
+ (unsigned int)tx_conf->tx_rs_thresh,
+ (int)data->port_id,
+ (int)qidx);
+ err = -EINVAL;
+ goto txbd_setup_failed;
+ }
+ if (txq->tx_rs_thresh + txq->tx_free_thresh >= nb_desc) {
+ RNP_PMD_ERR("tx_rs_thresh + tx_free_thresh >= nb_desc"
+ "%d + %d >= %d", txq->tx_rs_thresh,
+ txq->tx_free_thresh, nb_desc);
+ err = -EINVAL;
+ goto txbd_setup_failed;
+ }
+ txq->pthresh = (tx_conf->tx_thresh.pthresh) ?
+ tx_conf->tx_thresh.pthresh : RNP_TX_DESC_FETCH_TH;
+ txq->pburst = (tx_conf->tx_thresh.hthresh) ?
+ tx_conf->tx_thresh.hthresh : RNP_TX_DESC_FETCH_BURST;
+ txq->free_mbufs = rte_zmalloc_socket("txq->free_mbufs",
+ sizeof(struct rte_mbuf *) * txq->tx_rs_thresh,
+ RTE_CACHE_LINE_SIZE, socket_id);
+ txq->attr.index = rnp_get_dma_ring_index(port, qidx);
+ txq->attr.lane_id = port->attr.nr_lane;
+ txq->attr.port_id = dev->data->port_id;
+ txq->attr.nb_desc_mask = nb_desc - 1;
+ txq->attr.vf_num = hw->mbx.vf_num;
+ txq->attr.nb_desc = nb_desc;
+ txq->attr.queue_id = qidx;
+
+ err = rnp_alloc_txbdr(dev, txq, nb_desc, socket_id);
+ if (err)
+ goto txbd_setup_failed;
+ rnp_setup_txbdr(hw, txq);
+ if (txq->tx_tail)
+ rnp_reset_hw_txq_op(hw, txq);
+ rnp_tx_queue_sw_reset(txq);
+ RNP_PMD_LOG(INFO, "PF[%d] dev:[%d] hw-lane[%d] txq queue_id[%d] "
+ "dma_idx %d socket %d\n",
+ hw->mbx.pf_num, txq->attr.port_id,
+ txq->attr.lane_id, qidx,
+ txq->attr.index, socket_id);
+ if (qidx < dev->data->nb_tx_queues)
+ data->tx_queues[qidx] = txq;
+ port->tx_queues[qidx] = txq;
+
+ txq->tx_deferred_start = tx_conf->tx_deferred_start;
+ txq->tx_offloads = offloads;
+
+ return 0;
+txbd_setup_failed:
+
+ rte_free(txq);
+
+ return err;
+}
diff --git a/drivers/net/rnp/rnp_rxtx.h b/drivers/net/rnp/rnp_rxtx.h
new file mode 100644
index 0000000..3ea977c
--- /dev/null
+++ b/drivers/net/rnp/rnp_rxtx.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_RXTX_H_
+#define _RNP_RXTX_H_
+
+#include "rnp.h"
+#include "base/rnp_bdq_if.h"
+
+#define RNP_RX_MAX_BURST_SIZE (32)
+#define RNP_TX_MAX_BURST_SIZE (32)
+#define RNP_BD_RING_ALIGN (128)
+#define RNP_MAX_RING_DESC (4096)
+#define RNP_RX_MAX_RING_SZ \
+ ((RNP_MAX_RING_DESC + \
+ RNP_RX_MAX_BURST_SIZE) * \
+ sizeof(struct rnp_rx_desc))
+#define RNP_TX_MAX_RING_SZ \
+ ((RNP_MAX_RING_DESC + \
+ RNP_TX_MAX_BURST_SIZE) * \
+ sizeof(struct rnp_tx_desc))
+
+#define RNP_RX_DESC_FETCH_TH (96) /* dma fetch desC threshold */
+#define RNP_RX_DESC_FETCH_BURST (32) /* */
+#define RNP_TX_DESC_FETCH_TH (64) /* dma fetch desc threshold */
+#define RNP_TX_DESC_FETCH_BURST (32) /* max-num_descs_peer_read*/
+
+#define RNP_DEFAULT_TX_FREE_THRESH (32)
+#define RNP_DEFAULT_TX_RS_THRESH (32)
+#define RNP_DEFAULT_RX_FREE_THRESH (32)
+
+/* rx queue info */
+struct rnp_queue_attr {
+ uint64_t sriov_st; /* enable sriov info */
+ uint16_t vf_num; /* ring belong to which vf */
+
+ uint16_t queue_id; /* sw queue index*/
+ uint16_t index; /* hw ring index */
+ uint16_t lane_id; /* ring belong to which physical Lane */
+ uint16_t nb_desc; /* max bds */
+ uint16_t nb_desc_mask; /* mask of bds */
+ uint16_t port_id; /* dpdk manage port sequence id */
+};
+
+struct rnp_rxsw_entry {
+ struct rte_mbuf *mbuf;
+};
+
+struct rnp_rx_queue {
+ struct rte_mempool *mb_pool; /* mbuf pool to populate rx ring. */
+ const struct rte_memzone *rz; /* rx hw ring base alloc memzone */
+ uint64_t ring_phys_addr; /* rx hw ring physical addr */
+ volatile struct rnp_rx_desc *rx_bdr; /* rx hw ring rirtual Addr */
+ volatile struct rnp_rx_desc zero_desc;
+ struct rnp_rxsw_entry *sw_ring; /* rx software ring addr */
+ volatile void *rx_tailreg; /* hw desc tail register */
+ volatile void *rx_headreg; /* hw desc head register*/
+ struct rnp_queue_attr attr;
+
+ uint16_t rx_buf_len; /* mempool mbuf buf len */
+ uint16_t nb_rx_free; /* number available use desc */
+ uint16_t rx_free_thresh; /* rx free desc desource thresh */
+ uint16_t rx_tail;
+
+ uint32_t nodesc_tm_thresh; /* rx queue no desc timeout thresh */
+ uint8_t rx_deferred_start; /* do not start queue with dev_start(). */
+ uint8_t pthresh; /* rx desc prefetch threshold */
+ uint8_t pburst; /* rx desc prefetch burst */
+
+ uint64_t rx_offloads; /* user set hw offload features */
+ struct rte_mbuf **free_mbufs; /* rx bulk alloc reserve of free mbufs */
+};
+
+struct rnp_txsw_entry {
+ struct rte_mbuf *mbuf; /* sync with tx desc dma physical addr */
+ uint16_t next_id; /* next entry resource used */
+ uint16_t last_id; /* last entry resource used */
+};
+
+struct rnp_tx_desc;
+struct rnp_tx_queue {
+ const struct rte_memzone *rz;
+ uint64_t ring_phys_addr; /* tx dma ring physical addr */
+ volatile struct rnp_tx_desc *tx_bdr; /* tx dma ring virtual addr */
+ struct rnp_txsw_entry *sw_ring; /* tx software ring addr */
+ volatile void *tx_tailreg; /* hw desc tail register */
+ volatile void *tx_headreg; /* hw desc head register*/
+ struct rnp_queue_attr attr;
+
+ uint16_t nb_tx_free; /* avail desc to set pkts */
+ uint16_t nb_tx_used;
+ uint16_t tx_tail;
+
+ uint16_t tx_next_dd; /* next to scan writeback dd bit */
+ uint16_t tx_rs_thresh; /* number of interval set rs bit */
+ uint16_t tx_next_rs; /* index of next time to set rs bit*/
+ uint16_t tx_free_thresh; /* thresh to free tx desc resource */
+
+ uint8_t tx_deferred_start; /*< Do not start queue with dev_start(). */
+ uint8_t pthresh; /* rx desc prefetch threshold */
+ uint8_t pburst; /* rx desc burst*/
+
+ uint64_t tx_offloads; /* tx offload features */
+ struct rte_mbuf **free_mbufs; /* tx bulk free reserve of free mbufs */
+};
+
+void
+rnp_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
+void
+rnp_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
+int rnp_rx_queue_setup(struct rte_eth_dev *eth_dev,
+ uint16_t qidx,
+ uint16_t nb_rx_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mb_pool);
+int rnp_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t qidx, uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf);
+
+#endif /* _RNP_RXTX_H_ */
--
1.8.3.1
next prev parent reply other threads:[~2025-02-08 2:46 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-08 2:43 [PATCH v7 00/28] [v6]drivers/net Add Support mucse N10 Pmd Driver Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 01/28] net/rnp: add skeleton Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 02/28] net/rnp: add ethdev probe and remove Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 03/28] net/rnp: add log Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 04/28] net/rnp: support mailbox basic operate Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 05/28] net/rnp: add device init and uninit Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 06/28] net/rnp: add get device information operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 07/28] net/rnp: add support mac promisc mode Wenbo Cao
2025-02-08 2:43 ` Wenbo Cao [this message]
2025-02-08 2:43 ` [PATCH v7 09/28] net/rnp: add queue stop and start operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 10/28] net/rnp: add support device start stop operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 11/28] net/rnp: add RSS support operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 12/28] net/rnp: add support link update operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 13/28] net/rnp: add support link setup operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 14/28] net/rnp: add Rx burst simple support Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 15/28] net/rnp: add Tx " Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 16/28] net/rnp: add MTU set operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 17/28] net/rnp: add Rx scatter segment version Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 18/28] net/rnp: add Tx multiple " Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 19/28] net/rnp: add support basic stats operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 20/28] net/rnp: add support xstats operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 21/28] net/rnp: add unicast MAC filter operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 22/28] net/rnp: add supported packet types Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 23/28] net/rnp: add support Rx checksum offload Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 24/28] net/rnp: add support Tx TSO offload Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 25/28] net/rnp: support VLAN offloads Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 26/28] net/rnp: add support VLAN filters operations Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 27/28] net/rnp: add queue info operation Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 28/28] net/rnp: support Rx/Tx burst mode info Wenbo Cao
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=1738982645-34550-9-git-send-email-caowenbo@mucse.com \
--to=caowenbo@mucse.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=stephen@networkplumber.org \
--cc=thomas@monjalon.net \
--cc=yaojun@mucse.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).