[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