[LEDE-DEV] Transmit timeouts with mtk_eth_soc and MT7621

Mingyu Li igvtee at gmail.com
Sun Jul 23 07:50:07 PDT 2017


Hi.
i write a path. could you help to verify it?


--- a/mtk_eth_soc.c     2017-07-22 08:13:52.845251484 +0800
+++ b/mtk_eth_soc.c     2017-07-23 22:38:37.746471417 +0800
@@ -810,6 +810,8 @@
        u8 *data, *new_data;
        struct fe_rx_dma *rxd, trxd;
        int done = 0, pad;
+       u32 hwidx;
+       int cnt;

        if (netdev->features & NETIF_F_RXCSUM)
                checksum_bit = soc->checksum_bit;
@@ -821,6 +823,12 @@
        else
                pad = NET_IP_ALIGN;

+       /* when rx count more the budget size not clear interrupt */
+       hwidx = fe_reg_r32(FE_REG_RX_DRX_IDX0);
+       cnt = ((hwidx - idx) & (ring->rx_ring_size - 1)) - 1;
+       if (cnt < budget)
+               fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
+
        while (done < budget) {
                unsigned int pktlen;
                dma_addr_t dma_addr;
@@ -890,14 +898,10 @@
                done++;
        }

-       if (done < budget)
-               fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
-
        return done;
 }

-static int fe_poll_tx(struct fe_priv *priv, int budget, u32 tx_intr,
-                     int *tx_again)
+static int fe_poll_tx(struct fe_priv *priv)
 {
        struct net_device *netdev = priv->netdev;
        struct device *dev = &netdev->dev;
@@ -911,7 +915,7 @@
        idx = ring->tx_free_idx;
        hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);

-       while ((idx != hwidx) && budget) {
+       while (idx != hwidx) {
                tx_buf = &ring->tx_buf[idx];
                skb = tx_buf->skb;

@@ -921,24 +925,12 @@
                if (skb != (struct sk_buff *)DMA_DUMMY_DESC) {
                        bytes_compl += skb->len;
                        done++;
-                       budget--;
                }
                fe_txd_unmap(dev, tx_buf);
                idx = NEXT_TX_DESP_IDX(idx);
        }
        ring->tx_free_idx = idx;

-       if (idx == hwidx) {
-               /* read hw index again make sure no new tx packet */
-               hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);
-               if (idx == hwidx)
-                       fe_reg_w32(tx_intr, FE_REG_FE_INT_STATUS);
-               else
-                       *tx_again = 1;
-       } else {
-               *tx_again = 1;
-       }
-
        if (done) {
                netdev_completed_queue(netdev, done, bytes_compl);
                smp_mb();
@@ -954,7 +946,7 @@
 {
        struct fe_priv *priv = container_of(napi, struct fe_priv, rx_napi);
        struct fe_hw_stats *hwstat = priv->hw_stats;
-       int tx_done, rx_done, tx_again;
+       int tx_done, rx_done;
        u32 status, fe_status, status_reg, mask;
        u32 tx_intr, rx_intr, status_intr;

@@ -965,7 +957,6 @@
        status_intr = priv->soc->status_int;
        tx_done = 0;
        rx_done = 0;
-       tx_again = 0;

        if (fe_reg_table[FE_REG_FE_INT_STATUS2]) {
                fe_status = fe_reg_r32(FE_REG_FE_INT_STATUS2);
@@ -974,8 +965,11 @@
                status_reg = FE_REG_FE_INT_STATUS;
        }

-       if (status & tx_intr)
-               tx_done = fe_poll_tx(priv, budget, tx_intr, &tx_again);
+       if (status & tx_intr) {
+               fe_reg_w32(tx_intr, FE_REG_FE_INT_STATUS);
+               tx_done = fe_poll_tx(priv);
+               status = fe_reg_r32(FE_REG_FE_INT_STATUS);
+       }

        if (status & rx_intr)
                rx_done = fe_poll_rx(napi, budget, priv, rx_intr);
@@ -995,7 +989,7 @@
                            tx_done, rx_done, status, mask);
        }

-       if (!tx_again && (rx_done < budget)) {
+       if (rx_done < budget) {
                status = fe_reg_r32(FE_REG_FE_INT_STATUS);
                if (status & (tx_intr | rx_intr)) {
                        /* let napi poll again */



More information about the Lede-dev mailing list