ocelot.c (ef57640575406f57f5b3393cf57f457b0ace837e) | ocelot.c (c518afec288351347dbe05ea3d49d18fb9a9fff1) |
---|---|
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/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 535 unchanged lines hidden (view full) --- 544 545 return 0; 546} 547EXPORT_SYMBOL(ocelot_vlan_add); 548 549int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) 550{ 551 struct ocelot_port *ocelot_port = ocelot->ports[port]; | 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/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 535 unchanged lines hidden (view full) --- 544 545 return 0; 546} 547EXPORT_SYMBOL(ocelot_vlan_add); 548 549int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) 550{ 551 struct ocelot_port *ocelot_port = ocelot->ports[port]; |
552 bool del_pvid = false; | |
553 int err; 554 | 552 int err; 553 |
555 if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) 556 del_pvid = true; 557 | |
558 err = ocelot_vlan_member_del(ocelot, port, vid); 559 if (err) 560 return err; 561 562 /* Ingress */ | 554 err = ocelot_vlan_member_del(ocelot, port, vid); 555 if (err) 556 return err; 557 558 /* Ingress */ |
563 if (del_pvid) | 559 if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) |
564 ocelot_port_set_pvid(ocelot, port, NULL); 565 566 /* Egress */ 567 ocelot_port_manage_port_tag(ocelot, port); 568 569 return 0; 570} 571EXPORT_SYMBOL(ocelot_vlan_del); --- 964 unchanged lines hidden (view full) --- 1536 if (!trap->ingress_port_mask) 1537 return ocelot_vcap_filter_del(ocelot, trap); 1538 1539 return ocelot_vcap_filter_replace(ocelot, trap); 1540} 1541 1542static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) 1543{ | 560 ocelot_port_set_pvid(ocelot, port, NULL); 561 562 /* Egress */ 563 ocelot_port_manage_port_tag(ocelot, port); 564 565 return 0; 566} 567EXPORT_SYMBOL(ocelot_vlan_del); --- 964 unchanged lines hidden (view full) --- 1532 if (!trap->ingress_port_mask) 1533 return ocelot_vcap_filter_del(ocelot, trap); 1534 1535 return ocelot_vcap_filter_replace(ocelot, trap); 1536} 1537 1538static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) 1539{ |
1544 unsigned long l2_cookie = ocelot->num_phys_ports + 1; | 1540 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); |
1545 1546 return ocelot_trap_add(ocelot, port, l2_cookie, 1547 ocelot_populate_l2_ptp_trap_key); 1548} 1549 1550static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) 1551{ | 1541 1542 return ocelot_trap_add(ocelot, port, l2_cookie, 1543 ocelot_populate_l2_ptp_trap_key); 1544} 1545 1546static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) 1547{ |
1552 unsigned long l2_cookie = ocelot->num_phys_ports + 1; | 1548 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); |
1553 1554 return ocelot_trap_del(ocelot, port, l2_cookie); 1555} 1556 1557static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) 1558{ | 1549 1550 return ocelot_trap_del(ocelot, port, l2_cookie); 1551} 1552 1553static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) 1554{ |
1559 unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; 1560 unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; | 1555 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); 1556 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); |
1561 int err; 1562 1563 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, 1564 ocelot_populate_ipv4_ptp_event_trap_key); 1565 if (err) 1566 return err; 1567 1568 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, 1569 ocelot_populate_ipv4_ptp_general_trap_key); 1570 if (err) 1571 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1572 1573 return err; 1574} 1575 1576static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) 1577{ | 1557 int err; 1558 1559 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, 1560 ocelot_populate_ipv4_ptp_event_trap_key); 1561 if (err) 1562 return err; 1563 1564 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, 1565 ocelot_populate_ipv4_ptp_general_trap_key); 1566 if (err) 1567 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1568 1569 return err; 1570} 1571 1572static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) 1573{ |
1578 unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; 1579 unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; | 1574 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); 1575 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); |
1580 int err; 1581 1582 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1583 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); 1584 return err; 1585} 1586 1587static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) 1588{ | 1576 int err; 1577 1578 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1579 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); 1580 return err; 1581} 1582 1583static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) 1584{ |
1589 unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; 1590 unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; | 1585 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); 1586 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); |
1591 int err; 1592 1593 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, 1594 ocelot_populate_ipv6_ptp_event_trap_key); 1595 if (err) 1596 return err; 1597 1598 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, 1599 ocelot_populate_ipv6_ptp_general_trap_key); 1600 if (err) 1601 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1602 1603 return err; 1604} 1605 1606static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) 1607{ | 1587 int err; 1588 1589 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, 1590 ocelot_populate_ipv6_ptp_event_trap_key); 1591 if (err) 1592 return err; 1593 1594 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, 1595 ocelot_populate_ipv6_ptp_general_trap_key); 1596 if (err) 1597 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1598 1599 return err; 1600} 1601 1602static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) 1603{ |
1608 unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; 1609 unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; | 1604 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); 1605 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); |
1610 int err; 1611 1612 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1613 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); 1614 return err; 1615} 1616 1617static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, --- 127 unchanged lines hidden (view full) --- 1745 1746 for (i = 0; i < ocelot->num_stats; i++) 1747 memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name, 1748 ETH_GSTRING_LEN); 1749} 1750EXPORT_SYMBOL(ocelot_get_strings); 1751 1752/* Caller must hold &ocelot->stats_lock */ | 1606 int err; 1607 1608 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1609 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); 1610 return err; 1611} 1612 1613static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, --- 127 unchanged lines hidden (view full) --- 1741 1742 for (i = 0; i < ocelot->num_stats; i++) 1743 memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name, 1744 ETH_GSTRING_LEN); 1745} 1746EXPORT_SYMBOL(ocelot_get_strings); 1747 1748/* Caller must hold &ocelot->stats_lock */ |
1753static void ocelot_update_stats(struct ocelot *ocelot) | 1749static int ocelot_port_update_stats(struct ocelot *ocelot, int port) |
1754{ | 1750{ |
1755 int i, j; | 1751 unsigned int idx = port * ocelot->num_stats; 1752 struct ocelot_stats_region *region; 1753 int err, j; |
1756 | 1754 |
1757 for (i = 0; i < ocelot->num_phys_ports; i++) { 1758 /* Configure the port to read the stats from */ 1759 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(i), SYS_STAT_CFG); | 1755 /* Configure the port to read the stats from */ 1756 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), SYS_STAT_CFG); |
1760 | 1757 |
1761 for (j = 0; j < ocelot->num_stats; j++) { 1762 u32 val; 1763 unsigned int idx = i * ocelot->num_stats + j; | 1758 list_for_each_entry(region, &ocelot->stats_regions, node) { 1759 err = ocelot_bulk_read_rix(ocelot, SYS_COUNT_RX_OCTETS, 1760 region->offset, region->buf, 1761 region->count); 1762 if (err) 1763 return err; |
1764 | 1764 |
1765 val = ocelot_read_rix(ocelot, SYS_COUNT_RX_OCTETS, 1766 ocelot->stats_layout[j].offset); | 1765 for (j = 0; j < region->count; j++) { 1766 u64 *stat = &ocelot->stats[idx + j]; 1767 u64 val = region->buf[j]; |
1767 | 1768 |
1768 if (val < (ocelot->stats[idx] & U32_MAX)) 1769 ocelot->stats[idx] += (u64)1 << 32; | 1769 if (val < (*stat & U32_MAX)) 1770 *stat += (u64)1 << 32; |
1770 | 1771 |
1771 ocelot->stats[idx] = (ocelot->stats[idx] & 1772 ~(u64)U32_MAX) + val; | 1772 *stat = (*stat & ~(u64)U32_MAX) + val; |
1773 } | 1773 } |
1774 1775 idx += region->count; |
|
1774 } | 1776 } |
1777 1778 return err; |
|
1775} 1776 1777static void ocelot_check_stats_work(struct work_struct *work) 1778{ 1779 struct delayed_work *del_work = to_delayed_work(work); 1780 struct ocelot *ocelot = container_of(del_work, struct ocelot, 1781 stats_work); | 1779} 1780 1781static void ocelot_check_stats_work(struct work_struct *work) 1782{ 1783 struct delayed_work *del_work = to_delayed_work(work); 1784 struct ocelot *ocelot = container_of(del_work, struct ocelot, 1785 stats_work); |
1786 int i, err; |
|
1782 1783 mutex_lock(&ocelot->stats_lock); | 1787 1788 mutex_lock(&ocelot->stats_lock); |
1784 ocelot_update_stats(ocelot); | 1789 for (i = 0; i < ocelot->num_phys_ports; i++) { 1790 err = ocelot_port_update_stats(ocelot, i); 1791 if (err) 1792 break; 1793 } |
1785 mutex_unlock(&ocelot->stats_lock); 1786 | 1794 mutex_unlock(&ocelot->stats_lock); 1795 |
1796 if (err) 1797 dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err); 1798 |
|
1787 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work, 1788 OCELOT_STATS_CHECK_DELAY); 1789} 1790 1791void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) 1792{ | 1799 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work, 1800 OCELOT_STATS_CHECK_DELAY); 1801} 1802 1803void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) 1804{ |
1793 int i; | 1805 int i, err; |
1794 1795 mutex_lock(&ocelot->stats_lock); 1796 1797 /* check and update now */ | 1806 1807 mutex_lock(&ocelot->stats_lock); 1808 1809 /* check and update now */ |
1798 ocelot_update_stats(ocelot); | 1810 err = ocelot_port_update_stats(ocelot, port); |
1799 1800 /* Copy all counters */ 1801 for (i = 0; i < ocelot->num_stats; i++) 1802 *data++ = ocelot->stats[port * ocelot->num_stats + i]; 1803 1804 mutex_unlock(&ocelot->stats_lock); | 1811 1812 /* Copy all counters */ 1813 for (i = 0; i < ocelot->num_stats; i++) 1814 *data++ = ocelot->stats[port * ocelot->num_stats + i]; 1815 1816 mutex_unlock(&ocelot->stats_lock); |
1817 1818 if (err) 1819 dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err); |
|
1805} 1806EXPORT_SYMBOL(ocelot_get_ethtool_stats); 1807 1808int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset) 1809{ 1810 if (sset != ETH_SS_STATS) 1811 return -EOPNOTSUPP; 1812 1813 return ocelot->num_stats; 1814} 1815EXPORT_SYMBOL(ocelot_get_sset_count); 1816 | 1820} 1821EXPORT_SYMBOL(ocelot_get_ethtool_stats); 1822 1823int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset) 1824{ 1825 if (sset != ETH_SS_STATS) 1826 return -EOPNOTSUPP; 1827 1828 return ocelot->num_stats; 1829} 1830EXPORT_SYMBOL(ocelot_get_sset_count); 1831 |
1832static int ocelot_prepare_stats_regions(struct ocelot *ocelot) 1833{ 1834 struct ocelot_stats_region *region = NULL; 1835 unsigned int last; 1836 int i; 1837 1838 INIT_LIST_HEAD(&ocelot->stats_regions); 1839 1840 for (i = 0; i < ocelot->num_stats; i++) { 1841 if (region && ocelot->stats_layout[i].offset == last + 1) { 1842 region->count++; 1843 } else { 1844 region = devm_kzalloc(ocelot->dev, sizeof(*region), 1845 GFP_KERNEL); 1846 if (!region) 1847 return -ENOMEM; 1848 1849 region->offset = ocelot->stats_layout[i].offset; 1850 region->count = 1; 1851 list_add_tail(®ion->node, &ocelot->stats_regions); 1852 } 1853 1854 last = ocelot->stats_layout[i].offset; 1855 } 1856 1857 list_for_each_entry(region, &ocelot->stats_regions, node) { 1858 region->buf = devm_kcalloc(ocelot->dev, region->count, 1859 sizeof(*region->buf), GFP_KERNEL); 1860 if (!region->buf) 1861 return -ENOMEM; 1862 } 1863 1864 return 0; 1865} 1866 |
|
1817int ocelot_get_ts_info(struct ocelot *ocelot, int port, 1818 struct ethtool_ts_info *info) 1819{ 1820 info->phc_index = ocelot->ptp_clock ? 1821 ptp_clock_index(ocelot->ptp_clock) : -1; 1822 if (info->phc_index == -1) { 1823 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | 1824 SOF_TIMESTAMPING_RX_SOFTWARE | --- 984 unchanged lines hidden (view full) --- 2809 ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) | 2810 ANA_CPUQ_CFG_CPUQ_IGMP(6) | 2811 ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG); 2812 for (i = 0; i < 16; i++) 2813 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) | 2814 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6), 2815 ANA_CPUQ_8021_CFG, i); 2816 | 1867int ocelot_get_ts_info(struct ocelot *ocelot, int port, 1868 struct ethtool_ts_info *info) 1869{ 1870 info->phc_index = ocelot->ptp_clock ? 1871 ptp_clock_index(ocelot->ptp_clock) : -1; 1872 if (info->phc_index == -1) { 1873 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | 1874 SOF_TIMESTAMPING_RX_SOFTWARE | --- 984 unchanged lines hidden (view full) --- 2859 ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) | 2860 ANA_CPUQ_CFG_CPUQ_IGMP(6) | 2861 ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG); 2862 for (i = 0; i < 16; i++) 2863 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) | 2864 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6), 2865 ANA_CPUQ_8021_CFG, i); 2866 |
2867 ret = ocelot_prepare_stats_regions(ocelot); 2868 if (ret) { 2869 destroy_workqueue(ocelot->stats_queue); 2870 destroy_workqueue(ocelot->owq); 2871 return ret; 2872 } 2873 |
|
2817 INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats_work); 2818 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work, 2819 OCELOT_STATS_CHECK_DELAY); 2820 2821 return 0; 2822} 2823EXPORT_SYMBOL(ocelot_init); 2824 --- 18 unchanged lines hidden --- | 2874 INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats_work); 2875 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work, 2876 OCELOT_STATS_CHECK_DELAY); 2877 2878 return 0; 2879} 2880EXPORT_SYMBOL(ocelot_init); 2881 --- 18 unchanged lines hidden --- |