ocelot.c (4bda14156ee22af4825c2dd140e76d0b301bcd1b) | ocelot.c (f270dbfab8799f9fd9cfb275df1cabd36c06e918) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/etherdevice.h> 8#include <linux/ethtool.h> --- 119 unchanged lines hidden (view full) --- 128 | ANA_AGENCTRL_LEARN_FWD_KILL 129 | ANA_AGENCTRL_LEARN_IGNORE_VLAN, 130 ANA_AGENCTRL); 131 132 /* Clear the MAC table */ 133 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); 134} 135 | 1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/etherdevice.h> 8#include <linux/ethtool.h> --- 119 unchanged lines hidden (view full) --- 128 | ANA_AGENCTRL_LEARN_FWD_KILL 129 | ANA_AGENCTRL_LEARN_IGNORE_VLAN, 130 ANA_AGENCTRL); 131 132 /* Clear the MAC table */ 133 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); 134} 135 |
136static void ocelot_vcap_enable(struct ocelot *ocelot, struct ocelot_port *port) | 136static void ocelot_vcap_enable(struct ocelot *ocelot, int port) |
137{ 138 ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | 139 ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa), | 137{ 138 ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | 139 ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa), |
140 ANA_PORT_VCAP_S2_CFG, port->chip_port); | 140 ANA_PORT_VCAP_S2_CFG, port); |
141} 142 143static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) 144{ 145 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); 146} 147 148static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) --- 16 unchanged lines hidden (view full) --- 165 /* Set the vlan port members mask and issue a write command */ 166 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(mask) | 167 ANA_TABLES_VLANACCESS_CMD_WRITE, 168 ANA_TABLES_VLANACCESS); 169 170 return ocelot_vlant_wait_for_completion(ocelot); 171} 172 | 141} 142 143static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) 144{ 145 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); 146} 147 148static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) --- 16 unchanged lines hidden (view full) --- 165 /* Set the vlan port members mask and issue a write command */ 166 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(mask) | 167 ANA_TABLES_VLANACCESS_CMD_WRITE, 168 ANA_TABLES_VLANACCESS); 169 170 return ocelot_vlant_wait_for_completion(ocelot); 171} 172 |
173static void ocelot_vlan_mode(struct ocelot_port *port, | 173static void ocelot_vlan_mode(struct ocelot *ocelot, int port, |
174 netdev_features_t features) 175{ | 174 netdev_features_t features) 175{ |
176 struct ocelot *ocelot = port->ocelot; 177 u8 p = port->chip_port; | |
178 u32 val; 179 180 /* Filtering */ 181 val = ocelot_read(ocelot, ANA_VLANMASK); 182 if (features & NETIF_F_HW_VLAN_CTAG_FILTER) | 176 u32 val; 177 178 /* Filtering */ 179 val = ocelot_read(ocelot, ANA_VLANMASK); 180 if (features & NETIF_F_HW_VLAN_CTAG_FILTER) |
183 val |= BIT(p); | 181 val |= BIT(port); |
184 else | 182 else |
185 val &= ~BIT(p); | 183 val &= ~BIT(port); |
186 ocelot_write(ocelot, val, ANA_VLANMASK); 187} 188 189static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 190 bool vlan_aware) 191{ 192 struct ocelot_port *ocelot_port = ocelot->ports[port]; 193 u32 val; --- 835 unchanged lines hidden (view full) --- 1029 u16 vid) 1030{ 1031 return ocelot_vlan_vid_del(dev, vid); 1032} 1033 1034static int ocelot_set_features(struct net_device *dev, 1035 netdev_features_t features) 1036{ | 184 ocelot_write(ocelot, val, ANA_VLANMASK); 185} 186 187static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 188 bool vlan_aware) 189{ 190 struct ocelot_port *ocelot_port = ocelot->ports[port]; 191 u32 val; --- 835 unchanged lines hidden (view full) --- 1027 u16 vid) 1028{ 1029 return ocelot_vlan_vid_del(dev, vid); 1030} 1031 1032static int ocelot_set_features(struct net_device *dev, 1033 netdev_features_t features) 1034{ |
1037 struct ocelot_port *port = netdev_priv(dev); | |
1038 netdev_features_t changed = dev->features ^ features; | 1035 netdev_features_t changed = dev->features ^ features; |
1036 struct ocelot_port *ocelot_port = netdev_priv(dev); 1037 struct ocelot *ocelot = ocelot_port->ocelot; 1038 int port = ocelot_port->chip_port; |
|
1039 1040 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && | 1039 1040 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && |
1041 port->tc.offload_cnt) { | 1041 ocelot_port->tc.offload_cnt) { |
1042 netdev_err(dev, 1043 "Cannot disable HW TC offload while offloads active\n"); 1044 return -EBUSY; 1045 } 1046 1047 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) | 1042 netdev_err(dev, 1043 "Cannot disable HW TC offload while offloads active\n"); 1044 return -EBUSY; 1045 } 1046 1047 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) |
1048 ocelot_vlan_mode(port, features); | 1048 ocelot_vlan_mode(ocelot, port, features); |
1049 1050 return 0; 1051} 1052 1053static int ocelot_get_port_parent_id(struct net_device *dev, 1054 struct netdev_phys_item_id *ppid) 1055{ 1056 struct ocelot_port *ocelot_port = netdev_priv(dev); --- 524 unchanged lines hidden (view full) --- 1581 break; 1582 default: 1583 return -EOPNOTSUPP; 1584 } 1585 1586 return ret; 1587} 1588 | 1049 1050 return 0; 1051} 1052 1053static int ocelot_get_port_parent_id(struct net_device *dev, 1054 struct netdev_phys_item_id *ppid) 1055{ 1056 struct ocelot_port *ocelot_port = netdev_priv(dev); --- 524 unchanged lines hidden (view full) --- 1581 break; 1582 default: 1583 return -EOPNOTSUPP; 1584 } 1585 1586 return ret; 1587} 1588 |
1589static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port, | 1589static int ocelot_port_bridge_join(struct ocelot *ocelot, int port, |
1590 struct net_device *bridge) 1591{ | 1590 struct net_device *bridge) 1591{ |
1592 struct ocelot *ocelot = ocelot_port->ocelot; 1593 | |
1594 if (!ocelot->bridge_mask) { 1595 ocelot->hw_bridge_dev = bridge; 1596 } else { 1597 if (ocelot->hw_bridge_dev != bridge) 1598 /* This is adding the port to a second bridge, this is 1599 * unsupported */ 1600 return -ENODEV; 1601 } 1602 | 1592 if (!ocelot->bridge_mask) { 1593 ocelot->hw_bridge_dev = bridge; 1594 } else { 1595 if (ocelot->hw_bridge_dev != bridge) 1596 /* This is adding the port to a second bridge, this is 1597 * unsupported */ 1598 return -ENODEV; 1599 } 1600 |
1603 ocelot->bridge_mask |= BIT(ocelot_port->chip_port); | 1601 ocelot->bridge_mask |= BIT(port); |
1604 1605 return 0; 1606} 1607 | 1602 1603 return 0; 1604} 1605 |
1608static int ocelot_port_bridge_leave(struct ocelot_port *ocelot_port, | 1606static int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, |
1609 struct net_device *bridge) 1610{ | 1607 struct net_device *bridge) 1608{ |
1611 struct ocelot *ocelot = ocelot_port->ocelot; 1612 int port = ocelot_port->chip_port; 1613 | |
1614 ocelot->bridge_mask &= ~BIT(port); 1615 1616 if (!ocelot->bridge_mask) 1617 ocelot->hw_bridge_dev = NULL; 1618 1619 ocelot_port_vlan_filtering(ocelot, port, 0); 1620 ocelot_port_set_pvid(ocelot, port, 0); 1621 return ocelot_port_set_native_vlan(ocelot, port, 0); --- 52 unchanged lines hidden (view full) --- 1674 1675 /* Use lag port as logical port for port i */ 1676 ocelot_write_gix(ocelot, port_cfg | 1677 ANA_PORT_PORT_CFG_PORTID_VAL(lag), 1678 ANA_PORT_PORT_CFG, p); 1679 } 1680} 1681 | 1609 ocelot->bridge_mask &= ~BIT(port); 1610 1611 if (!ocelot->bridge_mask) 1612 ocelot->hw_bridge_dev = NULL; 1613 1614 ocelot_port_vlan_filtering(ocelot, port, 0); 1615 ocelot_port_set_pvid(ocelot, port, 0); 1616 return ocelot_port_set_native_vlan(ocelot, port, 0); --- 52 unchanged lines hidden (view full) --- 1669 1670 /* Use lag port as logical port for port i */ 1671 ocelot_write_gix(ocelot, port_cfg | 1672 ANA_PORT_PORT_CFG_PORTID_VAL(lag), 1673 ANA_PORT_PORT_CFG, p); 1674 } 1675} 1676 |
1682static int ocelot_port_lag_join(struct ocelot_port *ocelot_port, | 1677static int ocelot_port_lag_join(struct ocelot *ocelot, int port, |
1683 struct net_device *bond) 1684{ | 1678 struct net_device *bond) 1679{ |
1685 struct ocelot *ocelot = ocelot_port->ocelot; 1686 int p = ocelot_port->chip_port; 1687 int lag, lp; | |
1688 struct net_device *ndev; 1689 u32 bond_mask = 0; | 1680 struct net_device *ndev; 1681 u32 bond_mask = 0; |
1682 int lag, lp; |
|
1690 1691 rcu_read_lock(); 1692 for_each_netdev_in_bond_rcu(bond, ndev) { 1693 struct ocelot_port *port = netdev_priv(ndev); 1694 1695 bond_mask |= BIT(port->chip_port); 1696 } 1697 rcu_read_unlock(); 1698 1699 lp = __ffs(bond_mask); 1700 1701 /* If the new port is the lowest one, use it as the logical port from 1702 * now on 1703 */ | 1683 1684 rcu_read_lock(); 1685 for_each_netdev_in_bond_rcu(bond, ndev) { 1686 struct ocelot_port *port = netdev_priv(ndev); 1687 1688 bond_mask |= BIT(port->chip_port); 1689 } 1690 rcu_read_unlock(); 1691 1692 lp = __ffs(bond_mask); 1693 1694 /* If the new port is the lowest one, use it as the logical port from 1695 * now on 1696 */ |
1704 if (p == lp) { 1705 lag = p; 1706 ocelot->lags[p] = bond_mask; 1707 bond_mask &= ~BIT(p); | 1697 if (port == lp) { 1698 lag = port; 1699 ocelot->lags[port] = bond_mask; 1700 bond_mask &= ~BIT(port); |
1708 if (bond_mask) { 1709 lp = __ffs(bond_mask); 1710 ocelot->lags[lp] = 0; 1711 } 1712 } else { 1713 lag = lp; | 1701 if (bond_mask) { 1702 lp = __ffs(bond_mask); 1703 ocelot->lags[lp] = 0; 1704 } 1705 } else { 1706 lag = lp; |
1714 ocelot->lags[lp] |= BIT(p); | 1707 ocelot->lags[lp] |= BIT(port); |
1715 } 1716 1717 ocelot_setup_lag(ocelot, lag); 1718 ocelot_set_aggr_pgids(ocelot); 1719 1720 return 0; 1721} 1722 | 1708 } 1709 1710 ocelot_setup_lag(ocelot, lag); 1711 ocelot_set_aggr_pgids(ocelot); 1712 1713 return 0; 1714} 1715 |
1723static void ocelot_port_lag_leave(struct ocelot_port *ocelot_port, | 1716static void ocelot_port_lag_leave(struct ocelot *ocelot, int port, |
1724 struct net_device *bond) 1725{ | 1717 struct net_device *bond) 1718{ |
1726 struct ocelot *ocelot = ocelot_port->ocelot; 1727 int p = ocelot_port->chip_port; | |
1728 u32 port_cfg; 1729 int i; 1730 1731 /* Remove port from any lag */ 1732 for (i = 0; i < ocelot->num_phys_ports; i++) | 1719 u32 port_cfg; 1720 int i; 1721 1722 /* Remove port from any lag */ 1723 for (i = 0; i < ocelot->num_phys_ports; i++) |
1733 ocelot->lags[i] &= ~BIT(ocelot_port->chip_port); | 1724 ocelot->lags[i] &= ~BIT(port); |
1734 1735 /* if it was the logical port of the lag, move the lag config to the 1736 * next port 1737 */ | 1725 1726 /* if it was the logical port of the lag, move the lag config to the 1727 * next port 1728 */ |
1738 if (ocelot->lags[p]) { 1739 int n = __ffs(ocelot->lags[p]); | 1729 if (ocelot->lags[port]) { 1730 int n = __ffs(ocelot->lags[port]); |
1740 | 1731 |
1741 ocelot->lags[n] = ocelot->lags[p]; 1742 ocelot->lags[p] = 0; | 1732 ocelot->lags[n] = ocelot->lags[port]; 1733 ocelot->lags[port] = 0; |
1743 1744 ocelot_setup_lag(ocelot, n); 1745 } 1746 | 1734 1735 ocelot_setup_lag(ocelot, n); 1736 } 1737 |
1747 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, p); | 1738 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port); |
1748 port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M; | 1739 port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M; |
1749 ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(p), 1750 ANA_PORT_PORT_CFG, p); | 1740 ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(port), 1741 ANA_PORT_PORT_CFG, port); |
1751 1752 ocelot_set_aggr_pgids(ocelot); 1753} 1754 1755/* Checks if the net_device instance given to us originate from our driver. */ 1756static bool ocelot_netdevice_dev_check(const struct net_device *dev) 1757{ 1758 return dev->netdev_ops == &ocelot_port_netdev_ops; 1759} 1760 1761static int ocelot_netdevice_port_event(struct net_device *dev, 1762 unsigned long event, 1763 struct netdev_notifier_changeupper_info *info) 1764{ 1765 struct ocelot_port *ocelot_port = netdev_priv(dev); | 1742 1743 ocelot_set_aggr_pgids(ocelot); 1744} 1745 1746/* Checks if the net_device instance given to us originate from our driver. */ 1747static bool ocelot_netdevice_dev_check(const struct net_device *dev) 1748{ 1749 return dev->netdev_ops == &ocelot_port_netdev_ops; 1750} 1751 1752static int ocelot_netdevice_port_event(struct net_device *dev, 1753 unsigned long event, 1754 struct netdev_notifier_changeupper_info *info) 1755{ 1756 struct ocelot_port *ocelot_port = netdev_priv(dev); |
1757 struct ocelot *ocelot = ocelot_port->ocelot; 1758 int port = ocelot_port->chip_port; |
|
1766 int err = 0; 1767 1768 switch (event) { 1769 case NETDEV_CHANGEUPPER: 1770 if (netif_is_bridge_master(info->upper_dev)) { 1771 if (info->linking) | 1759 int err = 0; 1760 1761 switch (event) { 1762 case NETDEV_CHANGEUPPER: 1763 if (netif_is_bridge_master(info->upper_dev)) { 1764 if (info->linking) |
1772 err = ocelot_port_bridge_join(ocelot_port, | 1765 err = ocelot_port_bridge_join(ocelot, port, |
1773 info->upper_dev); 1774 else | 1766 info->upper_dev); 1767 else |
1775 err = ocelot_port_bridge_leave(ocelot_port, | 1768 err = ocelot_port_bridge_leave(ocelot, port, |
1776 info->upper_dev); 1777 } 1778 if (netif_is_lag_master(info->upper_dev)) { 1779 if (info->linking) | 1769 info->upper_dev); 1770 } 1771 if (netif_is_lag_master(info->upper_dev)) { 1772 if (info->linking) |
1780 err = ocelot_port_lag_join(ocelot_port, | 1773 err = ocelot_port_lag_join(ocelot, port, |
1781 info->upper_dev); 1782 else | 1774 info->upper_dev); 1775 else |
1783 ocelot_port_lag_leave(ocelot_port, | 1776 ocelot_port_lag_leave(ocelot, port, |
1784 info->upper_dev); 1785 } 1786 break; 1787 default: 1788 break; 1789 } 1790 1791 return err; --- 339 unchanged lines hidden (view full) --- 2131 ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port); 2132 2133 /* Set default VLAN and tag type to 8021Q. */ 2134 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), 2135 REW_PORT_VLAN_CFG_PORT_TPID_M, 2136 REW_PORT_VLAN_CFG, port); 2137 2138 /* Enable vcap lookups */ | 1777 info->upper_dev); 1778 } 1779 break; 1780 default: 1781 break; 1782 } 1783 1784 return err; --- 339 unchanged lines hidden (view full) --- 2124 ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port); 2125 2126 /* Set default VLAN and tag type to 8021Q. */ 2127 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), 2128 REW_PORT_VLAN_CFG_PORT_TPID_M, 2129 REW_PORT_VLAN_CFG, port); 2130 2131 /* Enable vcap lookups */ |
2139 ocelot_vcap_enable(ocelot, ocelot_port); | 2132 ocelot_vcap_enable(ocelot, port); |
2140 2141 return 0; 2142 2143err_register_netdev: 2144 free_netdev(dev); 2145 return err; 2146} 2147EXPORT_SYMBOL(ocelot_probe_port); --- 175 unchanged lines hidden --- | 2133 2134 return 0; 2135 2136err_register_netdev: 2137 free_netdev(dev); 2138 return err; 2139} 2140EXPORT_SYMBOL(ocelot_probe_port); --- 175 unchanged lines hidden --- |