Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'dsa-felix-qos'

Vladimir Oltean says:

====================
Basic QoS classification on Felix DSA switch using dcbnl

Basic QoS classification for Ocelot switches means port-based default
priority, DSCP-based and VLAN PCP based. This is opposed to advanced QoS
classification which is done through the VCAP IS1 TCAM based engine.

The patch set is a logical continuation of this RFC which attempted to
describe the default-prio as a matchall entry placed at the end of a
series of offloaded tc filters:
https://patchwork.kernel.org/project/netdevbpf/cover/20210113154139.1803705-1-olteanv@gmail.com/

I have tried my best to satisfy the feedback that we should cater for
pre-configured QoS profiles. Ironically, the only pre-configured QoS
profile that the Felix switch driver has is for VLAN PCP (1:1 mapping
with QoS class), yet IEEE 802.1Q or dcbnl offer no mechanism for
reporting or changing that.

Testing was done with the iproute2 dcb app. The qos_class of packets was
dumped from net/dsa/tag_ocelot.c.

(1) $ dcb app show dev swp3
default-prio 0
(2) $ dcb app replace dev swp3 default-prio 3
(3) $ dcb app replace dev swp3 dscp-prio CS3:5
(4) $ dcb app replace dev swp3 dscp-prio CS2:2
(5) $ dcb app show dev swp3
default-prio 3
dscp-prio CS2:2 CS3:5

Traffic sent with "ping -Q 64 <ipaddr>", which means CS2.
These packets match qos_class 0 after command (1),
qos_class 3 after command (2),
qos_class 3 after command (3), and
qos_class 2 after command (2).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+399
+43
drivers/net/dsa/ocelot/felix.c
··· 1799 1799 return ocelot_mrp_del_ring_role(ocelot, port, mrp); 1800 1800 } 1801 1801 1802 + static int felix_port_get_default_prio(struct dsa_switch *ds, int port) 1803 + { 1804 + struct ocelot *ocelot = ds->priv; 1805 + 1806 + return ocelot_port_get_default_prio(ocelot, port); 1807 + } 1808 + 1809 + static int felix_port_set_default_prio(struct dsa_switch *ds, int port, 1810 + u8 prio) 1811 + { 1812 + struct ocelot *ocelot = ds->priv; 1813 + 1814 + return ocelot_port_set_default_prio(ocelot, port, prio); 1815 + } 1816 + 1817 + static int felix_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp) 1818 + { 1819 + struct ocelot *ocelot = ds->priv; 1820 + 1821 + return ocelot_port_get_dscp_prio(ocelot, port, dscp); 1822 + } 1823 + 1824 + static int felix_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, 1825 + u8 prio) 1826 + { 1827 + struct ocelot *ocelot = ds->priv; 1828 + 1829 + return ocelot_port_add_dscp_prio(ocelot, port, dscp, prio); 1830 + } 1831 + 1832 + static int felix_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, 1833 + u8 prio) 1834 + { 1835 + struct ocelot *ocelot = ds->priv; 1836 + 1837 + return ocelot_port_del_dscp_prio(ocelot, port, dscp, prio); 1838 + } 1839 + 1802 1840 const struct dsa_switch_ops felix_switch_ops = { 1803 1841 .get_tag_protocol = felix_get_tag_protocol, 1804 1842 .change_tag_protocol = felix_change_tag_protocol, ··· 1900 1862 .port_mrp_del_ring_role = felix_mrp_del_ring_role, 1901 1863 .tag_8021q_vlan_add = felix_tag_8021q_vlan_add, 1902 1864 .tag_8021q_vlan_del = felix_tag_8021q_vlan_del, 1865 + .port_get_default_prio = felix_port_get_default_prio, 1866 + .port_set_default_prio = felix_port_set_default_prio, 1867 + .port_get_dscp_prio = felix_port_get_dscp_prio, 1868 + .port_add_dscp_prio = felix_port_add_dscp_prio, 1869 + .port_del_dscp_prio = felix_port_del_dscp_prio, 1903 1870 }; 1904 1871 1905 1872 struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port)
+116
drivers/net/ethernet/mscc/ocelot.c
··· 2907 2907 } 2908 2908 EXPORT_SYMBOL(ocelot_port_bridge_flags); 2909 2909 2910 + int ocelot_port_get_default_prio(struct ocelot *ocelot, int port) 2911 + { 2912 + int val = ocelot_read_gix(ocelot, ANA_PORT_QOS_CFG, port); 2913 + 2914 + return ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_X(val); 2915 + } 2916 + EXPORT_SYMBOL_GPL(ocelot_port_get_default_prio); 2917 + 2918 + int ocelot_port_set_default_prio(struct ocelot *ocelot, int port, u8 prio) 2919 + { 2920 + if (prio >= IEEE_8021QAZ_MAX_TCS) 2921 + return -ERANGE; 2922 + 2923 + ocelot_rmw_gix(ocelot, 2924 + ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL(prio), 2925 + ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_M, 2926 + ANA_PORT_QOS_CFG, 2927 + port); 2928 + 2929 + return 0; 2930 + } 2931 + EXPORT_SYMBOL_GPL(ocelot_port_set_default_prio); 2932 + 2933 + int ocelot_port_get_dscp_prio(struct ocelot *ocelot, int port, u8 dscp) 2934 + { 2935 + int qos_cfg = ocelot_read_gix(ocelot, ANA_PORT_QOS_CFG, port); 2936 + int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); 2937 + 2938 + /* Return error if DSCP prioritization isn't enabled */ 2939 + if (!(qos_cfg & ANA_PORT_QOS_CFG_QOS_DSCP_ENA)) 2940 + return -EOPNOTSUPP; 2941 + 2942 + if (qos_cfg & ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA) { 2943 + dscp = ANA_DSCP_CFG_DSCP_TRANSLATE_VAL_X(dscp_cfg); 2944 + /* Re-read ANA_DSCP_CFG for the translated DSCP */ 2945 + dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); 2946 + } 2947 + 2948 + /* If the DSCP value is not trusted, the QoS classification falls back 2949 + * to VLAN PCP or port-based default. 2950 + */ 2951 + if (!(dscp_cfg & ANA_DSCP_CFG_DSCP_TRUST_ENA)) 2952 + return -EOPNOTSUPP; 2953 + 2954 + return ANA_DSCP_CFG_QOS_DSCP_VAL_X(dscp_cfg); 2955 + } 2956 + EXPORT_SYMBOL_GPL(ocelot_port_get_dscp_prio); 2957 + 2958 + int ocelot_port_add_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio) 2959 + { 2960 + int mask, val; 2961 + 2962 + if (prio >= IEEE_8021QAZ_MAX_TCS) 2963 + return -ERANGE; 2964 + 2965 + /* There is at least one app table priority (this one), so we need to 2966 + * make sure DSCP prioritization is enabled on the port. 2967 + * Also make sure DSCP translation is disabled 2968 + * (dcbnl doesn't support it). 2969 + */ 2970 + mask = ANA_PORT_QOS_CFG_QOS_DSCP_ENA | 2971 + ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA; 2972 + 2973 + ocelot_rmw_gix(ocelot, ANA_PORT_QOS_CFG_QOS_DSCP_ENA, mask, 2974 + ANA_PORT_QOS_CFG, port); 2975 + 2976 + /* Trust this DSCP value and map it to the given QoS class */ 2977 + val = ANA_DSCP_CFG_DSCP_TRUST_ENA | ANA_DSCP_CFG_QOS_DSCP_VAL(prio); 2978 + 2979 + ocelot_write_rix(ocelot, val, ANA_DSCP_CFG, dscp); 2980 + 2981 + return 0; 2982 + } 2983 + EXPORT_SYMBOL_GPL(ocelot_port_add_dscp_prio); 2984 + 2985 + int ocelot_port_del_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio) 2986 + { 2987 + int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); 2988 + int mask, i; 2989 + 2990 + /* During a "dcb app replace" command, the new app table entry will be 2991 + * added first, then the old one will be deleted. But the hardware only 2992 + * supports one QoS class per DSCP value (duh), so if we blindly delete 2993 + * the app table entry for this DSCP value, we end up deleting the 2994 + * entry with the new priority. Avoid that by checking whether user 2995 + * space wants to delete the priority which is currently configured, or 2996 + * something else which is no longer current. 2997 + */ 2998 + if (ANA_DSCP_CFG_QOS_DSCP_VAL_X(dscp_cfg) != prio) 2999 + return 0; 3000 + 3001 + /* Untrust this DSCP value */ 3002 + ocelot_write_rix(ocelot, 0, ANA_DSCP_CFG, dscp); 3003 + 3004 + for (i = 0; i < 64; i++) { 3005 + int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, i); 3006 + 3007 + /* There are still app table entries on the port, so we need to 3008 + * keep DSCP enabled, nothing to do. 3009 + */ 3010 + if (dscp_cfg & ANA_DSCP_CFG_DSCP_TRUST_ENA) 3011 + return 0; 3012 + } 3013 + 3014 + /* Disable DSCP QoS classification if there isn't any trusted 3015 + * DSCP value left. 3016 + */ 3017 + mask = ANA_PORT_QOS_CFG_QOS_DSCP_ENA | 3018 + ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA; 3019 + 3020 + ocelot_rmw_gix(ocelot, 0, mask, ANA_PORT_QOS_CFG, port); 3021 + 3022 + return 0; 3023 + } 3024 + EXPORT_SYMBOL_GPL(ocelot_port_del_dscp_prio); 3025 + 2910 3026 void ocelot_init_port(struct ocelot *ocelot, int port) 2911 3027 { 2912 3028 struct ocelot_port *ocelot_port = ocelot->ports[port];
+12
include/net/dsa.h
··· 893 893 struct ethtool_ts_info *ts); 894 894 895 895 /* 896 + * DCB ops 897 + */ 898 + int (*port_get_default_prio)(struct dsa_switch *ds, int port); 899 + int (*port_set_default_prio)(struct dsa_switch *ds, int port, 900 + u8 prio); 901 + int (*port_get_dscp_prio)(struct dsa_switch *ds, int port, u8 dscp); 902 + int (*port_add_dscp_prio)(struct dsa_switch *ds, int port, u8 dscp, 903 + u8 prio); 904 + int (*port_del_dscp_prio)(struct dsa_switch *ds, int port, u8 dscp, 905 + u8 prio); 906 + 907 + /* 896 908 * Suspend and resume 897 909 */ 898 910 int (*suspend)(struct dsa_switch *ds);
+5
include/soc/mscc/ocelot.h
··· 869 869 struct switchdev_brport_flags val); 870 870 void ocelot_port_bridge_flags(struct ocelot *ocelot, int port, 871 871 struct switchdev_brport_flags val); 872 + int ocelot_port_get_default_prio(struct ocelot *ocelot, int port); 873 + int ocelot_port_set_default_prio(struct ocelot *ocelot, int port, u8 prio); 874 + int ocelot_port_get_dscp_prio(struct ocelot *ocelot, int port, u8 dscp); 875 + int ocelot_port_add_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio); 876 + int ocelot_port_del_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio); 872 877 int ocelot_port_bridge_join(struct ocelot *ocelot, int port, 873 878 struct net_device *bridge, int bridge_num, 874 879 struct netlink_ext_ack *extack);
+223
net/dsa/slave.c
··· 19 19 #include <net/tc_act/tc_mirred.h> 20 20 #include <linux/if_bridge.h> 21 21 #include <linux/if_hsr.h> 22 + #include <net/dcbnl.h> 22 23 #include <linux/netpoll.h> 23 24 24 25 #include "dsa_priv.h" ··· 1853 1852 return err; 1854 1853 } 1855 1854 1855 + static int __maybe_unused 1856 + dsa_slave_dcbnl_set_default_prio(struct net_device *dev, struct dcb_app *app) 1857 + { 1858 + struct dsa_port *dp = dsa_slave_to_port(dev); 1859 + struct dsa_switch *ds = dp->ds; 1860 + unsigned long mask, new_prio; 1861 + int err, port = dp->index; 1862 + 1863 + if (!ds->ops->port_set_default_prio) 1864 + return -EOPNOTSUPP; 1865 + 1866 + err = dcb_ieee_setapp(dev, app); 1867 + if (err) 1868 + return err; 1869 + 1870 + mask = dcb_ieee_getapp_mask(dev, app); 1871 + new_prio = __fls(mask); 1872 + 1873 + err = ds->ops->port_set_default_prio(ds, port, new_prio); 1874 + if (err) { 1875 + dcb_ieee_delapp(dev, app); 1876 + return err; 1877 + } 1878 + 1879 + return 0; 1880 + } 1881 + 1882 + static int __maybe_unused 1883 + dsa_slave_dcbnl_add_dscp_prio(struct net_device *dev, struct dcb_app *app) 1884 + { 1885 + struct dsa_port *dp = dsa_slave_to_port(dev); 1886 + struct dsa_switch *ds = dp->ds; 1887 + unsigned long mask, new_prio; 1888 + int err, port = dp->index; 1889 + u8 dscp = app->protocol; 1890 + 1891 + if (!ds->ops->port_add_dscp_prio) 1892 + return -EOPNOTSUPP; 1893 + 1894 + if (dscp >= 64) { 1895 + netdev_err(dev, "DSCP APP entry with protocol value %u is invalid\n", 1896 + dscp); 1897 + return -EINVAL; 1898 + } 1899 + 1900 + err = dcb_ieee_setapp(dev, app); 1901 + if (err) 1902 + return err; 1903 + 1904 + mask = dcb_ieee_getapp_mask(dev, app); 1905 + new_prio = __fls(mask); 1906 + 1907 + err = ds->ops->port_add_dscp_prio(ds, port, dscp, new_prio); 1908 + if (err) { 1909 + dcb_ieee_delapp(dev, app); 1910 + return err; 1911 + } 1912 + 1913 + return 0; 1914 + } 1915 + 1916 + static int __maybe_unused dsa_slave_dcbnl_ieee_setapp(struct net_device *dev, 1917 + struct dcb_app *app) 1918 + { 1919 + switch (app->selector) { 1920 + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: 1921 + switch (app->protocol) { 1922 + case 0: 1923 + return dsa_slave_dcbnl_set_default_prio(dev, app); 1924 + default: 1925 + return -EOPNOTSUPP; 1926 + } 1927 + break; 1928 + case IEEE_8021QAZ_APP_SEL_DSCP: 1929 + return dsa_slave_dcbnl_add_dscp_prio(dev, app); 1930 + default: 1931 + return -EOPNOTSUPP; 1932 + } 1933 + } 1934 + 1935 + static int __maybe_unused 1936 + dsa_slave_dcbnl_del_default_prio(struct net_device *dev, struct dcb_app *app) 1937 + { 1938 + struct dsa_port *dp = dsa_slave_to_port(dev); 1939 + struct dsa_switch *ds = dp->ds; 1940 + unsigned long mask, new_prio; 1941 + int err, port = dp->index; 1942 + 1943 + if (!ds->ops->port_set_default_prio) 1944 + return -EOPNOTSUPP; 1945 + 1946 + err = dcb_ieee_delapp(dev, app); 1947 + if (err) 1948 + return err; 1949 + 1950 + mask = dcb_ieee_getapp_mask(dev, app); 1951 + new_prio = mask ? __fls(mask) : 0; 1952 + 1953 + err = ds->ops->port_set_default_prio(ds, port, new_prio); 1954 + if (err) { 1955 + dcb_ieee_setapp(dev, app); 1956 + return err; 1957 + } 1958 + 1959 + return 0; 1960 + } 1961 + 1962 + static int __maybe_unused 1963 + dsa_slave_dcbnl_del_dscp_prio(struct net_device *dev, struct dcb_app *app) 1964 + { 1965 + struct dsa_port *dp = dsa_slave_to_port(dev); 1966 + struct dsa_switch *ds = dp->ds; 1967 + int err, port = dp->index; 1968 + u8 dscp = app->protocol; 1969 + 1970 + if (!ds->ops->port_del_dscp_prio) 1971 + return -EOPNOTSUPP; 1972 + 1973 + err = dcb_ieee_delapp(dev, app); 1974 + if (err) 1975 + return err; 1976 + 1977 + err = ds->ops->port_del_dscp_prio(ds, port, dscp, app->priority); 1978 + if (err) { 1979 + dcb_ieee_setapp(dev, app); 1980 + return err; 1981 + } 1982 + 1983 + return 0; 1984 + } 1985 + 1986 + static int __maybe_unused dsa_slave_dcbnl_ieee_delapp(struct net_device *dev, 1987 + struct dcb_app *app) 1988 + { 1989 + switch (app->selector) { 1990 + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: 1991 + switch (app->protocol) { 1992 + case 0: 1993 + return dsa_slave_dcbnl_del_default_prio(dev, app); 1994 + default: 1995 + return -EOPNOTSUPP; 1996 + } 1997 + break; 1998 + case IEEE_8021QAZ_APP_SEL_DSCP: 1999 + return dsa_slave_dcbnl_del_dscp_prio(dev, app); 2000 + default: 2001 + return -EOPNOTSUPP; 2002 + } 2003 + } 2004 + 2005 + /* Pre-populate the DCB application priority table with the priorities 2006 + * configured during switch setup, which we read from hardware here. 2007 + */ 2008 + static int dsa_slave_dcbnl_init(struct net_device *dev) 2009 + { 2010 + struct dsa_port *dp = dsa_slave_to_port(dev); 2011 + struct dsa_switch *ds = dp->ds; 2012 + int port = dp->index; 2013 + int err; 2014 + 2015 + if (ds->ops->port_get_default_prio) { 2016 + int prio = ds->ops->port_get_default_prio(ds, port); 2017 + struct dcb_app app = { 2018 + .selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE, 2019 + .protocol = 0, 2020 + .priority = prio, 2021 + }; 2022 + 2023 + if (prio < 0) 2024 + return prio; 2025 + 2026 + err = dcb_ieee_setapp(dev, &app); 2027 + if (err) 2028 + return err; 2029 + } 2030 + 2031 + if (ds->ops->port_get_dscp_prio) { 2032 + int protocol; 2033 + 2034 + for (protocol = 0; protocol < 64; protocol++) { 2035 + struct dcb_app app = { 2036 + .selector = IEEE_8021QAZ_APP_SEL_DSCP, 2037 + .protocol = protocol, 2038 + }; 2039 + int prio; 2040 + 2041 + prio = ds->ops->port_get_dscp_prio(ds, port, protocol); 2042 + if (prio == -EOPNOTSUPP) 2043 + continue; 2044 + if (prio < 0) 2045 + return prio; 2046 + 2047 + app.priority = prio; 2048 + 2049 + err = dcb_ieee_setapp(dev, &app); 2050 + if (err) 2051 + return err; 2052 + } 2053 + } 2054 + 2055 + return 0; 2056 + } 2057 + 1856 2058 static const struct ethtool_ops dsa_slave_ethtool_ops = { 1857 2059 .get_drvinfo = dsa_slave_get_drvinfo, 1858 2060 .get_regs_len = dsa_slave_get_regs_len, ··· 2083 1879 .set_rxnfc = dsa_slave_set_rxnfc, 2084 1880 .get_ts_info = dsa_slave_get_ts_info, 2085 1881 .self_test = dsa_slave_net_selftest, 1882 + }; 1883 + 1884 + static const struct dcbnl_rtnl_ops __maybe_unused dsa_slave_dcbnl_ops = { 1885 + .ieee_setapp = dsa_slave_dcbnl_ieee_setapp, 1886 + .ieee_delapp = dsa_slave_dcbnl_ieee_delapp, 2086 1887 }; 2087 1888 2088 1889 static struct devlink_port *dsa_slave_get_devlink_port(struct net_device *dev) ··· 2314 2105 return -ENOMEM; 2315 2106 2316 2107 slave_dev->ethtool_ops = &dsa_slave_ethtool_ops; 2108 + #if IS_ENABLED(CONFIG_DCB) 2109 + slave_dev->dcbnl_ops = &dsa_slave_dcbnl_ops; 2110 + #endif 2317 2111 if (!is_zero_ether_addr(port->mac)) 2318 2112 eth_hw_addr_set(slave_dev, port->mac); 2319 2113 else ··· 2372 2160 ret, slave_dev->name); 2373 2161 rtnl_unlock(); 2374 2162 goto out_phy; 2163 + } 2164 + 2165 + if (IS_ENABLED(CONFIG_DCB)) { 2166 + ret = dsa_slave_dcbnl_init(slave_dev); 2167 + if (ret) { 2168 + netdev_err(slave_dev, 2169 + "failed to initialize DCB: %pe\n", 2170 + ERR_PTR(ret)); 2171 + rtnl_unlock(); 2172 + goto out_unregister; 2173 + } 2375 2174 } 2376 2175 2377 2176 ret = netdev_upper_dev_link(master, slave_dev, NULL);