| From 02a54164c52ed6eca3089a0d402170fbf34d6cf5 Mon Sep 17 00:00:00 2001 |
| From: Mugunthan V N <mugunthanvnm@ti.com> |
| Date: Thu, 22 Jan 2015 15:19:22 +0530 |
| Subject: drivers: net: cpsw: discard dual emac default vlan configuration |
| |
| From: Mugunthan V N <mugunthanvnm@ti.com> |
| |
| commit 02a54164c52ed6eca3089a0d402170fbf34d6cf5 upstream. |
| |
| In Dual EMAC, the default VLANs are used to segregate Rx packets between |
| the ports, so adding the same default VLAN to the switch will affect the |
| normal packet transfers. So returning error on addition of dual EMAC |
| default VLANs. |
| |
| Even if EMAC 0 default port VLAN is added to EMAC 1, it will lead to |
| break dual EMAC port separations. |
| |
| Fixes: d9ba8f9e6298 (driver: net: ethernet: cpsw: dual emac interface implementation) |
| Reported-by: Felipe Balbi <balbi@ti.com> |
| Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/ethernet/ti/cpsw.c | 22 ++++++++++++++++++++++ |
| 1 file changed, 22 insertions(+) |
| |
| --- a/drivers/net/ethernet/ti/cpsw.c |
| +++ b/drivers/net/ethernet/ti/cpsw.c |
| @@ -1676,6 +1676,19 @@ static int cpsw_ndo_vlan_rx_add_vid(stru |
| if (vid == priv->data.default_vlan) |
| return 0; |
| |
| + if (priv->data.dual_emac) { |
| + /* In dual EMAC, reserved VLAN id should not be used for |
| + * creating VLAN interfaces as this can break the dual |
| + * EMAC port separation |
| + */ |
| + int i; |
| + |
| + for (i = 0; i < priv->data.slaves; i++) { |
| + if (vid == priv->slaves[i].port_vlan) |
| + return -EINVAL; |
| + } |
| + } |
| + |
| dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); |
| return cpsw_add_vlan_ale_entry(priv, vid); |
| } |
| @@ -1689,6 +1702,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(str |
| if (vid == priv->data.default_vlan) |
| return 0; |
| |
| + if (priv->data.dual_emac) { |
| + int i; |
| + |
| + for (i = 0; i < priv->data.slaves; i++) { |
| + if (vid == priv->slaves[i].port_vlan) |
| + return -EINVAL; |
| + } |
| + } |
| + |
| dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); |
| ret = cpsw_ale_del_vlan(priv->ale, vid, 0); |
| if (ret != 0) |