ocelot.c (860dbce3d8dd90cb9e909c58fa79808766243651) | ocelot.c (b596229448dd2a263cdc4906e60b1b2249777ee4) |
---|---|
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> --- 8 unchanged lines hidden (view full) --- 17#include <linux/skbuff.h> 18#include <linux/iopoll.h> 19#include <net/arp.h> 20#include <net/netevent.h> 21#include <net/rtnetlink.h> 22#include <net/switchdev.h> 23 24#include "ocelot.h" | 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> --- 8 unchanged lines hidden (view full) --- 17#include <linux/skbuff.h> 18#include <linux/iopoll.h> 19#include <net/arp.h> 20#include <net/netevent.h> 21#include <net/rtnetlink.h> 22#include <net/switchdev.h> 23 24#include "ocelot.h" |
25#include "ocelot_ace.h" |
|
25 26#define TABLE_UPDATE_SLEEP_US 10 27#define TABLE_UPDATE_TIMEOUT_US 100000 28 29/* MAC table entry types. 30 * ENTRYTYPE_NORMAL is subject to aging. 31 * ENTRYTYPE_LOCKED is not subject to aging. 32 * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast. --- 92 unchanged lines hidden (view full) --- 125 | ANA_AGENCTRL_LEARN_FWD_KILL 126 | ANA_AGENCTRL_LEARN_IGNORE_VLAN, 127 ANA_AGENCTRL); 128 129 /* Clear the MAC table */ 130 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); 131} 132 | 26 27#define TABLE_UPDATE_SLEEP_US 10 28#define TABLE_UPDATE_TIMEOUT_US 100000 29 30/* MAC table entry types. 31 * ENTRYTYPE_NORMAL is subject to aging. 32 * ENTRYTYPE_LOCKED is not subject to aging. 33 * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast. --- 92 unchanged lines hidden (view full) --- 126 | ANA_AGENCTRL_LEARN_FWD_KILL 127 | ANA_AGENCTRL_LEARN_IGNORE_VLAN, 128 ANA_AGENCTRL); 129 130 /* Clear the MAC table */ 131 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); 132} 133 |
134static void ocelot_vcap_enable(struct ocelot *ocelot, struct ocelot_port *port) 135{ 136 ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | 137 ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa), 138 ANA_PORT_VCAP_S2_CFG, port->chip_port); 139} 140 |
|
133static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) 134{ 135 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); 136} 137 138static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) 139{ 140 u32 val; --- 738 unchanged lines hidden (view full) --- 879} 880 881static int ocelot_set_features(struct net_device *dev, 882 netdev_features_t features) 883{ 884 struct ocelot_port *port = netdev_priv(dev); 885 netdev_features_t changed = dev->features ^ features; 886 | 141static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) 142{ 143 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); 144} 145 146static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) 147{ 148 u32 val; --- 738 unchanged lines hidden (view full) --- 887} 888 889static int ocelot_set_features(struct net_device *dev, 890 netdev_features_t features) 891{ 892 struct ocelot_port *port = netdev_priv(dev); 893 netdev_features_t changed = dev->features ^ features; 894 |
895 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && 896 port->tc.offload_cnt) { 897 netdev_err(dev, 898 "Cannot disable HW TC offload while offloads active\n"); 899 return -EBUSY; 900 } 901 |
|
887 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) 888 ocelot_vlan_mode(port, features); 889 890 return 0; 891} 892 893static int ocelot_get_port_parent_id(struct net_device *dev, 894 struct netdev_phys_item_id *ppid) --- 17 unchanged lines hidden (view full) --- 912 .ndo_get_stats64 = ocelot_get_stats64, 913 .ndo_fdb_add = ocelot_fdb_add, 914 .ndo_fdb_del = ocelot_fdb_del, 915 .ndo_fdb_dump = ocelot_fdb_dump, 916 .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid, 917 .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid, 918 .ndo_set_features = ocelot_set_features, 919 .ndo_get_port_parent_id = ocelot_get_port_parent_id, | 902 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) 903 ocelot_vlan_mode(port, features); 904 905 return 0; 906} 907 908static int ocelot_get_port_parent_id(struct net_device *dev, 909 struct netdev_phys_item_id *ppid) --- 17 unchanged lines hidden (view full) --- 927 .ndo_get_stats64 = ocelot_get_stats64, 928 .ndo_fdb_add = ocelot_fdb_add, 929 .ndo_fdb_del = ocelot_fdb_del, 930 .ndo_fdb_dump = ocelot_fdb_dump, 931 .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid, 932 .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid, 933 .ndo_set_features = ocelot_set_features, 934 .ndo_get_port_parent_id = ocelot_get_port_parent_id, |
935 .ndo_setup_tc = ocelot_setup_tc, |
|
920}; 921 922static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data) 923{ 924 struct ocelot_port *port = netdev_priv(netdev); 925 struct ocelot *ocelot = port->ocelot; 926 int i; 927 --- 703 unchanged lines hidden (view full) --- 1631 ocelot_port->regs = regs; 1632 ocelot_port->chip_port = port; 1633 ocelot_port->phy = phy; 1634 ocelot->ports[port] = ocelot_port; 1635 1636 dev->netdev_ops = &ocelot_port_netdev_ops; 1637 dev->ethtool_ops = &ocelot_ethtool_ops; 1638 | 936}; 937 938static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data) 939{ 940 struct ocelot_port *port = netdev_priv(netdev); 941 struct ocelot *ocelot = port->ocelot; 942 int i; 943 --- 703 unchanged lines hidden (view full) --- 1647 ocelot_port->regs = regs; 1648 ocelot_port->chip_port = port; 1649 ocelot_port->phy = phy; 1650 ocelot->ports[port] = ocelot_port; 1651 1652 dev->netdev_ops = &ocelot_port_netdev_ops; 1653 dev->ethtool_ops = &ocelot_ethtool_ops; 1654 |
1639 dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS; 1640 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | 1655 dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS | 1656 NETIF_F_HW_TC; 1657 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC; |
1641 1642 memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN); 1643 dev->dev_addr[ETH_ALEN - 1] += port; 1644 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid, 1645 ENTRYTYPE_LOCKED); 1646 1647 err = register_netdev(dev); 1648 if (err) { 1649 dev_err(ocelot->dev, "register_netdev failed\n"); 1650 goto err_register_netdev; 1651 } 1652 1653 /* Basic L2 initialization */ 1654 ocelot_vlan_port_apply(ocelot, ocelot_port); 1655 | 1658 1659 memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN); 1660 dev->dev_addr[ETH_ALEN - 1] += port; 1661 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid, 1662 ENTRYTYPE_LOCKED); 1663 1664 err = register_netdev(dev); 1665 if (err) { 1666 dev_err(ocelot->dev, "register_netdev failed\n"); 1667 goto err_register_netdev; 1668 } 1669 1670 /* Basic L2 initialization */ 1671 ocelot_vlan_port_apply(ocelot, ocelot_port); 1672 |
1673 /* Enable vcap lookups */ 1674 ocelot_vcap_enable(ocelot, ocelot_port); 1675 |
|
1656 return 0; 1657 1658err_register_netdev: 1659 free_netdev(dev); 1660 return err; 1661} 1662EXPORT_SYMBOL(ocelot_probe_port); 1663 --- 18 unchanged lines hidden (view full) --- 1682 snprintf(queue_name, sizeof(queue_name), "%s-stats", 1683 dev_name(ocelot->dev)); 1684 ocelot->stats_queue = create_singlethread_workqueue(queue_name); 1685 if (!ocelot->stats_queue) 1686 return -ENOMEM; 1687 1688 ocelot_mact_init(ocelot); 1689 ocelot_vlan_init(ocelot); | 1676 return 0; 1677 1678err_register_netdev: 1679 free_netdev(dev); 1680 return err; 1681} 1682EXPORT_SYMBOL(ocelot_probe_port); 1683 --- 18 unchanged lines hidden (view full) --- 1702 snprintf(queue_name, sizeof(queue_name), "%s-stats", 1703 dev_name(ocelot->dev)); 1704 ocelot->stats_queue = create_singlethread_workqueue(queue_name); 1705 if (!ocelot->stats_queue) 1706 return -ENOMEM; 1707 1708 ocelot_mact_init(ocelot); 1709 ocelot_vlan_init(ocelot); |
1710 ocelot_ace_init(ocelot); |
|
1690 1691 for (port = 0; port < ocelot->num_phys_ports; port++) { 1692 /* Clear all counters (5 groups) */ 1693 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) | 1694 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f), 1695 SYS_STAT_CFG); 1696 } 1697 --- 96 unchanged lines hidden (view full) --- 1794 return 0; 1795} 1796EXPORT_SYMBOL(ocelot_init); 1797 1798void ocelot_deinit(struct ocelot *ocelot) 1799{ 1800 destroy_workqueue(ocelot->stats_queue); 1801 mutex_destroy(&ocelot->stats_lock); | 1711 1712 for (port = 0; port < ocelot->num_phys_ports; port++) { 1713 /* Clear all counters (5 groups) */ 1714 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) | 1715 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f), 1716 SYS_STAT_CFG); 1717 } 1718 --- 96 unchanged lines hidden (view full) --- 1815 return 0; 1816} 1817EXPORT_SYMBOL(ocelot_init); 1818 1819void ocelot_deinit(struct ocelot *ocelot) 1820{ 1821 destroy_workqueue(ocelot->stats_queue); 1822 mutex_destroy(&ocelot->stats_lock); |
1823 ocelot_ace_deinit(); |
|
1802} 1803EXPORT_SYMBOL(ocelot_deinit); 1804 1805MODULE_LICENSE("Dual MIT/GPL"); | 1824} 1825EXPORT_SYMBOL(ocelot_deinit); 1826 1827MODULE_LICENSE("Dual MIT/GPL"); |