Patch "net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-mscc-ocelot-fix-qos-class-for-injected-packets-w.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit a35e5915d7b0e66ae25b7d1c0afd10e5bc013093
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Thu Aug 15 03:07:03 2024 +0300

    net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"
    
    [ Upstream commit e1b9e80236c540fa85d76e2d510d1b38e1968c5d ]
    
    There are 2 distinct code paths (listed below) in the source code which
    set up an injection header for Ocelot(-like) switches. Code path (2)
    lacks the QoS class and source port being set correctly. Especially the
    improper QoS classification is a problem for the "ocelot-8021q"
    alternative DSA tagging protocol, because we support tc-taprio and each
    packet needs to be scheduled precisely through its time slot. This
    includes PTP, which is normally assigned to a traffic class other than
    0, but would be sent through TC 0 nonetheless.
    
    The code paths are:
    
    (1) ocelot_xmit_common() from net/dsa/tag_ocelot.c - called only by the
        standard "ocelot" DSA tagging protocol which uses NPI-based
        injection - sets up bit fields in the tag manually to account for
        a small difference (destination port offset) between Ocelot and
        Seville. Namely, ocelot_ifh_set_dest() is omitted out of
        ocelot_xmit_common(), because there's also seville_ifh_set_dest().
    
    (2) ocelot_ifh_set_basic(), called by:
        - ocelot_fdma_prepare_skb() for FDMA transmission of the ocelot
          switchdev driver
        - ocelot_port_xmit() -> ocelot_port_inject_frame() for
          register-based transmission of the ocelot switchdev driver
        - felix_port_deferred_xmit() -> ocelot_port_inject_frame() for the
          DSA tagger ocelot-8021q when it must transmit PTP frames (also
          through register-based injection).
        sets the bit fields according to its own logic.
    
    The problem is that (2) doesn't call ocelot_ifh_set_qos_class().
    Copying that logic from ocelot_xmit_common() fixes that.
    
    Unfortunately, although desirable, it is not easily possible to
    de-duplicate code paths (1) and (2), and make net/dsa/tag_ocelot.c
    directly call ocelot_ifh_set_basic()), because of the ocelot/seville
    difference. This is the "minimal" fix with some logic duplicated (but
    at least more consolidated).
    
    Fixes: 0a6f17c6ae21 ("net: dsa: tag_ocelot_8021q: add support for PTP timestamping")
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index c739124b394b5..4e01abf6cc72c 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1208,13 +1208,21 @@ void ocelot_ifh_set_basic(void *ifh, struct ocelot *ocelot, int port,
 			  u32 rew_op, struct sk_buff *skb)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
+	struct net_device *dev = skb->dev;
 	u64 vlan_tci, tag_type;
+	int qos_class;
 
 	ocelot_xmit_get_vlan_info(skb, ocelot_port->bridge, &vlan_tci,
 				  &tag_type);
 
+	qos_class = netdev_get_num_tc(dev) ?
+		    netdev_get_prio_tc_map(dev, skb->priority) : skb->priority;
+
+	memset(ifh, 0, OCELOT_TAG_LEN);
 	ocelot_ifh_set_bypass(ifh, 1);
+	ocelot_ifh_set_src(ifh, BIT_ULL(ocelot->num_phys_ports));
 	ocelot_ifh_set_dest(ifh, BIT_ULL(port));
+	ocelot_ifh_set_qos_class(ifh, qos_class);
 	ocelot_ifh_set_tag_type(ifh, tag_type);
 	ocelot_ifh_set_vlan_tci(ifh, vlan_tci);
 	if (rew_op)
@@ -1225,7 +1233,7 @@ EXPORT_SYMBOL(ocelot_ifh_set_basic);
 void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp,
 			      u32 rew_op, struct sk_buff *skb)
 {
-	u32 ifh[OCELOT_TAG_LEN / 4] = {0};
+	u32 ifh[OCELOT_TAG_LEN / 4];
 	unsigned int i, count, last;
 
 	ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
diff --git a/drivers/net/ethernet/mscc/ocelot_fdma.c b/drivers/net/ethernet/mscc/ocelot_fdma.c
index 87b59cc5e4416..00326ae8c708b 100644
--- a/drivers/net/ethernet/mscc/ocelot_fdma.c
+++ b/drivers/net/ethernet/mscc/ocelot_fdma.c
@@ -665,7 +665,6 @@ static int ocelot_fdma_prepare_skb(struct ocelot *ocelot, int port, u32 rew_op,
 
 	ifh = skb_push(skb, OCELOT_TAG_LEN);
 	skb_put(skb, ETH_FCS_LEN);
-	memset(ifh, 0, OCELOT_TAG_LEN);
 	ocelot_ifh_set_basic(ifh, ocelot, port, rew_op, skb);
 
 	return 0;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux