diff mbox series

[7/8] net: dc2114x: allow users to decide how to tx packets according to IP core

Message ID tencent_57E89FA08481630DE0DE98E0EBC8B269B305@qq.com
State New
Delegated to: Ramon Fried
Headers show
Series [1/8] net: dc2114x: add support for platforms that don't have pci controllers | expand

Commit Message

Hanyuan Zhao Aug. 9, 2024, 8:57 a.m. UTC
Some IP cores of dc2114x or its variants do not comply so well with
the behaviors described by the official document. Originally this
driver uses only one tx descriptor and organizes it as a ring buffer,
which would lead to a problem that one packet would be sent twice.
This commit adds support to prevent this bug if you are using IP
cores with this issue, by using multiple tx descriptors and
organizing them as a real well-defined ring buffer.

Signed-off-by: Hanyuan Zhao <zhaohy22@mails.tsinghua.edu.cn>
---
 drivers/net/Kconfig   | 13 +++++++++++++
 drivers/net/dc2114x.c | 17 ++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d79d8ad9c4..89bd77da19 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -759,6 +759,19 @@  config TULIP_IGNORE_TX_NO_CARRIER
 	  of this IP core do not detect this error anymore. Say Y to this could
 	  disable handling of this error.
 
+config TULIP_MULTIPLE_TX_DESC
+	bool "Use multiple tx descriptors"
+	depends on TULIP
+	default n
+	help
+	  Some IP cores of dc2114x or its variants do not comply so well with
+	  the behaviors described by the official document. Originally this
+	  driver uses only one tx descriptor and organizes it as a ring buffer,
+	  which would lead to a problem that one packet would be sent twice.
+	  Say Y to this could prevent this bug if you are using IP cores with
+	  this issue, by using multiple tx descriptors and organizing them as
+	  a real well-defined ring buffer.
+
 config XILINX_AXIEMAC
 	select PHYLIB
 	select MII
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index dc28712221..11dea9b4d7 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -78,10 +78,15 @@ 
 #else
 #define phys_to_bus(dev, a)	dm_pci_phys_to_mem((dev), (a))
 #endif
+
+/* Number of TX descriptors   */
+#if CONFIG_IS_ENABLED(TULIP_MULTIPLE_TX_DESC)
+#define NUM_TX_DESC 4
+#else
+#define NUM_TX_DESC 1
 #endif
 
 #define NUM_RX_DESC PKTBUFSRX
-#define NUM_TX_DESC 1			/* Number of TX descriptors   */
 #define RX_BUFF_SZ  PKTSIZE_ALIGN
 
 #define TOUT_LOOP   1000000
@@ -312,7 +317,12 @@  static void send_setup_frame(struct dc2114x_priv *priv)
 
 	priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno,
 						      (phys_addr_t)&setup_frame[0]));
+#if CONFIG_IS_ENABLED(TULIP_MULTIPLE_TX_DESC)
+	priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_SET | SETUP_FRAME_LEN);
+	priv->tx_ring[priv->tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER);
+#else
 	priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN);
+#endif
 	priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN);
 
 	dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD);
@@ -356,7 +366,12 @@  static int dc21x4x_send_common(struct dc2114x_priv *priv, void *packet, int leng
 
 	priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno,
 						      (phys_addr_t)packet));
+#if CONFIG_IS_ENABLED(TULIP_MULTIPLE_TX_DESC)
+	priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_LS | TD_FS | length);
+	priv->tx_ring[priv->tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER);
+#else
 	priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+#endif
 	priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN);
 
 	dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD);