* [PATCH 01/13] net/txgbe: fix swfw mbox failure
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 02/13] net/txgbe: fix VF-PF mbox interrupt Jiawen Wu
` (12 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There is a unknown bug that the register TXGBE_MNGMBX cannot be written
in the loop, when DPDK is built with GCC high version. Access any register
before write TXGBE_MNGMBX can fix it.
Bugzilla ID: 1531
Fixes: 35c90ecccfd4 ("net/txgbe: add EEPROM functions")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_mng.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/txgbe/base/txgbe_mng.c b/drivers/net/txgbe/base/txgbe_mng.c
index 20db982891..7dc8f21183 100644
--- a/drivers/net/txgbe/base/txgbe_mng.c
+++ b/drivers/net/txgbe/base/txgbe_mng.c
@@ -58,6 +58,7 @@ txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
dword_len = length >> 2;
+ txgbe_flush(hw);
/* The device driver writes the relevant command block
* into the ram area.
*/
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 02/13] net/txgbe: fix VF-PF mbox interrupt
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
2024-10-23 6:48 ` [PATCH 01/13] net/txgbe: fix swfw mbox failure Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 03/13] net/txgbe: remove outer UDP checksum capability Jiawen Wu
` (11 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There was a incorrect bit to define TXGBE_ICRMISC_VFMBX that prevents the
interrupt from being handled correctly.
Fixes: a6712cd029a4 ("net/txgbe: add PF module init and uninit for SRIOV")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_regs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index 4ea4a2e3d8..b46d65331e 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1197,7 +1197,7 @@ enum txgbe_5tuple_protocol {
#define TXGBE_ICRMISC_ANDONE MS(19, 0x1) /* link auto-nego done */
#define TXGBE_ICRMISC_ERRIG MS(20, 0x1) /* integrity error */
#define TXGBE_ICRMISC_SPI MS(21, 0x1) /* SPI interface */
-#define TXGBE_ICRMISC_VFMBX MS(22, 0x1) /* VF-PF message box */
+#define TXGBE_ICRMISC_VFMBX MS(23, 0x1) /* VF-PF message box */
#define TXGBE_ICRMISC_GPIO MS(26, 0x1) /* GPIO interrupt */
#define TXGBE_ICRMISC_ERRPCI MS(27, 0x1) /* pcie request error */
#define TXGBE_ICRMISC_HEAT MS(28, 0x1) /* overheat detection */
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 03/13] net/txgbe: remove outer UDP checksum capability
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
2024-10-23 6:48 ` [PATCH 01/13] net/txgbe: fix swfw mbox failure Jiawen Wu
2024-10-23 6:48 ` [PATCH 02/13] net/txgbe: fix VF-PF mbox interrupt Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 04/13] net/txgbe: fix driver load bit to inform firmware Jiawen Wu
` (10 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
The hardware does not support outer UDP checksum for tunnel packets.
It's wrong to claim this Tx offload capability, so fix it.
Bugzilla ID: 1529
Fixes: b950203be7f1 ("net/txgbe: support VXLAN-GPE")
Fixes: 295968d17407 ("ethdev: add namespace")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 5bc0f8772f..c12726553c 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -2284,8 +2284,7 @@ txgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MACSEC_INSERT;
- tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
- RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
+ tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
#ifdef RTE_LIB_SECURITY
if (dev->security_ctx)
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 04/13] net/txgbe: fix driver load bit to inform firmware
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (2 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 03/13] net/txgbe: remove outer UDP checksum capability Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 05/13] net/txgbe: enable Tx descriptor error interrupt Jiawen Wu
` (9 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
Drv_load bit will be reset to default 0 after hardware LAN reset,
reconfigure it to inform firmware that driver is loaded. And set it to 0
when device is closed.
Fixes: b1f596677d8e ("net/txgbe: support device start")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 2834468764..4aa3bfd0bc 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -331,6 +331,8 @@ txgbe_pf_reset_hw(struct txgbe_hw *hw)
status = hw->mac.reset_hw(hw);
ctrl_ext = rd32(hw, TXGBE_PORTCTL);
+ /* let hardware know driver is loaded */
+ ctrl_ext |= TXGBE_PORTCTL_DRVLOAD;
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext |= TXGBE_PORTCTL_RSTDONE;
wr32(hw, TXGBE_PORTCTL, ctrl_ext);
@@ -2061,6 +2063,9 @@ txgbe_dev_close(struct rte_eth_dev *dev)
ret = txgbe_dev_stop(dev);
+ /* Let firmware take over control of hardware */
+ wr32m(hw, TXGBE_PORTCTL, TXGBE_PORTCTL_DRVLOAD, 0);
+
txgbe_dev_free_queues(dev);
txgbe_set_pcie_master(hw, false);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 05/13] net/txgbe: enable Tx descriptor error interrupt
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (3 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 04/13] net/txgbe: fix driver load bit to inform firmware Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 06/13] net/txgbe: check length of Tx packets Jiawen Wu
` (8 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Enable Tdm_desc_chk then handle the interrupt of TDM desc error. If it's a
non-fatal error, clear the error to reset the queue. If it's a fatal error,
require users to manually restart the port. This flow prevents the hardware
from PCIe pending due to Tx hang, resulting in a reboot to recover.
But remarkably, when packet layer length does not match the packet type in
TX descriptor, it will cause non-fatal error if Tdm_desc_chk is enabled.
But it can be transmitted normally if Tdm_desc_chk is disabled. So in order
to prevent hardware over check, fix the layer length on the basis of packet
type.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_regs.h | 6 ++
drivers/net/txgbe/txgbe_ethdev.c | 64 ++++++++++++++++++
drivers/net/txgbe/txgbe_ethdev.h | 3 +
drivers/net/txgbe/txgbe_rxtx.c | 100 ++++++++++++++++++++++++++++
drivers/net/txgbe/txgbe_rxtx.h | 1 +
5 files changed, 174 insertions(+)
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index b46d65331e..7a9ba6976f 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1197,6 +1197,7 @@ enum txgbe_5tuple_protocol {
#define TXGBE_ICRMISC_ANDONE MS(19, 0x1) /* link auto-nego done */
#define TXGBE_ICRMISC_ERRIG MS(20, 0x1) /* integrity error */
#define TXGBE_ICRMISC_SPI MS(21, 0x1) /* SPI interface */
+#define TXGBE_ICRMISC_TXDESC MS(22, 0x1) /* TDM desc error */
#define TXGBE_ICRMISC_VFMBX MS(23, 0x1) /* VF-PF message box */
#define TXGBE_ICRMISC_GPIO MS(26, 0x1) /* GPIO interrupt */
#define TXGBE_ICRMISC_ERRPCI MS(27, 0x1) /* pcie request error */
@@ -1382,6 +1383,11 @@ enum txgbe_5tuple_protocol {
#define TXGBE_TXCFG_WTHRESH(v) LS(v, 16, 0x7F)
#define TXGBE_TXCFG_FLUSH MS(26, 0x1)
+#define TXGBE_TDM_DESC_CHK(i) (0x0180B0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_NONFATAL(i) (0x0180C0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_FATAL(i) (0x0180D0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_MASK(v) MS(v, 0x1)
+
/* interrupt registers */
#define TXGBE_ITRI 0x000180
#define TXGBE_ITR(i) (0x000200 + 4 * (i))
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 4aa3bfd0bc..bafa9cf829 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -1936,6 +1936,7 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
+ rte_eal_alarm_cancel(txgbe_tx_queue_clear_error, dev);
txgbe_dev_wait_setup_link_complete(dev, 0);
/* disable interrupts */
@@ -2838,6 +2839,60 @@ txgbe_dev_setup_link_alarm_handler(void *param)
intr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;
}
+static void
+txgbe_do_reset(struct rte_eth_dev *dev)
+{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ txq->resetting = true;
+ }
+
+ rte_delay_ms(1);
+ wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
+ txgbe_flush(hw);
+
+ PMD_DRV_LOG(ERR, "Please manually restart the port %d",
+ dev->data->port_id);
+}
+
+static void
+txgbe_tx_ring_recovery(struct rte_eth_dev *dev)
+{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ u32 desc_error[4] = {0, 0, 0, 0};
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ /* check tdm fatal error */
+ for (i = 0; i < 4; i++) {
+ desc_error[i] = rd32(hw, TXGBE_TDM_DESC_FATAL(i));
+ if (desc_error[i] != 0) {
+ PMD_DRV_LOG(ERR, "TDM fatal error reg[%d]: 0x%x", i, desc_error[i]);
+ txgbe_do_reset(dev);
+ return;
+ }
+ }
+
+ /* check tdm non-fatal error */
+ for (i = 0; i < 4; i++)
+ desc_error[i] = rd32(hw, TXGBE_TDM_DESC_NONFATAL(i));
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ if (desc_error[i / 32] & (1 << i % 32)) {
+ PMD_DRV_LOG(ERR, "TDM non-fatal error, reset port[%d] queue[%d]",
+ dev->data->port_id, i);
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ txq = dev->data->tx_queues[i];
+ txq->resetting = true;
+ rte_eal_alarm_set(1000, txgbe_tx_queue_clear_error, (void *)dev);
+ }
+ }
+}
+
/*
* If @timeout_ms was 0, it means that it will not return until link complete.
* It returns 1 on complete, return 0 on timeout.
@@ -3096,6 +3151,7 @@ txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev)
intr->mask |= mask;
intr->mask_misc |= TXGBE_ICRMISC_GPIO;
intr->mask_misc |= TXGBE_ICRMISC_ANDONE;
+ intr->mask_misc |= TXGBE_ICRMISC_TXDESC;
return 0;
}
@@ -3191,6 +3247,9 @@ txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev,
if (eicr & TXGBE_ICRMISC_HEAT)
intr->flags |= TXGBE_FLAG_OVERHEAT;
+ if (eicr & TXGBE_ICRMISC_TXDESC)
+ intr->flags |= TXGBE_FLAG_TX_DESC_ERR;
+
((u32 *)hw->isb_mem)[TXGBE_ISB_MISC] = 0;
return 0;
@@ -3310,6 +3369,11 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev,
intr->flags &= ~TXGBE_FLAG_OVERHEAT;
}
+ if (intr->flags & TXGBE_FLAG_TX_DESC_ERR) {
+ txgbe_tx_ring_recovery(dev);
+ intr->flags &= ~TXGBE_FLAG_TX_DESC_ERR;
+ }
+
PMD_DRV_LOG(DEBUG, "enable intr immediately");
txgbe_enable_intr(dev);
rte_intr_enable(intr_handle);
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index f0f4ced5b0..302ea9f037 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -31,6 +31,7 @@
#define TXGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4)
#define TXGBE_FLAG_NEED_AN_CONFIG (uint32_t)(1 << 5)
#define TXGBE_FLAG_OVERHEAT (uint32_t)(1 << 6)
+#define TXGBE_FLAG_TX_DESC_ERR (uint32_t)(1 << 7)
/*
* Defines that were not part of txgbe_type.h as they are not used by the
@@ -474,6 +475,8 @@ int txgbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
int txgbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+void txgbe_tx_queue_clear_error(void *param);
+
void txgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index c12726553c..2d2b437643 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -728,6 +728,66 @@ txgbe_get_tun_len(struct rte_mbuf *mbuf)
return tun_len;
}
+static inline void
+txgbe_fix_offload_len(union txgbe_tx_offload *ol)
+{
+ uint8_t ptid = ol->ptid;
+
+ if (ptid & TXGBE_PTID_PKT_TUN) {
+ if (ol->outer_l2_len == 0)
+ ol->outer_l2_len = sizeof(struct rte_ether_hdr);
+ if (ol->outer_l3_len == 0) {
+ if (ptid & TXGBE_PTID_TUN_IPV6)
+ ol->outer_l3_len = sizeof(struct rte_ipv6_hdr);
+ else
+ ol->outer_l3_len = sizeof(struct rte_ipv4_hdr);
+ }
+ if ((ptid & 0xF) == 0) {
+ ol->l3_len = 0;
+ ol->l4_len = 0;
+ } else {
+ goto inner;
+ }
+ }
+
+ if ((ptid & 0xF0) == TXGBE_PTID_PKT_MAC) {
+ if (ol->l2_len == 0)
+ ol->l2_len = sizeof(struct rte_ether_hdr);
+ ol->l3_len = 0;
+ ol->l4_len = 0;
+ } else if ((ptid & 0xF0) == TXGBE_PTID_PKT_IP) {
+ if (ol->l2_len == 0)
+ ol->l2_len = sizeof(struct rte_ether_hdr);
+inner:
+ if (ol->l3_len == 0) {
+ if (ptid & TXGBE_PTID_PKT_IPV6)
+ ol->l3_len = sizeof(struct rte_ipv6_hdr);
+ else
+ ol->l3_len = sizeof(struct rte_ipv4_hdr);
+ }
+ switch (ptid & 0x7) {
+ case 0x1:
+ case 0x2:
+ ol->l4_len = 0;
+ break;
+ case 0x3:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_udp_hdr);
+ break;
+ case 0x4:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_tcp_hdr);
+ break;
+ case 0x5:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_sctp_hdr);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
static inline uint8_t
txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
{
@@ -782,6 +842,10 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint8_t use_ipsec;
#endif
+ txq = tx_queue;
+ if (txq->resetting)
+ return 0;
+
tx_offload.data[0] = 0;
tx_offload.data[1] = 0;
txq = tx_queue;
@@ -826,6 +890,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
if (tx_offload.ptid & TXGBE_PTID_PKT_TUN)
tx_offload.ptid |= txgbe_parse_tun_ptid(tx_pkt,
tx_offload.outer_tun_len);
+ txgbe_fix_offload_len(&tx_offload);
#ifdef RTE_LIB_SECURITY
if (use_ipsec) {
@@ -4570,6 +4635,11 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
wr32(hw, TXGBE_TXWP(txq->reg_idx), 0);
}
+#ifndef RTE_LIB_SECURITY
+ for (i = 0; i < 4; i++)
+ wr32(hw, TXGBE_TDM_DESC_CHK(i), 0xFFFFFFFF);
+#endif
+
/* Device configured with multiple TX queues. */
txgbe_dev_mq_tx_configure(dev);
}
@@ -4806,6 +4876,7 @@ txgbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
rte_wmb();
wr32(hw, TXGBE_TXWP(txq->reg_idx), txq->tx_tail);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+ txq->resetting = false;
return 0;
}
@@ -4863,6 +4934,35 @@ txgbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
return 0;
}
+void
+txgbe_tx_queue_clear_error(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq->resetting)
+ continue;
+
+ txgbe_dev_save_tx_queue(hw, i);
+
+ /* tx ring reset */
+ wr32(hw, TXGBE_TDM_DESC_NONFATAL(i / 32),
+ TXGBE_TDM_DESC_MASK(i % 32));
+
+ if (txq->ops != NULL) {
+ txq->ops->release_mbufs(txq);
+ txq->ops->reset(txq);
+ }
+
+ txgbe_dev_store_tx_queue(hw, i);
+ txgbe_dev_tx_queue_start(dev, i);
+ }
+}
+
void
txgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_rxq_info *qinfo)
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index 9155eb1f70..e668b60b1e 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -412,6 +412,7 @@ struct txgbe_tx_queue {
/**< indicates that IPsec TX feature is in use */
#endif
const struct rte_memzone *mz;
+ bool resetting;
};
struct txgbe_txq_ops {
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 06/13] net/txgbe: check length of Tx packets
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (4 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 05/13] net/txgbe: enable Tx descriptor error interrupt Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 07/13] net/txgbe: add Tx descriptor error statistics Jiawen Wu
` (7 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Add checking of the Tx packet length to avoid TDM fatal error as far as
possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
and drop it directly in featured Tx code path.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 33 +++++++++++++++++++++++++
drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 11 ++++++---
drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 ++++++---
3 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 2d2b437643..06acbd0881 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -160,6 +160,8 @@ tx4(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
@@ -180,6 +182,8 @@ tx1(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = cpu_to_le64(buf_dma_addr);
@@ -813,6 +817,30 @@ txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
return ptid;
}
+static inline bool
+txgbe_check_pkt_err(struct rte_mbuf *tx_pkt)
+{
+ uint32_t total_len = 0, nb_seg = 0;
+ struct rte_mbuf *mseg;
+
+ mseg = tx_pkt;
+ do {
+ if (mseg->data_len == 0)
+ return true;
+ total_len += mseg->data_len;
+ nb_seg++;
+ mseg = mseg->next;
+ } while (mseg != NULL);
+
+ if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
+ return true;
+
+ if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
+ return true;
+
+ return false;
+}
+
uint16_t
txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -864,6 +892,11 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
new_ctx = 0;
tx_pkt = *tx_pkts++;
+ if (txgbe_check_pkt_err(tx_pkt)) {
+ rte_pktmbuf_free(tx_pkt);
+ continue;
+ }
+
pkt_len = tx_pkt->pkt_len;
/*
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_neon.c b/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
index a96baf9b1d..14be7886ef 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
@@ -476,9 +476,14 @@ static inline void
vtx1(volatile struct txgbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- uint64x2_t descriptor = {
- pkt->buf_iova + pkt->data_off,
- (uint64_t)pkt->pkt_len << 45 | flags | pkt->data_len};
+ uint16_t pkt_len = pkt->data_len;
+ uint64x2_t descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
+
+ descriptor = {pkt->buf_iova + pkt->data_off,
+ (uint64_t)pkt_len << 45 | flags | pkt_len};
vst1q_u64((uint64_t *)(uintptr_t)txdp, descriptor);
}
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_sse.c b/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
index 1a3f2ce3cd..8ecce33471 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
@@ -607,9 +607,14 @@ static inline void
vtx1(volatile struct txgbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- __m128i descriptor = _mm_set_epi64x((uint64_t)pkt->pkt_len << 45 |
- flags | pkt->data_len,
- pkt->buf_iova + pkt->data_off);
+ uint16_t pkt_len = pkt->data_len;
+ __m128i descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
+
+ descriptor = _mm_set_epi64x((uint64_t)pkt_len << 45 | flags | pkt_len,
+ pkt->buf_iova + pkt->data_off);
_mm_store_si128((__m128i *)(uintptr_t)txdp, descriptor);
}
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 07/13] net/txgbe: add Tx descriptor error statistics
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (5 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 06/13] net/txgbe: check length of Tx packets Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 08/13] net/ngbe: check length of Tx packets Jiawen Wu
` (6 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Count the number of packets not sent due to Tx descriptor error.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 6 ++++++
drivers/net/txgbe/txgbe_rxtx.c | 3 +++
drivers/net/txgbe/txgbe_rxtx.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index bafa9cf829..0c76e986f4 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2344,6 +2344,7 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
struct txgbe_stat_mappings *stat_mappings =
TXGBE_DEV_STAT_MAPPINGS(dev);
+ struct txgbe_tx_queue *txq;
uint32_t i, j;
txgbe_read_stats_registers(hw, hw_stats);
@@ -2398,6 +2399,11 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
/* Tx Errors */
stats->oerrors = 0;
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ stats->oerrors += txq->desc_error;
+ }
+
return 0;
}
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 06acbd0881..fc9e7b14f5 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -894,6 +894,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_pkt = *tx_pkts++;
if (txgbe_check_pkt_err(tx_pkt)) {
rte_pktmbuf_free(tx_pkt);
+ txq->desc_error++;
continue;
}
@@ -2523,6 +2524,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
txgbe_set_tx_function(dev, txq);
txq->ops->reset(txq);
+ txq->desc_error = 0;
dev->data->tx_queues[queue_idx] = txq;
@@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
if (!txq->resetting)
continue;
+ txq->desc_error++;
txgbe_dev_save_tx_queue(hw, i);
/* tx ring reset */
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index e668b60b1e..622a0d3981 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -412,6 +412,7 @@ struct txgbe_tx_queue {
/**< indicates that IPsec TX feature is in use */
#endif
const struct rte_memzone *mz;
+ uint64_t desc_error;
bool resetting;
};
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 08/13] net/ngbe: check length of Tx packets
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (6 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 07/13] net/txgbe: add Tx descriptor error statistics Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 09/13] net/ngbe: add Tx descriptor error statistics Jiawen Wu
` (5 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Add checking of the Tx packet length to avoid TDM fatal error as far as
possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
and drop it directly in featured Tx code path. Althrough the hardware
does not support TDM desc check.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_rxtx.c | 33 +++++++++++++++++++++++++++
drivers/net/ngbe/ngbe_rxtx_vec_neon.c | 11 ++++++---
drivers/net/ngbe/ngbe_rxtx_vec_sse.c | 11 ++++++---
3 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index f3eb797d0c..25a314f10a 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -113,6 +113,8 @@ tx4(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts)
for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
@@ -133,6 +135,8 @@ tx1(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts)
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = cpu_to_le64(buf_dma_addr);
@@ -555,6 +559,30 @@ ngbe_xmit_cleanup(struct ngbe_tx_queue *txq)
return 0;
}
+static inline bool
+ngbe_check_pkt_err(struct rte_mbuf *tx_pkt)
+{
+ uint32_t total_len = 0, nb_seg = 0;
+ struct rte_mbuf *mseg;
+
+ mseg = tx_pkt;
+ do {
+ if (mseg->data_len == 0)
+ return true;
+ total_len += mseg->data_len;
+ nb_seg++;
+ mseg = mseg->next;
+ } while (mseg != NULL);
+
+ if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
+ return true;
+
+ if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
+ return true;
+
+ return false;
+}
+
uint16_t
ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -599,6 +627,11 @@ ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
new_ctx = 0;
tx_pkt = *tx_pkts++;
+ if (ngbe_check_pkt_err(tx_pkt)) {
+ rte_pktmbuf_free(tx_pkt);
+ continue;
+ }
+
pkt_len = tx_pkt->pkt_len;
/*
diff --git a/drivers/net/ngbe/ngbe_rxtx_vec_neon.c b/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
index dcf12b7070..d870191792 100644
--- a/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
+++ b/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
@@ -476,9 +476,14 @@ static inline void
vtx1(volatile struct ngbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- uint64x2_t descriptor = {
- pkt->buf_iova + pkt->data_off,
- (uint64_t)pkt->pkt_len << 45 | flags | pkt->data_len};
+ uint16_t pkt_len = pkt->data_len;
+ uint64x2_t descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
+
+ descriptor = {pkt->buf_iova + pkt->data_off,
+ (uint64_t)pkt_len << 45 | flags | pkt_len};
vst1q_u64((uint64_t *)(uintptr_t)txdp, descriptor);
}
diff --git a/drivers/net/ngbe/ngbe_rxtx_vec_sse.c b/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
index b128bd3a67..19c69cdfa6 100644
--- a/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
+++ b/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
@@ -563,9 +563,14 @@ static inline void
vtx1(volatile struct ngbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- __m128i descriptor = _mm_set_epi64x((uint64_t)pkt->pkt_len << 45 |
- flags | pkt->data_len,
- pkt->buf_iova + pkt->data_off);
+ uint16_t pkt_len = pkt->data_len;
+ __m128i descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
+
+ descriptor = _mm_set_epi64x((uint64_t)pkt_len << 45 | flags | pkt_len,
+ pkt->buf_iova + pkt->data_off);
_mm_store_si128((__m128i *)(uintptr_t)txdp, descriptor);
}
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 09/13] net/ngbe: add Tx descriptor error statistics
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (7 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 08/13] net/ngbe: check length of Tx packets Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 10/13] net/ngbe: fix driver load bit to inform firmware Jiawen Wu
` (4 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Count the number of packets not sent due to Tx descriptor error.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 6 ++++++
drivers/net/ngbe/ngbe_rxtx.c | 2 ++
drivers/net/ngbe/ngbe_rxtx.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index 6c45ffaad3..d9d2daf656 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1507,6 +1507,7 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
struct ngbe_hw_stats *hw_stats = NGBE_DEV_STATS(dev);
struct ngbe_stat_mappings *stat_mappings =
NGBE_DEV_STAT_MAPPINGS(dev);
+ struct ngbe_tx_queue *txq;
uint32_t i, j;
ngbe_read_stats_registers(hw, hw_stats);
@@ -1559,6 +1560,11 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
/* Tx Errors */
stats->oerrors = 0;
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ stats->oerrors += txq->desc_error;
+ }
+
return 0;
}
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index 25a314f10a..8d31d47de9 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -629,6 +629,7 @@ ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_pkt = *tx_pkts++;
if (ngbe_check_pkt_err(tx_pkt)) {
rte_pktmbuf_free(tx_pkt);
+ txq->desc_error++;
continue;
}
@@ -2100,6 +2101,7 @@ ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
ngbe_set_tx_function(dev, txq);
txq->ops->reset(txq);
+ txq->desc_error = 0;
dev->data->tx_queues[queue_idx] = txq;
diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h
index 7574db32d8..8534ec123a 100644
--- a/drivers/net/ngbe/ngbe_rxtx.h
+++ b/drivers/net/ngbe/ngbe_rxtx.h
@@ -375,6 +375,7 @@ struct ngbe_tx_queue {
const struct ngbe_txq_ops *ops; /**< txq ops */
const struct rte_memzone *mz;
+ uint64_t desc_error;
};
struct ngbe_txq_ops {
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 10/13] net/ngbe: fix driver load bit to inform firmware
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (8 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 09/13] net/ngbe: add Tx descriptor error statistics Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 11/13] net/ngbe: reconfigure more MAC Rx registers Jiawen Wu
` (3 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
Drv_load bit will be reset to default 0 after hardware LAN reset,
reconfigure it to inform firmware that driver is loaded. And set it to 0
when device is closed.
Fixes: 3518df5774c7 ("net/ngbe: support device start/stop")
Fixes: cc63194e89cb ("net/ngbe: support close and reset device")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index d9d2daf656..ba46dcf2a5 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -263,6 +263,8 @@ ngbe_pf_reset_hw(struct ngbe_hw *hw)
status = hw->mac.reset_hw(hw);
ctrl_ext = rd32(hw, NGBE_PORTCTL);
+ /* let hardware know driver is loaded */
+ ctrl_ext |= NGBE_PORTCTL_DRVLOAD;
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext |= NGBE_PORTCTL_RSTDONE;
wr32(hw, NGBE_PORTCTL, ctrl_ext);
@@ -1277,6 +1279,9 @@ ngbe_dev_close(struct rte_eth_dev *dev)
ngbe_dev_stop(dev);
+ /* Let firmware take over control of hardware */
+ wr32m(hw, NGBE_PORTCTL, NGBE_PORTCTL_DRVLOAD, 0);
+
ngbe_dev_free_queues(dev);
ngbe_set_pcie_master(hw, false);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 11/13] net/ngbe: reconfigure more MAC Rx registers
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (9 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 10/13] net/ngbe: fix driver load bit to inform firmware Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode Jiawen Wu
` (2 subsequent siblings)
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
When link status changes, there is a probability that no more packets
can be received on the port, due to hardware defects. These MAC Rx
registers should be reconfigured to fix this problem.
Fixes: b9246b8fa280 ("net/ngbe: support link update")
Fixes: a7c5f95ed9c2 ("net/ngbe: reconfigure MAC Rx when link update")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/base/ngbe_regs.h | 2 ++
drivers/net/ngbe/ngbe_ethdev.c | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/ngbe/base/ngbe_regs.h b/drivers/net/ngbe/base/ngbe_regs.h
index 8a6776b0e6..b1295280a7 100644
--- a/drivers/net/ngbe/base/ngbe_regs.h
+++ b/drivers/net/ngbe/base/ngbe_regs.h
@@ -712,6 +712,8 @@ enum ngbe_5tuple_protocol {
#define NGBE_MACRXFLT_CTL_PASS LS(3, 6, 0x3)
#define NGBE_MACRXFLT_RXALL MS(31, 0x1)
+#define NGBE_MAC_WDG_TIMEOUT 0x01100C
+
/******************************************************************************
* Statistic Registers
******************************************************************************/
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index ba46dcf2a5..3ea7ed43ff 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1934,6 +1934,7 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev,
bool link_up;
int err;
int wait = 1;
+ u32 reg;
memset(&link, 0, sizeof(link));
link.link_status = RTE_ETH_LINK_DOWN;
@@ -1991,8 +1992,13 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev,
wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_SPEED_MASK,
NGBE_MACTXCFG_SPEED_1G | NGBE_MACTXCFG_TE);
}
+ /* Re configure MAC RX */
+ reg = rd32(hw, NGBE_MACRXCFG);
+ wr32(hw, NGBE_MACRXCFG, reg);
wr32m(hw, NGBE_MACRXFLT, NGBE_MACRXFLT_PROMISC,
NGBE_MACRXFLT_PROMISC);
+ reg = rd32(hw, NGBE_MAC_WDG_TIMEOUT);
+ wr32(hw, NGBE_MAC_WDG_TIMEOUT, reg);
}
return rte_eth_linkstatus_set(dev, &link);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (10 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 11/13] net/ngbe: reconfigure more MAC Rx registers Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-23 6:48 ` [PATCH 13/13] net/ngbe: restrict configuration of VLAN strip offload Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
When interrupt is legacy or MSI mode, shared interrupt may cause the
interrupt cannot be re-enabled. So fix to read the shared interrupt.
Fixes: b9246b8fa280 ("net/ngbe: support link update")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index 3ea7ed43ff..e7dc1c0f94 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -2186,6 +2186,19 @@ ngbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
struct ngbe_hw *hw = ngbe_dev_hw(dev);
struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_VEC0];
+ if (!eicr) {
+ /*
+ * shared interrupt alert!
+ * make sure interrupts are enabled because the read will
+ * have disabled interrupts.
+ */
+ if (!hw->adapter_stopped)
+ ngbe_enable_intr(dev);
+ return 0;
+ }
+ ((u32 *)hw->isb_mem)[NGBE_ISB_VEC0] = 0;
+
/* read-on-clear nic registers here */
eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
PMD_DRV_LOG(DEBUG, "eicr %x", eicr);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 13/13] net/ngbe: restrict configuration of VLAN strip offload
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (11 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode Jiawen Wu
@ 2024-10-23 6:48 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
13 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-23 6:48 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There is a hardware limitation that Rx ring config register is not
writable when Rx ring is enabled, i.e. the NGBE_RXCFG_ENA bit is set.
But disabling the ring when there is traffic will cause ring get stuck.
So restrict the configuration of VLAN strip offload only if device is
started.
Fixes: 59b46438fdaa ("net/ngbe: support VLAN offload and VLAN filter")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 49 ++++++++++++++--------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index e7dc1c0f94..eef31af233 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -586,41 +586,25 @@ ngbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
}
static void
-ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
+ngbe_vlan_strip_q_set(struct rte_eth_dev *dev, uint16_t queue, int on)
{
- struct ngbe_hw *hw = ngbe_dev_hw(dev);
- struct ngbe_rx_queue *rxq;
- bool restart;
- uint32_t rxcfg, rxbal, rxbah;
-
if (on)
ngbe_vlan_hw_strip_enable(dev, queue);
else
ngbe_vlan_hw_strip_disable(dev, queue);
+}
- rxq = dev->data->rx_queues[queue];
- rxbal = rd32(hw, NGBE_RXBAL(rxq->reg_idx));
- rxbah = rd32(hw, NGBE_RXBAH(rxq->reg_idx));
- rxcfg = rd32(hw, NGBE_RXCFG(rxq->reg_idx));
- if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
- restart = (rxcfg & NGBE_RXCFG_ENA) &&
- !(rxcfg & NGBE_RXCFG_VLAN);
- rxcfg |= NGBE_RXCFG_VLAN;
- } else {
- restart = (rxcfg & NGBE_RXCFG_ENA) &&
- (rxcfg & NGBE_RXCFG_VLAN);
- rxcfg &= ~NGBE_RXCFG_VLAN;
- }
- rxcfg &= ~NGBE_RXCFG_ENA;
+static void
+ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
- if (restart) {
- /* set vlan strip for ring */
- ngbe_dev_rx_queue_stop(dev, queue);
- wr32(hw, NGBE_RXBAL(rxq->reg_idx), rxbal);
- wr32(hw, NGBE_RXBAH(rxq->reg_idx), rxbah);
- wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxcfg);
- ngbe_dev_rx_queue_start(dev, queue);
+ if (!hw->adapter_stopped) {
+ PMD_DRV_LOG(ERR, "Please stop port first");
+ return;
}
+
+ ngbe_vlan_strip_q_set(dev, queue, on);
}
static int
@@ -846,9 +830,9 @@ ngbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
rxq = dev->data->rx_queues[i];
if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
- ngbe_vlan_hw_strip_enable(dev, i);
+ ngbe_vlan_strip_q_set(dev, i, 1);
else
- ngbe_vlan_hw_strip_disable(dev, i);
+ ngbe_vlan_strip_q_set(dev, i, 0);
}
}
@@ -910,6 +894,13 @@ ngbe_vlan_offload_config(struct rte_eth_dev *dev, int mask)
static int
ngbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
+ if (!hw->adapter_stopped && (mask & RTE_ETH_VLAN_STRIP_MASK)) {
+ PMD_DRV_LOG(ERR, "Please stop port first");
+ return -EPERM;
+ }
+
ngbe_config_vlan_strip_on_all_queues(dev, mask);
ngbe_vlan_offload_config(dev, mask);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 00/13] Wangxun fixes
2024-10-23 6:48 [PATCH 00/13] Wangxun fixes Jiawen Wu
` (12 preceding siblings ...)
2024-10-23 6:48 ` [PATCH 13/13] net/ngbe: restrict configuration of VLAN strip offload Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 01/13] net/txgbe: fix swfw mbox failure Jiawen Wu
` (12 more replies)
13 siblings, 13 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Fix some bugs in txgbe/ngbe, and optimize the Tx flow.
v1 -> v2:
- Fix build errors on ARM platform.
Jiawen Wu (13):
net/txgbe: fix swfw mbox failure
net/txgbe: fix VF-PF mbox interrupt
net/txgbe: remove outer UDP checksum capability
net/txgbe: fix driver load bit to inform firmware
net/txgbe: enable Tx descriptor error interrupt
net/txgbe: check length of Tx packets
net/txgbe: add Tx descriptor error statistics
net/ngbe: check length of Tx packets
net/ngbe: add Tx descriptor error statistics
net/ngbe: fix driver load bit to inform firmware
net/ngbe: reconfigure more MAC Rx registers
net/ngbe: fix interrupt lost in legacy or MSI mode
net/ngbe: restrict configuration of VLAN strip offload
drivers/net/ngbe/base/ngbe_regs.h | 2 +
drivers/net/ngbe/ngbe_ethdev.c | 79 +++++++++-----
drivers/net/ngbe/ngbe_rxtx.c | 35 ++++++
drivers/net/ngbe/ngbe_rxtx.h | 1 +
drivers/net/ngbe/ngbe_rxtx_vec_neon.c | 10 +-
drivers/net/ngbe/ngbe_rxtx_vec_sse.c | 11 +-
drivers/net/txgbe/base/txgbe_mng.c | 1 +
drivers/net/txgbe/base/txgbe_regs.h | 8 +-
drivers/net/txgbe/txgbe_ethdev.c | 75 +++++++++++++
drivers/net/txgbe/txgbe_ethdev.h | 3 +
drivers/net/txgbe/txgbe_rxtx.c | 139 +++++++++++++++++++++++-
drivers/net/txgbe/txgbe_rxtx.h | 2 +
drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 10 +-
drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 +-
14 files changed, 343 insertions(+), 44 deletions(-)
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 01/13] net/txgbe: fix swfw mbox failure
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 02/13] net/txgbe: fix VF-PF mbox interrupt Jiawen Wu
` (11 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There is a unknown bug that the register TXGBE_MNGMBX cannot be written
in the loop, when DPDK is built with GCC high version. Access any register
before write TXGBE_MNGMBX can fix it.
Bugzilla ID: 1531
Fixes: 35c90ecccfd4 ("net/txgbe: add EEPROM functions")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_mng.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/txgbe/base/txgbe_mng.c b/drivers/net/txgbe/base/txgbe_mng.c
index 20db982891..7dc8f21183 100644
--- a/drivers/net/txgbe/base/txgbe_mng.c
+++ b/drivers/net/txgbe/base/txgbe_mng.c
@@ -58,6 +58,7 @@ txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
dword_len = length >> 2;
+ txgbe_flush(hw);
/* The device driver writes the relevant command block
* into the ram area.
*/
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 02/13] net/txgbe: fix VF-PF mbox interrupt
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 01/13] net/txgbe: fix swfw mbox failure Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 03/13] net/txgbe: remove outer UDP checksum capability Jiawen Wu
` (10 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There was a incorrect bit to define TXGBE_ICRMISC_VFMBX that prevents the
interrupt from being handled correctly.
Fixes: a6712cd029a4 ("net/txgbe: add PF module init and uninit for SRIOV")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_regs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index 4ea4a2e3d8..b46d65331e 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1197,7 +1197,7 @@ enum txgbe_5tuple_protocol {
#define TXGBE_ICRMISC_ANDONE MS(19, 0x1) /* link auto-nego done */
#define TXGBE_ICRMISC_ERRIG MS(20, 0x1) /* integrity error */
#define TXGBE_ICRMISC_SPI MS(21, 0x1) /* SPI interface */
-#define TXGBE_ICRMISC_VFMBX MS(22, 0x1) /* VF-PF message box */
+#define TXGBE_ICRMISC_VFMBX MS(23, 0x1) /* VF-PF message box */
#define TXGBE_ICRMISC_GPIO MS(26, 0x1) /* GPIO interrupt */
#define TXGBE_ICRMISC_ERRPCI MS(27, 0x1) /* pcie request error */
#define TXGBE_ICRMISC_HEAT MS(28, 0x1) /* overheat detection */
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 03/13] net/txgbe: remove outer UDP checksum capability
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 01/13] net/txgbe: fix swfw mbox failure Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 02/13] net/txgbe: fix VF-PF mbox interrupt Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 04/13] net/txgbe: fix driver load bit to inform firmware Jiawen Wu
` (9 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
The hardware does not support outer UDP checksum for tunnel packets.
It's wrong to claim this Tx offload capability, so fix it.
Bugzilla ID: 1529
Fixes: b950203be7f1 ("net/txgbe: support VXLAN-GPE")
Fixes: 295968d17407 ("ethdev: add namespace")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 5bc0f8772f..c12726553c 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -2284,8 +2284,7 @@ txgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MACSEC_INSERT;
- tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
- RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
+ tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
#ifdef RTE_LIB_SECURITY
if (dev->security_ctx)
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 04/13] net/txgbe: fix driver load bit to inform firmware
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (2 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 03/13] net/txgbe: remove outer UDP checksum capability Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 05/13] net/txgbe: enable Tx descriptor error interrupt Jiawen Wu
` (8 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
Drv_load bit will be reset to default 0 after hardware LAN reset,
reconfigure it to inform firmware that driver is loaded. And set it to 0
when device is closed.
Fixes: b1f596677d8e ("net/txgbe: support device start")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 2834468764..4aa3bfd0bc 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -331,6 +331,8 @@ txgbe_pf_reset_hw(struct txgbe_hw *hw)
status = hw->mac.reset_hw(hw);
ctrl_ext = rd32(hw, TXGBE_PORTCTL);
+ /* let hardware know driver is loaded */
+ ctrl_ext |= TXGBE_PORTCTL_DRVLOAD;
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext |= TXGBE_PORTCTL_RSTDONE;
wr32(hw, TXGBE_PORTCTL, ctrl_ext);
@@ -2061,6 +2063,9 @@ txgbe_dev_close(struct rte_eth_dev *dev)
ret = txgbe_dev_stop(dev);
+ /* Let firmware take over control of hardware */
+ wr32m(hw, TXGBE_PORTCTL, TXGBE_PORTCTL_DRVLOAD, 0);
+
txgbe_dev_free_queues(dev);
txgbe_set_pcie_master(hw, false);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 05/13] net/txgbe: enable Tx descriptor error interrupt
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (3 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 04/13] net/txgbe: fix driver load bit to inform firmware Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 06/13] net/txgbe: check length of Tx packets Jiawen Wu
` (7 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Enable Tdm_desc_chk then handle the interrupt of TDM desc error. If it's a
non-fatal error, clear the error to reset the queue. If it's a fatal error,
require users to manually restart the port. This flow prevents the hardware
from PCIe pending due to Tx hang, resulting in a reboot to recover.
But remarkably, when packet layer length does not match the packet type in
TX descriptor, it will cause non-fatal error if Tdm_desc_chk is enabled.
But it can be transmitted normally if Tdm_desc_chk is disabled. So in order
to prevent hardware over check, fix the layer length on the basis of packet
type.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_regs.h | 6 ++
drivers/net/txgbe/txgbe_ethdev.c | 64 ++++++++++++++++++
drivers/net/txgbe/txgbe_ethdev.h | 3 +
drivers/net/txgbe/txgbe_rxtx.c | 100 ++++++++++++++++++++++++++++
drivers/net/txgbe/txgbe_rxtx.h | 1 +
5 files changed, 174 insertions(+)
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index b46d65331e..7a9ba6976f 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1197,6 +1197,7 @@ enum txgbe_5tuple_protocol {
#define TXGBE_ICRMISC_ANDONE MS(19, 0x1) /* link auto-nego done */
#define TXGBE_ICRMISC_ERRIG MS(20, 0x1) /* integrity error */
#define TXGBE_ICRMISC_SPI MS(21, 0x1) /* SPI interface */
+#define TXGBE_ICRMISC_TXDESC MS(22, 0x1) /* TDM desc error */
#define TXGBE_ICRMISC_VFMBX MS(23, 0x1) /* VF-PF message box */
#define TXGBE_ICRMISC_GPIO MS(26, 0x1) /* GPIO interrupt */
#define TXGBE_ICRMISC_ERRPCI MS(27, 0x1) /* pcie request error */
@@ -1382,6 +1383,11 @@ enum txgbe_5tuple_protocol {
#define TXGBE_TXCFG_WTHRESH(v) LS(v, 16, 0x7F)
#define TXGBE_TXCFG_FLUSH MS(26, 0x1)
+#define TXGBE_TDM_DESC_CHK(i) (0x0180B0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_NONFATAL(i) (0x0180C0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_FATAL(i) (0x0180D0 + (i) * 4) /*0-3*/
+#define TXGBE_TDM_DESC_MASK(v) MS(v, 0x1)
+
/* interrupt registers */
#define TXGBE_ITRI 0x000180
#define TXGBE_ITR(i) (0x000200 + 4 * (i))
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 4aa3bfd0bc..bafa9cf829 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -1936,6 +1936,7 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
+ rte_eal_alarm_cancel(txgbe_tx_queue_clear_error, dev);
txgbe_dev_wait_setup_link_complete(dev, 0);
/* disable interrupts */
@@ -2838,6 +2839,60 @@ txgbe_dev_setup_link_alarm_handler(void *param)
intr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;
}
+static void
+txgbe_do_reset(struct rte_eth_dev *dev)
+{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ txq->resetting = true;
+ }
+
+ rte_delay_ms(1);
+ wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
+ txgbe_flush(hw);
+
+ PMD_DRV_LOG(ERR, "Please manually restart the port %d",
+ dev->data->port_id);
+}
+
+static void
+txgbe_tx_ring_recovery(struct rte_eth_dev *dev)
+{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ u32 desc_error[4] = {0, 0, 0, 0};
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ /* check tdm fatal error */
+ for (i = 0; i < 4; i++) {
+ desc_error[i] = rd32(hw, TXGBE_TDM_DESC_FATAL(i));
+ if (desc_error[i] != 0) {
+ PMD_DRV_LOG(ERR, "TDM fatal error reg[%d]: 0x%x", i, desc_error[i]);
+ txgbe_do_reset(dev);
+ return;
+ }
+ }
+
+ /* check tdm non-fatal error */
+ for (i = 0; i < 4; i++)
+ desc_error[i] = rd32(hw, TXGBE_TDM_DESC_NONFATAL(i));
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ if (desc_error[i / 32] & (1 << i % 32)) {
+ PMD_DRV_LOG(ERR, "TDM non-fatal error, reset port[%d] queue[%d]",
+ dev->data->port_id, i);
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ txq = dev->data->tx_queues[i];
+ txq->resetting = true;
+ rte_eal_alarm_set(1000, txgbe_tx_queue_clear_error, (void *)dev);
+ }
+ }
+}
+
/*
* If @timeout_ms was 0, it means that it will not return until link complete.
* It returns 1 on complete, return 0 on timeout.
@@ -3096,6 +3151,7 @@ txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev)
intr->mask |= mask;
intr->mask_misc |= TXGBE_ICRMISC_GPIO;
intr->mask_misc |= TXGBE_ICRMISC_ANDONE;
+ intr->mask_misc |= TXGBE_ICRMISC_TXDESC;
return 0;
}
@@ -3191,6 +3247,9 @@ txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev,
if (eicr & TXGBE_ICRMISC_HEAT)
intr->flags |= TXGBE_FLAG_OVERHEAT;
+ if (eicr & TXGBE_ICRMISC_TXDESC)
+ intr->flags |= TXGBE_FLAG_TX_DESC_ERR;
+
((u32 *)hw->isb_mem)[TXGBE_ISB_MISC] = 0;
return 0;
@@ -3310,6 +3369,11 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev,
intr->flags &= ~TXGBE_FLAG_OVERHEAT;
}
+ if (intr->flags & TXGBE_FLAG_TX_DESC_ERR) {
+ txgbe_tx_ring_recovery(dev);
+ intr->flags &= ~TXGBE_FLAG_TX_DESC_ERR;
+ }
+
PMD_DRV_LOG(DEBUG, "enable intr immediately");
txgbe_enable_intr(dev);
rte_intr_enable(intr_handle);
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index f0f4ced5b0..302ea9f037 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -31,6 +31,7 @@
#define TXGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4)
#define TXGBE_FLAG_NEED_AN_CONFIG (uint32_t)(1 << 5)
#define TXGBE_FLAG_OVERHEAT (uint32_t)(1 << 6)
+#define TXGBE_FLAG_TX_DESC_ERR (uint32_t)(1 << 7)
/*
* Defines that were not part of txgbe_type.h as they are not used by the
@@ -474,6 +475,8 @@ int txgbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
int txgbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+void txgbe_tx_queue_clear_error(void *param);
+
void txgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index c12726553c..2d2b437643 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -728,6 +728,66 @@ txgbe_get_tun_len(struct rte_mbuf *mbuf)
return tun_len;
}
+static inline void
+txgbe_fix_offload_len(union txgbe_tx_offload *ol)
+{
+ uint8_t ptid = ol->ptid;
+
+ if (ptid & TXGBE_PTID_PKT_TUN) {
+ if (ol->outer_l2_len == 0)
+ ol->outer_l2_len = sizeof(struct rte_ether_hdr);
+ if (ol->outer_l3_len == 0) {
+ if (ptid & TXGBE_PTID_TUN_IPV6)
+ ol->outer_l3_len = sizeof(struct rte_ipv6_hdr);
+ else
+ ol->outer_l3_len = sizeof(struct rte_ipv4_hdr);
+ }
+ if ((ptid & 0xF) == 0) {
+ ol->l3_len = 0;
+ ol->l4_len = 0;
+ } else {
+ goto inner;
+ }
+ }
+
+ if ((ptid & 0xF0) == TXGBE_PTID_PKT_MAC) {
+ if (ol->l2_len == 0)
+ ol->l2_len = sizeof(struct rte_ether_hdr);
+ ol->l3_len = 0;
+ ol->l4_len = 0;
+ } else if ((ptid & 0xF0) == TXGBE_PTID_PKT_IP) {
+ if (ol->l2_len == 0)
+ ol->l2_len = sizeof(struct rte_ether_hdr);
+inner:
+ if (ol->l3_len == 0) {
+ if (ptid & TXGBE_PTID_PKT_IPV6)
+ ol->l3_len = sizeof(struct rte_ipv6_hdr);
+ else
+ ol->l3_len = sizeof(struct rte_ipv4_hdr);
+ }
+ switch (ptid & 0x7) {
+ case 0x1:
+ case 0x2:
+ ol->l4_len = 0;
+ break;
+ case 0x3:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_udp_hdr);
+ break;
+ case 0x4:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_tcp_hdr);
+ break;
+ case 0x5:
+ if (ol->l4_len == 0)
+ ol->l4_len = sizeof(struct rte_sctp_hdr);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
static inline uint8_t
txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
{
@@ -782,6 +842,10 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint8_t use_ipsec;
#endif
+ txq = tx_queue;
+ if (txq->resetting)
+ return 0;
+
tx_offload.data[0] = 0;
tx_offload.data[1] = 0;
txq = tx_queue;
@@ -826,6 +890,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
if (tx_offload.ptid & TXGBE_PTID_PKT_TUN)
tx_offload.ptid |= txgbe_parse_tun_ptid(tx_pkt,
tx_offload.outer_tun_len);
+ txgbe_fix_offload_len(&tx_offload);
#ifdef RTE_LIB_SECURITY
if (use_ipsec) {
@@ -4570,6 +4635,11 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
wr32(hw, TXGBE_TXWP(txq->reg_idx), 0);
}
+#ifndef RTE_LIB_SECURITY
+ for (i = 0; i < 4; i++)
+ wr32(hw, TXGBE_TDM_DESC_CHK(i), 0xFFFFFFFF);
+#endif
+
/* Device configured with multiple TX queues. */
txgbe_dev_mq_tx_configure(dev);
}
@@ -4806,6 +4876,7 @@ txgbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
rte_wmb();
wr32(hw, TXGBE_TXWP(txq->reg_idx), txq->tx_tail);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+ txq->resetting = false;
return 0;
}
@@ -4863,6 +4934,35 @@ txgbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
return 0;
}
+void
+txgbe_tx_queue_clear_error(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ struct txgbe_tx_queue *txq;
+ u32 i;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq->resetting)
+ continue;
+
+ txgbe_dev_save_tx_queue(hw, i);
+
+ /* tx ring reset */
+ wr32(hw, TXGBE_TDM_DESC_NONFATAL(i / 32),
+ TXGBE_TDM_DESC_MASK(i % 32));
+
+ if (txq->ops != NULL) {
+ txq->ops->release_mbufs(txq);
+ txq->ops->reset(txq);
+ }
+
+ txgbe_dev_store_tx_queue(hw, i);
+ txgbe_dev_tx_queue_start(dev, i);
+ }
+}
+
void
txgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_rxq_info *qinfo)
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index 9155eb1f70..e668b60b1e 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -412,6 +412,7 @@ struct txgbe_tx_queue {
/**< indicates that IPsec TX feature is in use */
#endif
const struct rte_memzone *mz;
+ bool resetting;
};
struct txgbe_txq_ops {
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 06/13] net/txgbe: check length of Tx packets
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (4 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 05/13] net/txgbe: enable Tx descriptor error interrupt Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-11-01 1:22 ` Ferruh Yigit
2024-10-28 2:31 ` [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics Jiawen Wu
` (6 subsequent siblings)
12 siblings, 1 reply; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Add checking of the Tx packet length to avoid TDM fatal error as far as
possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
and drop it directly in featured Tx code path.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 33 +++++++++++++++++++++++++
drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 10 +++++---
drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 ++++++---
3 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 2d2b437643..06acbd0881 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -160,6 +160,8 @@ tx4(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
@@ -180,6 +182,8 @@ tx1(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = cpu_to_le64(buf_dma_addr);
@@ -813,6 +817,30 @@ txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
return ptid;
}
+static inline bool
+txgbe_check_pkt_err(struct rte_mbuf *tx_pkt)
+{
+ uint32_t total_len = 0, nb_seg = 0;
+ struct rte_mbuf *mseg;
+
+ mseg = tx_pkt;
+ do {
+ if (mseg->data_len == 0)
+ return true;
+ total_len += mseg->data_len;
+ nb_seg++;
+ mseg = mseg->next;
+ } while (mseg != NULL);
+
+ if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
+ return true;
+
+ if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
+ return true;
+
+ return false;
+}
+
uint16_t
txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -864,6 +892,11 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
new_ctx = 0;
tx_pkt = *tx_pkts++;
+ if (txgbe_check_pkt_err(tx_pkt)) {
+ rte_pktmbuf_free(tx_pkt);
+ continue;
+ }
+
pkt_len = tx_pkt->pkt_len;
/*
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_neon.c b/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
index a96baf9b1d..d4d647fab5 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_neon.c
@@ -476,9 +476,13 @@ static inline void
vtx1(volatile struct txgbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- uint64x2_t descriptor = {
- pkt->buf_iova + pkt->data_off,
- (uint64_t)pkt->pkt_len << 45 | flags | pkt->data_len};
+ uint16_t pkt_len = pkt->data_len;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
+
+ uint64x2_t descriptor = {pkt->buf_iova + pkt->data_off,
+ (uint64_t)pkt_len << 45 | flags | pkt_len};
vst1q_u64((uint64_t *)(uintptr_t)txdp, descriptor);
}
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_sse.c b/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
index 1a3f2ce3cd..8ecce33471 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_sse.c
@@ -607,9 +607,14 @@ static inline void
vtx1(volatile struct txgbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- __m128i descriptor = _mm_set_epi64x((uint64_t)pkt->pkt_len << 45 |
- flags | pkt->data_len,
- pkt->buf_iova + pkt->data_off);
+ uint16_t pkt_len = pkt->data_len;
+ __m128i descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = TXGBE_FRAME_SIZE_DFT;
+
+ descriptor = _mm_set_epi64x((uint64_t)pkt_len << 45 | flags | pkt_len,
+ pkt->buf_iova + pkt->data_off);
_mm_store_si128((__m128i *)(uintptr_t)txdp, descriptor);
}
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/13] net/txgbe: check length of Tx packets
2024-10-28 2:31 ` [PATCH v2 06/13] net/txgbe: check length of Tx packets Jiawen Wu
@ 2024-11-01 1:22 ` Ferruh Yigit
2024-11-01 1:52 ` Jiawen Wu
2024-11-01 2:56 ` Stephen Hemminger
0 siblings, 2 replies; 36+ messages in thread
From: Ferruh Yigit @ 2024-11-01 1:22 UTC (permalink / raw)
To: Jiawen Wu, dev
On 10/28/2024 2:31 AM, Jiawen Wu wrote:
> Add checking of the Tx packet length to avoid TDM fatal error as far as
> possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
> and drop it directly in featured Tx code path.
>
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> ---
> drivers/net/txgbe/txgbe_rxtx.c | 33 +++++++++++++++++++++++++
> drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 10 +++++---
> drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 ++++++---
> 3 files changed, 48 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
> index 2d2b437643..06acbd0881 100644
> --- a/drivers/net/txgbe/txgbe_rxtx.c
> +++ b/drivers/net/txgbe/txgbe_rxtx.c
> @@ -160,6 +160,8 @@ tx4(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
> for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
> buf_dma_addr = rte_mbuf_data_iova(*pkts);
> pkt_len = (*pkts)->data_len;
> + if (pkt_len < RTE_ETHER_HDR_LEN)
> + pkt_len = TXGBE_FRAME_SIZE_DFT;
>
> /* write data to descriptor */
> txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
> @@ -180,6 +182,8 @@ tx1(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
>
> buf_dma_addr = rte_mbuf_data_iova(*pkts);
> pkt_len = (*pkts)->data_len;
> + if (pkt_len < RTE_ETHER_HDR_LEN)
> + pkt_len = TXGBE_FRAME_SIZE_DFT;
>
> /* write data to descriptor */
> txdp->qw0 = cpu_to_le64(buf_dma_addr);
> @@ -813,6 +817,30 @@ txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
> return ptid;
> }
>
> +static inline bool
> +txgbe_check_pkt_err(struct rte_mbuf *tx_pkt)
> +{
> + uint32_t total_len = 0, nb_seg = 0;
> + struct rte_mbuf *mseg;
> +
> + mseg = tx_pkt;
> + do {
> + if (mseg->data_len == 0)
> + return true;
> + total_len += mseg->data_len;
> + nb_seg++;
> + mseg = mseg->next;
> + } while (mseg != NULL);
> +
> + if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
> + return true;
> +
> + if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
> + return true;
> +
> + return false;
> +}
> +
>
Hi Jiawen,
Above are generic checks, we may add this function to ethdev driver
header (ethdev_driver.h) so that any PMD can use it, what do you think?
^ permalink raw reply [flat|nested] 36+ messages in thread
* RE: [PATCH v2 06/13] net/txgbe: check length of Tx packets
2024-11-01 1:22 ` Ferruh Yigit
@ 2024-11-01 1:52 ` Jiawen Wu
2024-11-01 2:49 ` Ferruh Yigit
2024-11-01 2:56 ` Stephen Hemminger
1 sibling, 1 reply; 36+ messages in thread
From: Jiawen Wu @ 2024-11-01 1:52 UTC (permalink / raw)
To: 'Ferruh Yigit', dev
On Fri, Nov 1, 2024 9:23 AM, Ferruh Yigit wrote:
> On 10/28/2024 2:31 AM, Jiawen Wu wrote:
> > Add checking of the Tx packet length to avoid TDM fatal error as far as
> > possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
> > and drop it directly in featured Tx code path.
> >
> > Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> > ---
> > drivers/net/txgbe/txgbe_rxtx.c | 33 +++++++++++++++++++++++++
> > drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 10 +++++---
> > drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 ++++++---
> > 3 files changed, 48 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
> > index 2d2b437643..06acbd0881 100644
> > --- a/drivers/net/txgbe/txgbe_rxtx.c
> > +++ b/drivers/net/txgbe/txgbe_rxtx.c
> > @@ -160,6 +160,8 @@ tx4(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
> > for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
> > buf_dma_addr = rte_mbuf_data_iova(*pkts);
> > pkt_len = (*pkts)->data_len;
> > + if (pkt_len < RTE_ETHER_HDR_LEN)
> > + pkt_len = TXGBE_FRAME_SIZE_DFT;
> >
> > /* write data to descriptor */
> > txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
> > @@ -180,6 +182,8 @@ tx1(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
> >
> > buf_dma_addr = rte_mbuf_data_iova(*pkts);
> > pkt_len = (*pkts)->data_len;
> > + if (pkt_len < RTE_ETHER_HDR_LEN)
> > + pkt_len = TXGBE_FRAME_SIZE_DFT;
> >
> > /* write data to descriptor */
> > txdp->qw0 = cpu_to_le64(buf_dma_addr);
> > @@ -813,6 +817,30 @@ txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
> > return ptid;
> > }
> >
> > +static inline bool
> > +txgbe_check_pkt_err(struct rte_mbuf *tx_pkt)
> > +{
> > + uint32_t total_len = 0, nb_seg = 0;
> > + struct rte_mbuf *mseg;
> > +
> > + mseg = tx_pkt;
> > + do {
> > + if (mseg->data_len == 0)
> > + return true;
> > + total_len += mseg->data_len;
> > + nb_seg++;
> > + mseg = mseg->next;
> > + } while (mseg != NULL);
> > +
> > + if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
> > + return true;
> > +
> > + if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
> > + return true;
> > +
> > + return false;
> > +}
> > +
> >
>
> Hi Jiawen,
>
> Above are generic checks, we may add this function to ethdev driver
> header (ethdev_driver.h) so that any PMD can use it, what do you think?
In fact, the limitation of tx_pkt->nb_segs is already implemented in
.tx_pkt_prepare. But users developing their own apps don't necessarily call
this function. So I'd like to add these in txgbe_xmit_pkts(). What are you
going to do about it?
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/13] net/txgbe: check length of Tx packets
2024-11-01 1:52 ` Jiawen Wu
@ 2024-11-01 2:49 ` Ferruh Yigit
0 siblings, 0 replies; 36+ messages in thread
From: Ferruh Yigit @ 2024-11-01 2:49 UTC (permalink / raw)
To: Jiawen Wu, dev
On 11/1/2024 1:52 AM, Jiawen Wu wrote:
> On Fri, Nov 1, 2024 9:23 AM, Ferruh Yigit wrote:
>> On 10/28/2024 2:31 AM, Jiawen Wu wrote:
>>> Add checking of the Tx packet length to avoid TDM fatal error as far as
>>> possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
>>> and drop it directly in featured Tx code path.
>>>
>>> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
>>> ---
>>> drivers/net/txgbe/txgbe_rxtx.c | 33 +++++++++++++++++++++++++
>>> drivers/net/txgbe/txgbe_rxtx_vec_neon.c | 10 +++++---
>>> drivers/net/txgbe/txgbe_rxtx_vec_sse.c | 11 ++++++---
>>> 3 files changed, 48 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
>>> index 2d2b437643..06acbd0881 100644
>>> --- a/drivers/net/txgbe/txgbe_rxtx.c
>>> +++ b/drivers/net/txgbe/txgbe_rxtx.c
>>> @@ -160,6 +160,8 @@ tx4(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
>>> for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
>>> buf_dma_addr = rte_mbuf_data_iova(*pkts);
>>> pkt_len = (*pkts)->data_len;
>>> + if (pkt_len < RTE_ETHER_HDR_LEN)
>>> + pkt_len = TXGBE_FRAME_SIZE_DFT;
>>>
>>> /* write data to descriptor */
>>> txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
>>> @@ -180,6 +182,8 @@ tx1(volatile struct txgbe_tx_desc *txdp, struct rte_mbuf **pkts)
>>>
>>> buf_dma_addr = rte_mbuf_data_iova(*pkts);
>>> pkt_len = (*pkts)->data_len;
>>> + if (pkt_len < RTE_ETHER_HDR_LEN)
>>> + pkt_len = TXGBE_FRAME_SIZE_DFT;
>>>
>>> /* write data to descriptor */
>>> txdp->qw0 = cpu_to_le64(buf_dma_addr);
>>> @@ -813,6 +817,30 @@ txgbe_parse_tun_ptid(struct rte_mbuf *tx_pkt, uint8_t tun_len)
>>> return ptid;
>>> }
>>>
>>> +static inline bool
>>> +txgbe_check_pkt_err(struct rte_mbuf *tx_pkt)
>>> +{
>>> + uint32_t total_len = 0, nb_seg = 0;
>>> + struct rte_mbuf *mseg;
>>> +
>>> + mseg = tx_pkt;
>>> + do {
>>> + if (mseg->data_len == 0)
>>> + return true;
>>> + total_len += mseg->data_len;
>>> + nb_seg++;
>>> + mseg = mseg->next;
>>> + } while (mseg != NULL);
>>> +
>>> + if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
>>> + return true;
>>> +
>>> + if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
>>> + return true;
>>> +
>>> + return false;
>>> +}
>>> +
>>>
>>
>> Hi Jiawen,
>>
>> Above are generic checks, we may add this function to ethdev driver
>> header (ethdev_driver.h) so that any PMD can use it, what do you think?
>
> In fact, the limitation of tx_pkt->nb_segs is already implemented in
> .tx_pkt_prepare. But users developing their own apps don't necessarily call
> this function. So I'd like to add these in txgbe_xmit_pkts(). What are you
> going to do about it?
>
>
I had the same thought, that is why I am not suggesting to add these
checks to .tx_pkt_prepare() function.
But still these generic checks can go into a new static inline function
for drivers to use, not for end users, and any other driver can call
this function. Your two drivers already using the same function.
This is not hard requirement, but if there is a common code for multiple
drivers, that can go into a helper function in ethdev_driver.h
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 06/13] net/txgbe: check length of Tx packets
2024-11-01 1:22 ` Ferruh Yigit
2024-11-01 1:52 ` Jiawen Wu
@ 2024-11-01 2:56 ` Stephen Hemminger
1 sibling, 0 replies; 36+ messages in thread
From: Stephen Hemminger @ 2024-11-01 2:56 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Jiawen Wu, dev
On Fri, 1 Nov 2024 01:22:47 +0000
Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> Hi Jiawen,
>
> Above are generic checks, we may add this function to ethdev driver
> header (ethdev_driver.h) so that any PMD can use it, what do you think?
This is in the fastpath, and additional checks should not be added there.
Or at least put them under RTE_ETHDEV_DEBUG.
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (5 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 06/13] net/txgbe: check length of Tx packets Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-11-01 1:33 ` Ferruh Yigit
2024-10-28 2:31 ` [PATCH v2 08/13] net/ngbe: check length of Tx packets Jiawen Wu
` (5 subsequent siblings)
12 siblings, 1 reply; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Count the number of packets not sent due to Tx descriptor error.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 6 ++++++
drivers/net/txgbe/txgbe_rxtx.c | 3 +++
drivers/net/txgbe/txgbe_rxtx.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index bafa9cf829..0c76e986f4 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2344,6 +2344,7 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
struct txgbe_stat_mappings *stat_mappings =
TXGBE_DEV_STAT_MAPPINGS(dev);
+ struct txgbe_tx_queue *txq;
uint32_t i, j;
txgbe_read_stats_registers(hw, hw_stats);
@@ -2398,6 +2399,11 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
/* Tx Errors */
stats->oerrors = 0;
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ stats->oerrors += txq->desc_error;
+ }
+
return 0;
}
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 06acbd0881..fc9e7b14f5 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -894,6 +894,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_pkt = *tx_pkts++;
if (txgbe_check_pkt_err(tx_pkt)) {
rte_pktmbuf_free(tx_pkt);
+ txq->desc_error++;
continue;
}
@@ -2523,6 +2524,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
txgbe_set_tx_function(dev, txq);
txq->ops->reset(txq);
+ txq->desc_error = 0;
dev->data->tx_queues[queue_idx] = txq;
@@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
if (!txq->resetting)
continue;
+ txq->desc_error++;
txgbe_dev_save_tx_queue(hw, i);
/* tx ring reset */
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index e668b60b1e..622a0d3981 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -412,6 +412,7 @@ struct txgbe_tx_queue {
/**< indicates that IPsec TX feature is in use */
#endif
const struct rte_memzone *mz;
+ uint64_t desc_error;
bool resetting;
};
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
2024-10-28 2:31 ` [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics Jiawen Wu
@ 2024-11-01 1:33 ` Ferruh Yigit
2024-11-01 2:06 ` Jiawen Wu
0 siblings, 1 reply; 36+ messages in thread
From: Ferruh Yigit @ 2024-11-01 1:33 UTC (permalink / raw)
To: Jiawen Wu, dev
On 10/28/2024 2:31 AM, Jiawen Wu wrote:
> Count the number of packets not sent due to Tx descriptor error.
>
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> ---
> drivers/net/txgbe/txgbe_ethdev.c | 6 ++++++
> drivers/net/txgbe/txgbe_rxtx.c | 3 +++
> drivers/net/txgbe/txgbe_rxtx.h | 1 +
> 3 files changed, 10 insertions(+)
>
> diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
> index bafa9cf829..0c76e986f4 100644
> --- a/drivers/net/txgbe/txgbe_ethdev.c
> +++ b/drivers/net/txgbe/txgbe_ethdev.c
> @@ -2344,6 +2344,7 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
> struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
> struct txgbe_stat_mappings *stat_mappings =
> TXGBE_DEV_STAT_MAPPINGS(dev);
> + struct txgbe_tx_queue *txq;
> uint32_t i, j;
>
> txgbe_read_stats_registers(hw, hw_stats);
> @@ -2398,6 +2399,11 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
>
> /* Tx Errors */
> stats->oerrors = 0;
> + for (i = 0; i < dev->data->nb_tx_queues; i++) {
> + txq = dev->data->tx_queues[i];
> + stats->oerrors += txq->desc_error;
> + }
> +
stats_get is implemented, but stats_reset also needs to be implemented
for this stat.
> return 0;
> }
>
> diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
> index 06acbd0881..fc9e7b14f5 100644
> --- a/drivers/net/txgbe/txgbe_rxtx.c
> +++ b/drivers/net/txgbe/txgbe_rxtx.c
> @@ -894,6 +894,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> tx_pkt = *tx_pkts++;
> if (txgbe_check_pkt_err(tx_pkt)) {
> rte_pktmbuf_free(tx_pkt);
> + txq->desc_error++;
> continue;
> }
>
> @@ -2523,6 +2524,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
> txgbe_set_tx_function(dev, txq);
>
> txq->ops->reset(txq);
> + txq->desc_error = 0;
>
> dev->data->tx_queues[queue_idx] = txq;
>
> @@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
> if (!txq->resetting)
> continue;
>
> + txq->desc_error++;
>
Why error value is increased in this function, which resets the Tx queue?
Is the intention to reset the error value here?
> txgbe_dev_save_tx_queue(hw, i);
>
> /* tx ring reset */
> diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
> index e668b60b1e..622a0d3981 100644
> --- a/drivers/net/txgbe/txgbe_rxtx.h
> +++ b/drivers/net/txgbe/txgbe_rxtx.h
> @@ -412,6 +412,7 @@ struct txgbe_tx_queue {
> /**< indicates that IPsec TX feature is in use */
> #endif
> const struct rte_memzone *mz;
> + uint64_t desc_error;
> bool resetting;
> };
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* RE: [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
2024-11-01 1:33 ` Ferruh Yigit
@ 2024-11-01 2:06 ` Jiawen Wu
2024-11-01 2:45 ` Ferruh Yigit
0 siblings, 1 reply; 36+ messages in thread
From: Jiawen Wu @ 2024-11-01 2:06 UTC (permalink / raw)
To: 'Ferruh Yigit', dev
> > @@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
> > if (!txq->resetting)
> > continue;
> >
> > + txq->desc_error++;
> >
>
> Why error value is increased in this function, which resets the Tx queue?
> Is the intention to reset the error value here?
When there is a desc error to cause Tx ring hang, the interrupt directs to
reset of the queue. So we increase the error count in the specific queue
reset function. The queue is reset, but the error that led to the resetting
is recorded. The error count is only reset at the setup function.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
2024-11-01 2:06 ` Jiawen Wu
@ 2024-11-01 2:45 ` Ferruh Yigit
2024-11-01 3:05 ` Jiawen Wu
0 siblings, 1 reply; 36+ messages in thread
From: Ferruh Yigit @ 2024-11-01 2:45 UTC (permalink / raw)
To: Jiawen Wu, dev
On 11/1/2024 2:06 AM, Jiawen Wu wrote:
>>> @@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
>>> if (!txq->resetting)
>>> continue;
>>>
>>> + txq->desc_error++;
>>>
>>
>> Why error value is increased in this function, which resets the Tx queue?
>> Is the intention to reset the error value here?
>
> When there is a desc error to cause Tx ring hang, the interrupt directs to
> reset of the queue. So we increase the error count in the specific queue
> reset function. The queue is reset, but the error that led to the resetting
> is recorded. The error count is only reset at the setup function.
>
Got it. But this variable counts number of bad packets. Increasing it
when Tx ring hang too may be confusing as there are two different
reasons to increase the counter.
Btw, .stats_reset() needs to reset this error stat.
^ permalink raw reply [flat|nested] 36+ messages in thread
* RE: [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
2024-11-01 2:45 ` Ferruh Yigit
@ 2024-11-01 3:05 ` Jiawen Wu
0 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-11-01 3:05 UTC (permalink / raw)
To: 'Ferruh Yigit', dev
> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Friday, November 1, 2024 10:46 AM
> To: Jiawen Wu <jiawenwu@trustnetic.com>; dev@dpdk.org
> Subject: Re: [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics
>
> On 11/1/2024 2:06 AM, Jiawen Wu wrote:
> >>> @@ -4980,6 +4982,7 @@ txgbe_tx_queue_clear_error(void *param)
> >>> if (!txq->resetting)
> >>> continue;
> >>>
> >>> + txq->desc_error++;
> >>>
> >>
> >> Why error value is increased in this function, which resets the Tx queue?
> >> Is the intention to reset the error value here?
> >
> > When there is a desc error to cause Tx ring hang, the interrupt directs to
> > reset of the queue. So we increase the error count in the specific queue
> > reset function. The queue is reset, but the error that led to the resetting
> > is recorded. The error count is only reset at the setup function.
> >
>
> Got it. But this variable counts number of bad packets. Increasing it
> when Tx ring hang too may be confusing as there are two different
> reasons to increase the counter.
I think I should add a comment here:
/* Increase the count of Tx desc error since it causes the queue reset. */
> Btw, .stats_reset() needs to reset this error stat.
I'll add it into .stats_reset() in patch set v3.
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 08/13] net/ngbe: check length of Tx packets
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (6 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 07/13] net/txgbe: add Tx descriptor error statistics Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 09/13] net/ngbe: add Tx descriptor error statistics Jiawen Wu
` (4 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Add checking of the Tx packet length to avoid TDM fatal error as far as
possible. Set the pkt_len=1518 for invalid packet in simple Tx code path,
and drop it directly in featured Tx code path. Althrough the hardware
does not support TDM desc check.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_rxtx.c | 33 +++++++++++++++++++++++++++
drivers/net/ngbe/ngbe_rxtx_vec_neon.c | 10 +++++---
drivers/net/ngbe/ngbe_rxtx_vec_sse.c | 11 ++++++---
3 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index f3eb797d0c..25a314f10a 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -113,6 +113,8 @@ tx4(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts)
for (i = 0; i < 4; ++i, ++txdp, ++pkts) {
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = rte_cpu_to_le_64(buf_dma_addr);
@@ -133,6 +135,8 @@ tx1(volatile struct ngbe_tx_desc *txdp, struct rte_mbuf **pkts)
buf_dma_addr = rte_mbuf_data_iova(*pkts);
pkt_len = (*pkts)->data_len;
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
/* write data to descriptor */
txdp->qw0 = cpu_to_le64(buf_dma_addr);
@@ -555,6 +559,30 @@ ngbe_xmit_cleanup(struct ngbe_tx_queue *txq)
return 0;
}
+static inline bool
+ngbe_check_pkt_err(struct rte_mbuf *tx_pkt)
+{
+ uint32_t total_len = 0, nb_seg = 0;
+ struct rte_mbuf *mseg;
+
+ mseg = tx_pkt;
+ do {
+ if (mseg->data_len == 0)
+ return true;
+ total_len += mseg->data_len;
+ nb_seg++;
+ mseg = mseg->next;
+ } while (mseg != NULL);
+
+ if (tx_pkt->pkt_len != total_len || tx_pkt->pkt_len == 0)
+ return true;
+
+ if (tx_pkt->nb_segs != nb_seg || tx_pkt->nb_segs > 64)
+ return true;
+
+ return false;
+}
+
uint16_t
ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -599,6 +627,11 @@ ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
new_ctx = 0;
tx_pkt = *tx_pkts++;
+ if (ngbe_check_pkt_err(tx_pkt)) {
+ rte_pktmbuf_free(tx_pkt);
+ continue;
+ }
+
pkt_len = tx_pkt->pkt_len;
/*
diff --git a/drivers/net/ngbe/ngbe_rxtx_vec_neon.c b/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
index dcf12b7070..37075ea5e7 100644
--- a/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
+++ b/drivers/net/ngbe/ngbe_rxtx_vec_neon.c
@@ -476,9 +476,13 @@ static inline void
vtx1(volatile struct ngbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- uint64x2_t descriptor = {
- pkt->buf_iova + pkt->data_off,
- (uint64_t)pkt->pkt_len << 45 | flags | pkt->data_len};
+ uint16_t pkt_len = pkt->data_len;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
+
+ uint64x2_t descriptor = {pkt->buf_iova + pkt->data_off,
+ (uint64_t)pkt_len << 45 | flags | pkt_len};
vst1q_u64((uint64_t *)(uintptr_t)txdp, descriptor);
}
diff --git a/drivers/net/ngbe/ngbe_rxtx_vec_sse.c b/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
index b128bd3a67..19c69cdfa6 100644
--- a/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
+++ b/drivers/net/ngbe/ngbe_rxtx_vec_sse.c
@@ -563,9 +563,14 @@ static inline void
vtx1(volatile struct ngbe_tx_desc *txdp,
struct rte_mbuf *pkt, uint64_t flags)
{
- __m128i descriptor = _mm_set_epi64x((uint64_t)pkt->pkt_len << 45 |
- flags | pkt->data_len,
- pkt->buf_iova + pkt->data_off);
+ uint16_t pkt_len = pkt->data_len;
+ __m128i descriptor;
+
+ if (pkt_len < RTE_ETHER_HDR_LEN)
+ pkt_len = NGBE_FRAME_SIZE_DFT;
+
+ descriptor = _mm_set_epi64x((uint64_t)pkt_len << 45 | flags | pkt_len,
+ pkt->buf_iova + pkt->data_off);
_mm_store_si128((__m128i *)(uintptr_t)txdp, descriptor);
}
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 09/13] net/ngbe: add Tx descriptor error statistics
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (7 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 08/13] net/ngbe: check length of Tx packets Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 10/13] net/ngbe: fix driver load bit to inform firmware Jiawen Wu
` (3 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu
Count the number of packets not sent due to Tx descriptor error.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 6 ++++++
drivers/net/ngbe/ngbe_rxtx.c | 2 ++
drivers/net/ngbe/ngbe_rxtx.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index 6c45ffaad3..d9d2daf656 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1507,6 +1507,7 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
struct ngbe_hw_stats *hw_stats = NGBE_DEV_STATS(dev);
struct ngbe_stat_mappings *stat_mappings =
NGBE_DEV_STAT_MAPPINGS(dev);
+ struct ngbe_tx_queue *txq;
uint32_t i, j;
ngbe_read_stats_registers(hw, hw_stats);
@@ -1559,6 +1560,11 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
/* Tx Errors */
stats->oerrors = 0;
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ stats->oerrors += txq->desc_error;
+ }
+
return 0;
}
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index 25a314f10a..8d31d47de9 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -629,6 +629,7 @@ ngbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_pkt = *tx_pkts++;
if (ngbe_check_pkt_err(tx_pkt)) {
rte_pktmbuf_free(tx_pkt);
+ txq->desc_error++;
continue;
}
@@ -2100,6 +2101,7 @@ ngbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
ngbe_set_tx_function(dev, txq);
txq->ops->reset(txq);
+ txq->desc_error = 0;
dev->data->tx_queues[queue_idx] = txq;
diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h
index 7574db32d8..8534ec123a 100644
--- a/drivers/net/ngbe/ngbe_rxtx.h
+++ b/drivers/net/ngbe/ngbe_rxtx.h
@@ -375,6 +375,7 @@ struct ngbe_tx_queue {
const struct ngbe_txq_ops *ops; /**< txq ops */
const struct rte_memzone *mz;
+ uint64_t desc_error;
};
struct ngbe_txq_ops {
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 10/13] net/ngbe: fix driver load bit to inform firmware
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (8 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 09/13] net/ngbe: add Tx descriptor error statistics Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 11/13] net/ngbe: reconfigure more MAC Rx registers Jiawen Wu
` (2 subsequent siblings)
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
Drv_load bit will be reset to default 0 after hardware LAN reset,
reconfigure it to inform firmware that driver is loaded. And set it to 0
when device is closed.
Fixes: 3518df5774c7 ("net/ngbe: support device start/stop")
Fixes: cc63194e89cb ("net/ngbe: support close and reset device")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index d9d2daf656..ba46dcf2a5 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -263,6 +263,8 @@ ngbe_pf_reset_hw(struct ngbe_hw *hw)
status = hw->mac.reset_hw(hw);
ctrl_ext = rd32(hw, NGBE_PORTCTL);
+ /* let hardware know driver is loaded */
+ ctrl_ext |= NGBE_PORTCTL_DRVLOAD;
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext |= NGBE_PORTCTL_RSTDONE;
wr32(hw, NGBE_PORTCTL, ctrl_ext);
@@ -1277,6 +1279,9 @@ ngbe_dev_close(struct rte_eth_dev *dev)
ngbe_dev_stop(dev);
+ /* Let firmware take over control of hardware */
+ wr32m(hw, NGBE_PORTCTL, NGBE_PORTCTL_DRVLOAD, 0);
+
ngbe_dev_free_queues(dev);
ngbe_set_pcie_master(hw, false);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 11/13] net/ngbe: reconfigure more MAC Rx registers
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (9 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 10/13] net/ngbe: fix driver load bit to inform firmware Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 13/13] net/ngbe: restrict configuration of VLAN strip offload Jiawen Wu
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
When link status changes, there is a probability that no more packets
can be received on the port, due to hardware defects. These MAC Rx
registers should be reconfigured to fix this problem.
Fixes: b9246b8fa280 ("net/ngbe: support link update")
Fixes: a7c5f95ed9c2 ("net/ngbe: reconfigure MAC Rx when link update")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/base/ngbe_regs.h | 2 ++
drivers/net/ngbe/ngbe_ethdev.c | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/ngbe/base/ngbe_regs.h b/drivers/net/ngbe/base/ngbe_regs.h
index 8a6776b0e6..b1295280a7 100644
--- a/drivers/net/ngbe/base/ngbe_regs.h
+++ b/drivers/net/ngbe/base/ngbe_regs.h
@@ -712,6 +712,8 @@ enum ngbe_5tuple_protocol {
#define NGBE_MACRXFLT_CTL_PASS LS(3, 6, 0x3)
#define NGBE_MACRXFLT_RXALL MS(31, 0x1)
+#define NGBE_MAC_WDG_TIMEOUT 0x01100C
+
/******************************************************************************
* Statistic Registers
******************************************************************************/
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index ba46dcf2a5..3ea7ed43ff 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1934,6 +1934,7 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev,
bool link_up;
int err;
int wait = 1;
+ u32 reg;
memset(&link, 0, sizeof(link));
link.link_status = RTE_ETH_LINK_DOWN;
@@ -1991,8 +1992,13 @@ ngbe_dev_link_update_share(struct rte_eth_dev *dev,
wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_SPEED_MASK,
NGBE_MACTXCFG_SPEED_1G | NGBE_MACTXCFG_TE);
}
+ /* Re configure MAC RX */
+ reg = rd32(hw, NGBE_MACRXCFG);
+ wr32(hw, NGBE_MACRXCFG, reg);
wr32m(hw, NGBE_MACRXFLT, NGBE_MACRXFLT_PROMISC,
NGBE_MACRXFLT_PROMISC);
+ reg = rd32(hw, NGBE_MAC_WDG_TIMEOUT);
+ wr32(hw, NGBE_MAC_WDG_TIMEOUT, reg);
}
return rte_eth_linkstatus_set(dev, &link);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (10 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 11/13] net/ngbe: reconfigure more MAC Rx registers Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
2024-10-28 2:31 ` [PATCH v2 13/13] net/ngbe: restrict configuration of VLAN strip offload Jiawen Wu
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
When interrupt is legacy or MSI mode, shared interrupt may cause the
interrupt cannot be re-enabled. So fix to read the shared interrupt.
Fixes: b9246b8fa280 ("net/ngbe: support link update")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index 3ea7ed43ff..e7dc1c0f94 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -2186,6 +2186,19 @@ ngbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
struct ngbe_hw *hw = ngbe_dev_hw(dev);
struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_VEC0];
+ if (!eicr) {
+ /*
+ * shared interrupt alert!
+ * make sure interrupts are enabled because the read will
+ * have disabled interrupts.
+ */
+ if (!hw->adapter_stopped)
+ ngbe_enable_intr(dev);
+ return 0;
+ }
+ ((u32 *)hw->isb_mem)[NGBE_ISB_VEC0] = 0;
+
/* read-on-clear nic registers here */
eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
PMD_DRV_LOG(DEBUG, "eicr %x", eicr);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 13/13] net/ngbe: restrict configuration of VLAN strip offload
2024-10-28 2:31 ` [PATCH v2 00/13] Wangxun fixes Jiawen Wu
` (11 preceding siblings ...)
2024-10-28 2:31 ` [PATCH v2 12/13] net/ngbe: fix interrupt lost in legacy or MSI mode Jiawen Wu
@ 2024-10-28 2:31 ` Jiawen Wu
12 siblings, 0 replies; 36+ messages in thread
From: Jiawen Wu @ 2024-10-28 2:31 UTC (permalink / raw)
To: dev; +Cc: Jiawen Wu, stable
There is a hardware limitation that Rx ring config register is not
writable when Rx ring is enabled, i.e. the NGBE_RXCFG_ENA bit is set.
But disabling the ring when there is traffic will cause ring get stuck.
So restrict the configuration of VLAN strip offload only if device is
started.
Fixes: 59b46438fdaa ("net/ngbe: support VLAN offload and VLAN filter")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev.c | 49 ++++++++++++++--------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index e7dc1c0f94..eef31af233 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -586,41 +586,25 @@ ngbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
}
static void
-ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
+ngbe_vlan_strip_q_set(struct rte_eth_dev *dev, uint16_t queue, int on)
{
- struct ngbe_hw *hw = ngbe_dev_hw(dev);
- struct ngbe_rx_queue *rxq;
- bool restart;
- uint32_t rxcfg, rxbal, rxbah;
-
if (on)
ngbe_vlan_hw_strip_enable(dev, queue);
else
ngbe_vlan_hw_strip_disable(dev, queue);
+}
- rxq = dev->data->rx_queues[queue];
- rxbal = rd32(hw, NGBE_RXBAL(rxq->reg_idx));
- rxbah = rd32(hw, NGBE_RXBAH(rxq->reg_idx));
- rxcfg = rd32(hw, NGBE_RXCFG(rxq->reg_idx));
- if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
- restart = (rxcfg & NGBE_RXCFG_ENA) &&
- !(rxcfg & NGBE_RXCFG_VLAN);
- rxcfg |= NGBE_RXCFG_VLAN;
- } else {
- restart = (rxcfg & NGBE_RXCFG_ENA) &&
- (rxcfg & NGBE_RXCFG_VLAN);
- rxcfg &= ~NGBE_RXCFG_VLAN;
- }
- rxcfg &= ~NGBE_RXCFG_ENA;
+static void
+ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
- if (restart) {
- /* set vlan strip for ring */
- ngbe_dev_rx_queue_stop(dev, queue);
- wr32(hw, NGBE_RXBAL(rxq->reg_idx), rxbal);
- wr32(hw, NGBE_RXBAH(rxq->reg_idx), rxbah);
- wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxcfg);
- ngbe_dev_rx_queue_start(dev, queue);
+ if (!hw->adapter_stopped) {
+ PMD_DRV_LOG(ERR, "Please stop port first");
+ return;
}
+
+ ngbe_vlan_strip_q_set(dev, queue, on);
}
static int
@@ -846,9 +830,9 @@ ngbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
rxq = dev->data->rx_queues[i];
if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
- ngbe_vlan_hw_strip_enable(dev, i);
+ ngbe_vlan_strip_q_set(dev, i, 1);
else
- ngbe_vlan_hw_strip_disable(dev, i);
+ ngbe_vlan_strip_q_set(dev, i, 0);
}
}
@@ -910,6 +894,13 @@ ngbe_vlan_offload_config(struct rte_eth_dev *dev, int mask)
static int
ngbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
+ if (!hw->adapter_stopped && (mask & RTE_ETH_VLAN_STRIP_MASK)) {
+ PMD_DRV_LOG(ERR, "Please stop port first");
+ return -EPERM;
+ }
+
ngbe_config_vlan_strip_on_all_queues(dev, mask);
ngbe_vlan_offload_config(dev, mask);
--
2.27.0
^ permalink raw reply [flat|nested] 36+ messages in thread