diff options
author | Mugunthan V N | 2014-09-02 08:04:20 -0500 |
---|---|---|
committer | Sekhar Nori | 2014-09-02 08:05:35 -0500 |
commit | fd012d03d17b38c5350ff814583b2f2f0fc0723f (patch) | |
tree | c477bcd5c426555a379b0fd248ef8aba28f43422 | |
parent | bbb401c6e8d9a92a86ba9d1bc6bebcec423ecfda (diff) | |
download | kernel-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.c | 26 | ||||
-rw-r--r-- | include/uapi/linux/net_switch_config.h | 5 |
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 | ||
33 | struct net_switch_config { | 34 | struct 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 */ |