aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMugunthan V N2014-09-02 08:04:20 -0500
committerSekhar Nori2014-09-02 08:05:35 -0500
commitfd012d03d17b38c5350ff814583b2f2f0fc0723f (patch)
treec477bcd5c426555a379b0fd248ef8aba28f43422
parentbbb401c6e8d9a92a86ba9d1bc6bebcec423ecfda (diff)
downloadkernel-video-fd012d03d17b38c5350ff814583b2f2f0fc0723f.tar.gz
kernel-video-fd012d03d17b38c5350ff814583b2f2f0fc0723f.tar.xz
kernel-video-fd012d03d17b38c5350ff814583b2f2f0fc0723f.zip
drivers: net: cpsw: switch-config: unknown vlan handling
Currently only known VLANs are handled inside the switch, when an unknown VLAN is received the switch will drop the packets. This ioctl allows user to subscribe the ports for unknown VLAN ids, then switch will start forwarding unknown VLAN packets as configured by the user. Additional features of the unknown vlan handling of the switch other than port forwarding are untag on egress, registered and unregistered multicast of the unknown VLAN ids Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--drivers/net/ethernet/ti/cpsw.c26
-rw-r--r--include/uapi/linux/net_switch_config.h5
2 files changed, 29 insertions, 2 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 9c193bfd035..d8ff8237af3 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1602,7 +1602,7 @@ static int cpsw_switch_config_ioctl(struct net_device *ndev,
1602{ 1602{
1603 struct cpsw_priv *priv = netdev_priv(ndev); 1603 struct cpsw_priv *priv = netdev_priv(ndev);
1604 struct net_switch_config config; 1604 struct net_switch_config config;
1605 int ret = -EFAULT; 1605 int ret = 0;
1606 1606
1607 if (priv->data.dual_emac) { 1607 if (priv->data.dual_emac) {
1608 dev_err(priv->dev, "CPSW not in switch mode\n"); 1608 dev_err(priv->dev, "CPSW not in switch mode\n");
@@ -1615,7 +1615,7 @@ static int cpsw_switch_config_ioctl(struct net_device *ndev,
1615 */ 1615 */
1616 1616
1617 if (copy_from_user(&config, (ifrq->ifr_data), sizeof(config))) 1617 if (copy_from_user(&config, (ifrq->ifr_data), sizeof(config)))
1618 return ret; 1618 return -EFAULT;
1619 1619
1620 if (config.vid > 4095) { 1620 if (config.vid > 4095) {
1621 dev_err(priv->dev, "Invalid VLAN Arguments for cmd %d\n", 1621 dev_err(priv->dev, "Invalid VLAN Arguments for cmd %d\n",
@@ -1699,6 +1699,28 @@ static int cpsw_switch_config_ioctl(struct net_device *ndev,
1699 ret = copy_to_user(ifrq->ifr_data, &config, sizeof(config)); 1699 ret = copy_to_user(ifrq->ifr_data, &config, sizeof(config));
1700 break; 1700 break;
1701 } 1701 }
1702 case CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO:
1703 if ((config.unknown_vlan_member <= 7) &&
1704 (config.unknown_vlan_untag <= 7) &&
1705 (config.unknown_vlan_unreg_multi <= 7) &&
1706 (config.unknown_vlan_reg_multi <= 7)) {
1707 cpsw_ale_control_set(priv->ale, 0,
1708 ALE_PORT_UNTAGGED_EGRESS,
1709 config.unknown_vlan_untag);
1710 cpsw_ale_control_set(priv->ale, 0,
1711 ALE_PORT_UNKNOWN_REG_MCAST_FLOOD,
1712 config.unknown_vlan_reg_multi);
1713 cpsw_ale_control_set(priv->ale, 0,
1714 ALE_PORT_UNKNOWN_MCAST_FLOOD,
1715 config.unknown_vlan_unreg_multi);
1716 cpsw_ale_control_set(priv->ale, 0,
1717 ALE_PORT_UNKNOWN_VLAN_MEMBER,
1718 config.unknown_vlan_member);
1719 } else {
1720 dev_err(priv->dev, "Invalid Arguments\n");
1721 ret = -EINVAL;
1722 }
1723 break;
1702 1724
1703 default: 1725 default:
1704 ret = -EOPNOTSUPP; 1726 ret = -EOPNOTSUPP;
diff --git a/include/uapi/linux/net_switch_config.h b/include/uapi/linux/net_switch_config.h
index f3c0b118f9d..afc64d9ceb5 100644
--- a/include/uapi/linux/net_switch_config.h
+++ b/include/uapi/linux/net_switch_config.h
@@ -28,6 +28,7 @@ enum {
28 CONFIG_SWITCH_DEL_VLAN, 28 CONFIG_SWITCH_DEL_VLAN,
29 CONFIG_SWITCH_SET_PORT_CONFIG, 29 CONFIG_SWITCH_SET_PORT_CONFIG,
30 CONFIG_SWITCH_GET_PORT_CONFIG, 30 CONFIG_SWITCH_GET_PORT_CONFIG,
31 CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO,
31}; 32};
32 33
33struct net_switch_config { 34struct net_switch_config {
@@ -40,6 +41,10 @@ struct net_switch_config {
40 unsigned char untag_port; /* Untag ports */ 41 unsigned char untag_port; /* Untag ports */
41 unsigned char addr[6]; 42 unsigned char addr[6];
42 unsigned int super; 43 unsigned int super;
44 unsigned char unknown_vlan_member;
45 unsigned char unknown_vlan_untag;
46 unsigned int unknown_vlan_unreg_multi;
47 unsigned int unknown_vlan_reg_multi;
43 struct ethtool_cmd ecmd; 48 struct ethtool_cmd ecmd;
44 49
45 unsigned int ret_type; /* Return Success/Failure */ 50 unsigned int ret_type; /* Return Success/Failure */