[PATCH 7/8] net: dc2114x: allow users to decide how to tx packets according to IP core
Hanyuan Zhao
hanyuan-z at qq.com
Fri Aug 9 10:57:00 CEST 2024
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 at mails.tsinghua.edu.cn>
---
drivers/net/Kconfig | 13 +++++++++++++
drivers/net/dc2114x.c | 17 ++++++++++++++++-
2 files changed, 29 insertions(+), 1 deletion(-)
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);
--
2.39.2
More information about the U-Boot
mailing list