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");