aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMugunthan V N2014-09-02 08:04:21 -0500
committerSekhar Nori2014-09-02 08:06:58 -0500
commit088f0226367a0f04d055080878a5c4c8a0ebf05b (patch)
tree751bf70be47e2918d575b2d24e397a5132b84b60
parentfd012d03d17b38c5350ff814583b2f2f0fc0723f (diff)
downloadkernel-video-088f0226367a0f04d055080878a5c4c8a0ebf05b.tar.gz
kernel-video-088f0226367a0f04d055080878a5c4c8a0ebf05b.tar.xz
kernel-video-088f0226367a0f04d055080878a5c4c8a0ebf05b.zip
drivers: net: cpsw: switch-config: set/get port state
Configuring port states handling of the packet switching to the slave port like disabling packet forwarding/learning. Note: Using this interface an user can disable all the slave ports which will bring down the Ethernet interface. 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.c51
-rw-r--r--include/uapi/linux/net_switch_config.h10
2 files changed, 59 insertions, 2 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index d8ff8237af3..5a7717ee83b 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -398,6 +398,7 @@ struct cpsw_priv {
398 struct cpdma_ctlr *dma; 398 struct cpdma_ctlr *dma;
399 struct cpdma_chan *txch, *rxch; 399 struct cpdma_chan *txch, *rxch;
400 struct cpsw_ale *ale; 400 struct cpsw_ale *ale;
401 u8 port_state[3];
401 /* snapshot of IRQ numbers */ 402 /* snapshot of IRQ numbers */
402 u32 irqs_table[4]; 403 u32 irqs_table[4];
403 u32 num_irqs; 404 u32 num_irqs;
@@ -842,7 +843,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
842 843
843 /* enable forwarding */ 844 /* enable forwarding */
844 cpsw_ale_control_set(priv->ale, slave_port, 845 cpsw_ale_control_set(priv->ale, slave_port,
845 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 846 ALE_PORT_STATE,
847 priv->port_state[slave_port]);
846 848
847 if (phy->speed == 1000) 849 if (phy->speed == 1000)
848 mac_control |= BIT(7); /* GIGABITEN */ 850 mac_control |= BIT(7); /* GIGABITEN */
@@ -860,7 +862,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
860 mac_control = 0; 862 mac_control = 0;
861 /* disable forwarding */ 863 /* disable forwarding */
862 cpsw_ale_control_set(priv->ale, slave_port, 864 cpsw_ale_control_set(priv->ale, slave_port,
863 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 865 ALE_PORT_STATE,
866 priv->port_state[slave_port]);
864 } 867 }
865 868
866 if (mac_control != slave->mac_control) { 869 if (mac_control != slave->mac_control) {
@@ -1181,6 +1184,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
1181 slave->mac_control = 0; /* no link yet */ 1184 slave->mac_control = 0; /* no link yet */
1182 1185
1183 slave_port = cpsw_get_slave_port(priv, slave->slave_num); 1186 slave_port = cpsw_get_slave_port(priv, slave->slave_num);
1187 priv->port_state[slave_port] = ALE_PORT_STATE_FORWARD;
1184 1188
1185 if (priv->data.dual_emac) 1189 if (priv->data.dual_emac)
1186 cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port); 1190 cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
@@ -1597,6 +1601,30 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
1597 1601
1598#endif /*CONFIG_TI_CPTS*/ 1602#endif /*CONFIG_TI_CPTS*/
1599 1603
1604static int cpsw_set_port_state(struct cpsw_priv *priv, int port,
1605 int port_state)
1606{
1607 switch (port_state) {
1608 case PORT_STATE_DISABLED:
1609 priv->port_state[port] = ALE_PORT_STATE_DISABLE;
1610 break;
1611 case PORT_STATE_BLOCKED:
1612 priv->port_state[port] = ALE_PORT_STATE_BLOCK;
1613 break;
1614 case PORT_STATE_LEARN:
1615 priv->port_state[port] = ALE_PORT_STATE_LEARN;
1616 break;
1617 case PORT_STATE_FORWARD:
1618 priv->port_state[port] = ALE_PORT_STATE_FORWARD;
1619 break;
1620 default:
1621 dev_err(priv->dev, "Switch config: Invalid port state\n");
1622 return -EFAULT;
1623 }
1624 return cpsw_ale_control_set(priv->ale, port, ALE_PORT_STATE,
1625 priv->port_state[port]);
1626}
1627
1600static int cpsw_switch_config_ioctl(struct net_device *ndev, 1628static int cpsw_switch_config_ioctl(struct net_device *ndev,
1601 struct ifreq *ifrq, int cmd) 1629 struct ifreq *ifrq, int cmd)
1602{ 1630{
@@ -1721,6 +1749,25 @@ static int cpsw_switch_config_ioctl(struct net_device *ndev,
1721 ret = -EINVAL; 1749 ret = -EINVAL;
1722 } 1750 }
1723 break; 1751 break;
1752 case CONFIG_SWITCH_GET_PORT_STATE:
1753 if ((config.port == 1) || (config.port == 2)) {
1754 config.port_state = priv->port_state[config.port];
1755 ret = copy_to_user(ifrq->ifr_data, &config,
1756 sizeof(config));
1757 } else {
1758 dev_err(priv->dev, "Invalid Arguments\n");
1759 ret = -EINVAL;
1760 }
1761 break;
1762 case CONFIG_SWITCH_SET_PORT_STATE:
1763 if ((config.port == 1) || (config.port == 2)) {
1764 ret = cpsw_set_port_state(priv, config.port,
1765 config.port_state);
1766 } else {
1767 dev_err(priv->dev, "Invalid Arguments\n");
1768 ret = -EINVAL;
1769 }
1770 break;
1724 1771
1725 default: 1772 default:
1726 ret = -EOPNOTSUPP; 1773 ret = -EOPNOTSUPP;
diff --git a/include/uapi/linux/net_switch_config.h b/include/uapi/linux/net_switch_config.h
index afc64d9ceb5..149fcdc0680 100644
--- a/include/uapi/linux/net_switch_config.h
+++ b/include/uapi/linux/net_switch_config.h
@@ -29,6 +29,15 @@ enum {
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 CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO,
32 CONFIG_SWITCH_GET_PORT_STATE,
33 CONFIG_SWITCH_SET_PORT_STATE,
34};
35
36enum {
37 PORT_STATE_DISABLED = 0,
38 PORT_STATE_BLOCKED,
39 PORT_STATE_LEARN,
40 PORT_STATE_FORWARD,
32}; 41};
33 42
34struct net_switch_config { 43struct net_switch_config {
@@ -45,6 +54,7 @@ struct net_switch_config {
45 unsigned char unknown_vlan_untag; 54 unsigned char unknown_vlan_untag;
46 unsigned int unknown_vlan_unreg_multi; 55 unsigned int unknown_vlan_unreg_multi;
47 unsigned int unknown_vlan_reg_multi; 56 unsigned int unknown_vlan_reg_multi;
57 unsigned int port_state;
48 struct ethtool_cmd ecmd; 58 struct ethtool_cmd ecmd;
49 59
50 unsigned int ret_type; /* Return Success/Failure */ 60 unsigned int ret_type; /* Return Success/Failure */