From c303f4a0dd7a6fba0a3103c1f8f490929ae5b578 Mon Sep 17 00:00:00 2001 From: Hanyuan Zhao Date: Fri, 9 Aug 2024 16:57:00 +0800 Subject: [PATCH] net: dc2114x: allow users to decide how to tx packets according to IP core 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 --- 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 804f4b09a2..6fd037b40f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -781,6 +781,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.5