]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
net: dc2114x: allow users to decide how to tx packets according to IP core
authorHanyuan Zhao <hanyuan-z@qq.com>
Fri, 9 Aug 2024 08:57:00 +0000 (16:57 +0800)
committerTom Rini <trini@konsulko.com>
Sun, 27 Oct 2024 16:15:29 +0000 (10:15 -0600)
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
drivers/net/dc2114x.c

index 804f4b09a208f8818cf7aa4fa0c5e2cf0d6e1f8a..6fd037b40f728a9c8c6554b93baedea1b8349f15 100644 (file)
@@ -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
index dc2871222101fef9956888acfa9944e0681d5f96..11dea9b4d7931b933a89b8cd249689fb29b0fafa 100644 (file)
 #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);