diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-23 12:09:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-23 12:09:27 -0400 |
commit | 1f6d80358dc9bbbeb56cb43384fa11fd645d9289 (patch) | |
tree | 152bfa5165292a8e4f06d536b6d222a68480e573 /drivers/net/ethernet/ti | |
parent | a2aeb02a8e6a9fef397c344245a54eeae67341f6 (diff) | |
parent | 98f75b8291a89ba6bf73e322ee467ce0bfeb91c1 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
arch/mips/net/bpf_jit.c
drivers/net/can/flexcan.c
Both the flexcan and MIPS bpf_jit conflicts were cases of simple
overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 5c3f1f3ad16f..45ba50e4eaec 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -701,6 +701,28 @@ static void cpsw_rx_handler(void *token, int len, int status) | |||
701 | cpsw_dual_emac_src_port_detect(status, priv, ndev, skb); | 701 | cpsw_dual_emac_src_port_detect(status, priv, ndev, skb); |
702 | 702 | ||
703 | if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { | 703 | if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { |
704 | bool ndev_status = false; | ||
705 | struct cpsw_slave *slave = priv->slaves; | ||
706 | int n; | ||
707 | |||
708 | if (priv->data.dual_emac) { | ||
709 | /* In dual emac mode check for all interfaces */ | ||
710 | for (n = priv->data.slaves; n; n--, slave++) | ||
711 | if (netif_running(slave->ndev)) | ||
712 | ndev_status = true; | ||
713 | } | ||
714 | |||
715 | if (ndev_status && (status >= 0)) { | ||
716 | /* The packet received is for the interface which | ||
717 | * is already down and the other interface is up | ||
718 | * and running, intead of freeing which results | ||
719 | * in reducing of the number of rx descriptor in | ||
720 | * DMA engine, requeue skb back to cpdma. | ||
721 | */ | ||
722 | new_skb = skb; | ||
723 | goto requeue; | ||
724 | } | ||
725 | |||
704 | /* the interface is going down, skbs are purged */ | 726 | /* the interface is going down, skbs are purged */ |
705 | dev_kfree_skb_any(skb); | 727 | dev_kfree_skb_any(skb); |
706 | return; | 728 | return; |
@@ -719,6 +741,7 @@ static void cpsw_rx_handler(void *token, int len, int status) | |||
719 | new_skb = skb; | 741 | new_skb = skb; |
720 | } | 742 | } |
721 | 743 | ||
744 | requeue: | ||
722 | ret = cpdma_chan_submit(priv->rxch, new_skb, new_skb->data, | 745 | ret = cpdma_chan_submit(priv->rxch, new_skb, new_skb->data, |
723 | skb_tailroom(new_skb), 0); | 746 | skb_tailroom(new_skb), 0); |
724 | if (WARN_ON(ret < 0)) | 747 | if (WARN_ON(ret < 0)) |
@@ -2354,10 +2377,19 @@ static int cpsw_suspend(struct device *dev) | |||
2354 | struct net_device *ndev = platform_get_drvdata(pdev); | 2377 | struct net_device *ndev = platform_get_drvdata(pdev); |
2355 | struct cpsw_priv *priv = netdev_priv(ndev); | 2378 | struct cpsw_priv *priv = netdev_priv(ndev); |
2356 | 2379 | ||
2357 | if (netif_running(ndev)) | 2380 | if (priv->data.dual_emac) { |
2358 | cpsw_ndo_stop(ndev); | 2381 | int i; |
2359 | 2382 | ||
2360 | for_each_slave(priv, soft_reset_slave); | 2383 | for (i = 0; i < priv->data.slaves; i++) { |
2384 | if (netif_running(priv->slaves[i].ndev)) | ||
2385 | cpsw_ndo_stop(priv->slaves[i].ndev); | ||
2386 | soft_reset_slave(priv->slaves + i); | ||
2387 | } | ||
2388 | } else { | ||
2389 | if (netif_running(ndev)) | ||
2390 | cpsw_ndo_stop(ndev); | ||
2391 | for_each_slave(priv, soft_reset_slave); | ||
2392 | } | ||
2361 | 2393 | ||
2362 | pm_runtime_put_sync(&pdev->dev); | 2394 | pm_runtime_put_sync(&pdev->dev); |
2363 | 2395 | ||
@@ -2371,14 +2403,24 @@ static int cpsw_resume(struct device *dev) | |||
2371 | { | 2403 | { |
2372 | struct platform_device *pdev = to_platform_device(dev); | 2404 | struct platform_device *pdev = to_platform_device(dev); |
2373 | struct net_device *ndev = platform_get_drvdata(pdev); | 2405 | struct net_device *ndev = platform_get_drvdata(pdev); |
2406 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
2374 | 2407 | ||
2375 | pm_runtime_get_sync(&pdev->dev); | 2408 | pm_runtime_get_sync(&pdev->dev); |
2376 | 2409 | ||
2377 | /* Select default pin state */ | 2410 | /* Select default pin state */ |
2378 | pinctrl_pm_select_default_state(&pdev->dev); | 2411 | pinctrl_pm_select_default_state(&pdev->dev); |
2379 | 2412 | ||
2380 | if (netif_running(ndev)) | 2413 | if (priv->data.dual_emac) { |
2381 | cpsw_ndo_open(ndev); | 2414 | int i; |
2415 | |||
2416 | for (i = 0; i < priv->data.slaves; i++) { | ||
2417 | if (netif_running(priv->slaves[i].ndev)) | ||
2418 | cpsw_ndo_open(priv->slaves[i].ndev); | ||
2419 | } | ||
2420 | } else { | ||
2421 | if (netif_running(ndev)) | ||
2422 | cpsw_ndo_open(ndev); | ||
2423 | } | ||
2382 | return 0; | 2424 | return 0; |
2383 | } | 2425 | } |
2384 | 2426 | ||