aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMugunthan V N <mugunthanvnm@ti.com>2015-01-15 04:29:28 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-15 13:57:07 -0500
commit9f6bd8fa5860fc7b041b10f2d463c78d65bdb59d (patch)
treefc9c939ed65a2f88e5a18f76166d112f457e2daf /drivers/net
parent16dde0d6ac159531a5e03cd3f8bc8a401d9f3fb6 (diff)
drivers: net: cpsw: fix cpsw hung with add vlan using vconfig
while adding vlan in dual EMAC mode, only specific ports should be subscribed for the vlan, else it will lead to switching mode and if both ports connected to same switch cpsw will hung as it creates a network loop. Fixing this by adding only specific ports in case of dual EMAC. Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/ti/cpsw.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 64d1cef4cda1..e068d48b0f21 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1634,16 +1634,24 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
1634 unsigned short vid) 1634 unsigned short vid)
1635{ 1635{
1636 int ret; 1636 int ret;
1637 int unreg_mcast_mask; 1637 int unreg_mcast_mask = 0;
1638 u32 port_mask;
1638 1639
1639 if (priv->ndev->flags & IFF_ALLMULTI) 1640 if (priv->data.dual_emac) {
1640 unreg_mcast_mask = ALE_ALL_PORTS; 1641 port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST;
1641 else 1642
1642 unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; 1643 if (priv->ndev->flags & IFF_ALLMULTI)
1644 unreg_mcast_mask = port_mask;
1645 } else {
1646 port_mask = ALE_ALL_PORTS;
1647
1648 if (priv->ndev->flags & IFF_ALLMULTI)
1649 unreg_mcast_mask = ALE_ALL_PORTS;
1650 else
1651 unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2;
1652 }
1643 1653
1644 ret = cpsw_ale_add_vlan(priv->ale, vid, 1654 ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask,
1645 ALE_ALL_PORTS << priv->host_port,
1646 0, ALE_ALL_PORTS << priv->host_port,
1647 unreg_mcast_mask << priv->host_port); 1655 unreg_mcast_mask << priv->host_port);
1648 if (ret != 0) 1656 if (ret != 0)
1649 return ret; 1657 return ret;
@@ -1654,8 +1662,7 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
1654 goto clean_vid; 1662 goto clean_vid;
1655 1663
1656 ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1664 ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
1657 ALE_ALL_PORTS << priv->host_port, 1665 port_mask, ALE_VLAN, vid, 0);
1658 ALE_VLAN, vid, 0);
1659 if (ret != 0) 1666 if (ret != 0)
1660 goto clean_vlan_ucast; 1667 goto clean_vlan_ucast;
1661 return 0; 1668 return 0;