Skip to content

Commit 5ec52d5

Browse files
committed
net: macb: restart tx after tx used bit read
On some platforms (currently detected only on sama5d4) TX might stuck even the pachets are still present in DMA memories and TX start was issued for them. This happens due to race condition between MACB driver updating next TX buffer descriptor to be used and IP reading the same descriptor. In such a case, the "TX USED BIT READ" interrupt is asserted. GEM GXL/MACB user guide specifies that if a "TX USED BIT READ" interrupt is asserted TX must be restarted. Restart TX if used bit is read and packets are present in software TX queue. Packets are removed from software TX queue if TX was successful for them (see macb_tx_interrupt()). Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
1 parent 986475a commit 5ec52d5

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
#define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \
6363
| MACB_BIT(ISR_RLE) \
6464
| MACB_BIT(TXERR))
65-
#define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP))
65+
#define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP) \
66+
| MACB_BIT(TXUBR))
6667

6768
/* Max length of transmit frame must be a multiple of 8 bytes */
6869
#define MACB_TX_LEN_ALIGN 8
@@ -1307,6 +1308,21 @@ static void macb_hresp_error_task(unsigned long data)
13071308
netif_tx_start_all_queues(dev);
13081309
}
13091310

1311+
inline static void macb_tx_restart(struct macb_queue *queue)
1312+
{
1313+
unsigned int head = queue->tx_head;
1314+
unsigned int tail = queue->tx_tail;
1315+
struct macb *bp = queue->bp;
1316+
1317+
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
1318+
queue_writel(queue, ISR, MACB_BIT(TXUBR));
1319+
1320+
if (head == tail)
1321+
return;
1322+
1323+
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
1324+
}
1325+
13101326
static irqreturn_t macb_interrupt(int irq, void *dev_id)
13111327
{
13121328
struct macb_queue *queue = dev_id;
@@ -1364,6 +1380,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
13641380
if (status & MACB_BIT(TCOMP))
13651381
macb_tx_interrupt(queue);
13661382

1383+
if (status & MACB_BIT(TXUBR))
1384+
macb_tx_restart(queue);
1385+
13671386
/* Link change detection isn't possible with RMII, so we'll
13681387
* add that if/when we get our hands on a full-blown MII PHY.
13691388
*/

0 commit comments

Comments
 (0)