From 16e5c57da61cda26998bee91a327960ebd1562f6 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Thu, 10 Apr 2014 14:23:23 +0530 Subject: drivers: net: cpsw: discard all packets received when interface is down When the Ethernet interface is brought down during high Ethernet traffic, then cpsw creates the following warn dump. When cpdma has already processed the packet then the status will be greater than 0, so the cpsw_rx_handler considers that the interface is up and try to resubmit one more rx buffer to cpdma which fails as the DMA is in teardown process. This can be avoided by checking the interface state and then process the received packet, if the interface is down just discard and free the skb and return. [ 2823.104591] WARNING: CPU: 0 PID: 1823 at drivers/net/ethernet/ti/cpsw.c:711 cpsw_rx_handler+0x148/0x164() [ 2823.114654] Modules linked in: [ 2823.117872] CPU: 0 PID: 1823 Comm: ifconfig Tainted: G W 3.14.0-11992-gf34c4a3 #11 [ 2823.126860] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 2823.135030] [] (show_stack) from [] (dump_stack+0x80/0x9c) [ 2823.142619] [] (dump_stack) from [] (warn_slowpath_common+0x6c/0x90) [ 2823.151141] [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [ 2823.160336] [] (warn_slowpath_null) from [] (cpsw_rx_handler+0x148/0x164) [ 2823.169314] [] (cpsw_rx_handler) from [] (__cpdma_chan_free+0x90/0xa8) [ 2823.178028] [] (__cpdma_chan_free) from [] (__cpdma_chan_process+0xf4/0x134) [ 2823.187279] [] (__cpdma_chan_process) from [] (cpdma_chan_stop+0xb4/0x17c) [ 2823.196349] [] (cpdma_chan_stop) from [] (cpdma_ctlr_stop+0x44/0x9c) [ 2823.204872] [] (cpdma_ctlr_stop) from [] (cpsw_ndo_stop+0x154/0x188) [ 2823.213321] [] (cpsw_ndo_stop) from [] (__dev_close_many+0x84/0xc8) [ 2823.221761] [] (__dev_close_many) from [] (__dev_close+0x28/0x3c) [ 2823.230012] [] (__dev_close) from [] (__dev_change_flags+0x88/0x160) [ 2823.238483] [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [ 2823.247316] [] (dev_change_flags) from [] (devinet_ioctl+0x61c/0x6e0) [ 2823.255884] [] (devinet_ioctl) from [] (sock_ioctl+0x68/0x2a4) [ 2823.263789] [] (sock_ioctl) from [] (do_vfs_ioctl+0x78/0x61c) [ 2823.271629] [] (do_vfs_ioctl) from [] (SyS_ioctl+0x64/0x74) [ 2823.279284] [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x48) Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 6133e4af9975..4e3d197ce55a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -687,7 +687,7 @@ static void cpsw_rx_handler(void *token, int len, int status) cpsw_dual_emac_src_port_detect(status, priv, ndev, skb); - if (unlikely(status < 0)) { + if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { /* the interface is going down, skbs are purged */ dev_kfree_skb_any(skb); return; -- cgit v1.2.3 From f63a975e8f07a75dbf0386402788330d0bebd8d8 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Thu, 10 Apr 2014 14:23:24 +0530 Subject: drivers: net: cpsw: enable interrupts after napi enable and clearing previous interrupts When the Ethernet interface is put down and up with heavy Ethernet traffic, then there is prossibility of an interrupt waiting in irq controller to be processed, so when the interface is brought up again just after enable interrupt, it goes to ISR due to the previous unhandled interrutp and in ISR napi is not scheduled as the napi is not enabled in ndo_open which results in disabled interrupt for CPSW and no packets are received in cpsw. So this patch moves enabling of interupts after napi_enable and clearing CPDMA interrupts. Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 4e3d197ce55a..36aa109416c4 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1252,6 +1252,12 @@ static int cpsw_ndo_open(struct net_device *ndev) cpsw_set_coalesce(ndev, &coal); } + napi_enable(&priv->napi); + cpdma_ctlr_start(priv->dma); + cpsw_intr_enable(priv); + cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); + cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); + prim_cpsw = cpsw_get_slave_priv(priv, 0); if (prim_cpsw->irq_enabled == false) { if ((priv == prim_cpsw) || !netif_running(prim_cpsw->ndev)) { @@ -1260,12 +1266,6 @@ static int cpsw_ndo_open(struct net_device *ndev) } } - napi_enable(&priv->napi); - cpdma_ctlr_start(priv->dma); - cpsw_intr_enable(priv); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); - if (priv->data.dual_emac) priv->slaves[priv->emac_port].open_stat = true; return 0; -- cgit v1.2.3