]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
igc: Restore default Qbv schedule when changing channels
authorKurt Kanzenbach <kurt@linutronix.de>
Thu, 20 Nov 2025 08:18:29 +0000 (09:18 +0100)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 13 Jan 2026 19:18:34 +0000 (11:18 -0800)
The Multi-queue Priority (MQPRIO) and Earliest TxTime First (ETF) offloads
utilize the Time Sensitive Networking (TSN) Tx mode. This mode is always
coupled to IEEE 802.1Qbv time aware shaper (Qbv). Therefore, the driver
sets a default Qbv schedule of all gates opened and a cycle time of
1s. This schedule is set during probe.

However, the following sequence of events lead to Tx issues:

 - Boot a dual core system
   igc_probe():
     igc_tsn_clear_schedule():
       -> Default Schedule is set
       Note: At this point the driver has allocated two Tx/Rx queues, because
       there are only two CPUs.

 - ethtool -L enp3s0 combined 4
   igc_ethtool_set_channels():
     igc_reinit_queues()
       -> Default schedule is gone, per Tx ring start and end time are zero

  - tc qdisc replace dev enp3s0 handle 100 parent root mqprio \
      num_tc 4 map 3 3 2 2 0 1 1 1 3 3 3 3 3 3 3 3 \
      queues 1@0 1@1 1@2 1@3 hw 1
    igc_tsn_offload_apply():
      igc_tsn_enable_offload():
        -> Writes zeros to IGC_STQT(i) and IGC_ENDQT(i), causing Tx to stall/fail

Therefore, restore the default Qbv schedule after changing the number of
channels.

Furthermore, add a restriction to not allow queue reconfiguration when
TSN/Qbv is enabled, because it may lead to inconsistent states.

Fixes: c814a2d2d48f ("igc: Use default cycle 'start' and 'end' values for queues")
Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/igc/igc_ethtool.c
drivers/net/ethernet/intel/igc/igc_main.c

index e94c1922b97af0a21beb6c872e1438f0ae0674c9..3172cdbca9ccdd21ec497c957a2552506d040ba4 100644 (file)
@@ -1565,8 +1565,8 @@ static int igc_ethtool_set_channels(struct net_device *netdev,
        if (ch->other_count != NON_Q_VECTORS)
                return -EINVAL;
 
-       /* Do not allow channel reconfiguration when mqprio is enabled */
-       if (adapter->strict_priority_enable)
+       /* Do not allow channel reconfiguration when any TSN qdisc is enabled */
+       if (adapter->flags & IGC_FLAG_TSN_ANY_ENABLED)
                return -EINVAL;
 
        /* Verify the number of channels doesn't exceed hw limits */
index 7aafa60ba0c86bd135b1961fdff06c7566d2e80c..89a321a344d263ace5c66f7ade782b40cc482566 100644 (file)
@@ -7759,6 +7759,11 @@ int igc_reinit_queues(struct igc_adapter *adapter)
        if (netif_running(netdev))
                err = igc_open(netdev);
 
+       if (!err) {
+               /* Restore default IEEE 802.1Qbv schedule after queue reinit */
+               igc_tsn_clear_schedule(adapter);
+       }
+
        return err;
 }