Skip to content

Commit 510a1e7

Browse files
mugunthanvnmdavem330
authored andcommitted
drivers: net: davinci_cpdma: acknowledge interrupt properly
CPDMA interrupts are not properly acknowledged which leads to interrupt storm, only cpdma interrupt 0 is acknowledged in Davinci CPDMA driver. Changed cpdma_ctlr_eoi api to acknowledge 1 and 2 interrupts which are used for rx and tx respectively. Reported-by: Pantelis Antoniou <[email protected]> Signed-off-by: Mugunthan V N <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4153577 commit 510a1e7

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

drivers/net/ethernet/ti/cpsw.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -510,19 +510,21 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
510510
int num_tx, num_rx;
511511

512512
num_tx = cpdma_chan_process(priv->txch, 128);
513-
num_rx = cpdma_chan_process(priv->rxch, budget);
514-
515-
if (num_rx || num_tx)
516-
cpsw_dbg(priv, intr, "poll %d rx, %d tx pkts\n",
517-
num_rx, num_tx);
513+
if (num_tx)
514+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
518515

516+
num_rx = cpdma_chan_process(priv->rxch, budget);
519517
if (num_rx < budget) {
520518
napi_complete(napi);
521519
cpsw_intr_enable(priv);
522-
cpdma_ctlr_eoi(priv->dma);
520+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
523521
cpsw_enable_irq(priv);
524522
}
525523

524+
if (num_rx || num_tx)
525+
cpsw_dbg(priv, intr, "poll %d rx, %d tx pkts\n",
526+
num_rx, num_tx);
527+
526528
return num_rx;
527529
}
528530

@@ -835,7 +837,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
835837
cpdma_ctlr_start(priv->dma);
836838
cpsw_intr_enable(priv);
837839
napi_enable(&priv->napi);
838-
cpdma_ctlr_eoi(priv->dma);
840+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
841+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
839842

840843
if (priv->data.dual_emac)
841844
priv->slaves[priv->emac_port].open_stat = true;
@@ -1075,7 +1078,9 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)
10751078
cpdma_chan_start(priv->txch);
10761079
cpdma_ctlr_int_ctrl(priv->dma, true);
10771080
cpsw_intr_enable(priv);
1078-
cpdma_ctlr_eoi(priv->dma);
1081+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
1082+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
1083+
10791084
}
10801085

10811086
static struct net_device_stats *cpsw_ndo_get_stats(struct net_device *ndev)
@@ -1094,7 +1099,9 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
10941099
cpsw_interrupt(ndev->irq, priv);
10951100
cpdma_ctlr_int_ctrl(priv->dma, true);
10961101
cpsw_intr_enable(priv);
1097-
cpdma_ctlr_eoi(priv->dma);
1102+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
1103+
cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
1104+
10981105
}
10991106
#endif
11001107

drivers/net/ethernet/ti/davinci_cpdma.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,9 @@ int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable)
493493
return 0;
494494
}
495495

496-
void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr)
496+
void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr, u32 value)
497497
{
498-
dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, 0);
498+
dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, value);
499499
}
500500

501501
struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,

drivers/net/ethernet/ti/davinci_cpdma.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626

2727
#define CPDMA_RX_SOURCE_PORT(__status__) ((__status__ >> 16) & 0x7)
2828

29+
#define CPDMA_EOI_RX_THRESH 0x0
30+
#define CPDMA_EOI_RX 0x1
31+
#define CPDMA_EOI_TX 0x2
32+
#define CPDMA_EOI_MISC 0x3
33+
2934
struct cpdma_params {
3035
struct device *dev;
3136
void __iomem *dmaregs;
@@ -88,7 +93,7 @@ int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
8893
int cpdma_chan_process(struct cpdma_chan *chan, int quota);
8994

9095
int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable);
91-
void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr);
96+
void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr, u32 value);
9297
int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable);
9398
bool cpdma_check_free_tx_desc(struct cpdma_chan *chan);
9499

0 commit comments

Comments
 (0)