Skip to content

Commit 2c68d5e

Browse files
committed
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2026-01-13 (ice, igc) For ice: Jake adds missing initialization calls to u64_stats_init(). Dave stops deletion of VLAN 0 from prune list when device is primary LAG interface. Ding Hui adds a missed unit conversion function for proper timeout value. For igc: Kurt Kanzenbach adds a call to re-set default Qbv schedule when number of channels changes. Chwee-Lin Choong reworks Tx timestamp detection logic to resolve a race condition and reverts changes to TSN packet buffer size causing Tx hangs under heavy load. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: igc: Reduce TSN TX packet buffer from 7KB to 5KB per queue igc: fix race condition in TX timestamp read for register 0 igc: Restore default Qbv schedule when changing channels ice: Fix incorrect timeout ice_release_res() ice: Avoid detrimental cleanup for bond during interface stop ice: initialize ring_stats->syncp ==================== Link: https://patch.msgid.link/20260113220220.1034638-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 4f5f148 + 8ad1b6c commit 2c68d5e

6 files changed

Lines changed: 57 additions & 31 deletions

File tree

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
22512251
/* there are some rare cases when trying to release the resource
22522252
* results in an admin queue timeout, so handle them correctly
22532253
*/
2254-
timeout = jiffies + 10 * ICE_CTL_Q_SQ_CMD_TIMEOUT;
2254+
timeout = jiffies + 10 * usecs_to_jiffies(ICE_CTL_Q_SQ_CMD_TIMEOUT);
22552255
do {
22562256
status = ice_aq_release_res(hw, res, 0, NULL);
22572257
if (status != -EIO)

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi)
398398
if (!ring_stats)
399399
goto err_out;
400400

401+
u64_stats_init(&ring_stats->syncp);
402+
401403
WRITE_ONCE(tx_ring_stats[i], ring_stats);
402404
}
403405

@@ -417,6 +419,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi)
417419
if (!ring_stats)
418420
goto err_out;
419421

422+
u64_stats_init(&ring_stats->syncp);
423+
420424
WRITE_ONCE(rx_ring_stats[i], ring_stats);
421425
}
422426

@@ -3805,22 +3809,31 @@ int ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
38053809
int ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
38063810
{
38073811
struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
3812+
struct ice_pf *pf = vsi->back;
38083813
struct ice_vlan vlan;
38093814
int err;
38103815

3811-
vlan = ICE_VLAN(0, 0, 0);
3812-
err = vlan_ops->del_vlan(vsi, &vlan);
3813-
if (err && err != -EEXIST)
3814-
return err;
3816+
if (pf->lag && pf->lag->primary) {
3817+
dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting prune list\n");
3818+
} else {
3819+
vlan = ICE_VLAN(0, 0, 0);
3820+
err = vlan_ops->del_vlan(vsi, &vlan);
3821+
if (err && err != -EEXIST)
3822+
return err;
3823+
}
38153824

38163825
/* in SVM both VLAN 0 filters are identical */
38173826
if (!ice_is_dvm_ena(&vsi->back->hw))
38183827
return 0;
38193828

3820-
vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
3821-
err = vlan_ops->del_vlan(vsi, &vlan);
3822-
if (err && err != -EEXIST)
3823-
return err;
3829+
if (pf->lag && pf->lag->primary) {
3830+
dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting QinQ prune list\n");
3831+
} else {
3832+
vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
3833+
err = vlan_ops->del_vlan(vsi, &vlan);
3834+
if (err && err != -EEXIST)
3835+
return err;
3836+
}
38243837

38253838
/* when deleting the last VLAN filter, make sure to disable the VLAN
38263839
* promisc mode so the filter isn't left by accident

drivers/net/ethernet/intel/igc/igc_defines.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,10 @@
443443
#define IGC_TXPBSIZE_DEFAULT ( \
444444
IGC_TXPB0SIZE(20) | IGC_TXPB1SIZE(0) | IGC_TXPB2SIZE(0) | \
445445
IGC_TXPB3SIZE(0) | IGC_OS2BMCPBSIZE(4))
446+
/* TSN value following I225/I226 SW User Manual Section 7.5.4 */
446447
#define IGC_TXPBSIZE_TSN ( \
447-
IGC_TXPB0SIZE(7) | IGC_TXPB1SIZE(7) | IGC_TXPB2SIZE(7) | \
448-
IGC_TXPB3SIZE(7) | IGC_OS2BMCPBSIZE(4))
448+
IGC_TXPB0SIZE(5) | IGC_TXPB1SIZE(5) | IGC_TXPB2SIZE(5) | \
449+
IGC_TXPB3SIZE(5) | IGC_OS2BMCPBSIZE(4))
449450

450451
#define IGC_DTXMXPKTSZ_TSN 0x19 /* 1600 bytes of max TX DMA packet size */
451452
#define IGC_DTXMXPKTSZ_DEFAULT 0x98 /* 9728-byte Jumbo frames */

drivers/net/ethernet/intel/igc/igc_ethtool.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,8 +1565,8 @@ static int igc_ethtool_set_channels(struct net_device *netdev,
15651565
if (ch->other_count != NON_Q_VECTORS)
15661566
return -EINVAL;
15671567

1568-
/* Do not allow channel reconfiguration when mqprio is enabled */
1569-
if (adapter->strict_priority_enable)
1568+
/* Do not allow channel reconfiguration when any TSN qdisc is enabled */
1569+
if (adapter->flags & IGC_FLAG_TSN_ANY_ENABLED)
15701570
return -EINVAL;
15711571

15721572
/* Verify the number of channels doesn't exceed hw limits */

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7759,6 +7759,11 @@ int igc_reinit_queues(struct igc_adapter *adapter)
77597759
if (netif_running(netdev))
77607760
err = igc_open(netdev);
77617761

7762+
if (!err) {
7763+
/* Restore default IEEE 802.1Qbv schedule after queue reinit */
7764+
igc_tsn_clear_schedule(adapter);
7765+
}
7766+
77627767
return err;
77637768
}
77647769

drivers/net/ethernet/intel/igc/igc_ptp.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -774,36 +774,43 @@ static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter,
774774
static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
775775
{
776776
struct igc_hw *hw = &adapter->hw;
777+
u32 txstmpl_old;
777778
u64 regval;
778779
u32 mask;
779780
int i;
780781

782+
/* Establish baseline of TXSTMPL_0 before checking TXTT_0.
783+
* This baseline is used to detect if a new timestamp arrives in
784+
* register 0 during the hardware bug workaround below.
785+
*/
786+
txstmpl_old = rd32(IGC_TXSTMPL);
787+
781788
mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY;
782789
if (mask & IGC_TSYNCTXCTL_TXTT_0) {
783790
regval = rd32(IGC_TXSTMPL);
784791
regval |= (u64)rd32(IGC_TXSTMPH) << 32;
785792
} else {
786-
/* There's a bug in the hardware that could cause
787-
* missing interrupts for TX timestamping. The issue
788-
* is that for new interrupts to be triggered, the
789-
* IGC_TXSTMPH_0 register must be read.
793+
/* TXTT_0 not set - register 0 has no new timestamp initially.
794+
*
795+
* Hardware bug: Future timestamp interrupts won't fire unless
796+
* TXSTMPH_0 is read, even if the timestamp was captured in
797+
* registers 1-3.
790798
*
791-
* To avoid discarding a valid timestamp that just
792-
* happened at the "wrong" time, we need to confirm
793-
* that there was no timestamp captured, we do that by
794-
* assuming that no two timestamps in sequence have
795-
* the same nanosecond value.
799+
* Workaround: Read TXSTMPH_0 here to enable future interrupts.
800+
* However, this read clears TXTT_0. If a timestamp arrives in
801+
* register 0 after checking TXTT_0 but before this read, it
802+
* would be lost.
796803
*
797-
* So, we read the "low" register, read the "high"
798-
* register (to latch a new timestamp) and read the
799-
* "low" register again, if "old" and "new" versions
800-
* of the "low" register are different, a valid
801-
* timestamp was captured, we can read the "high"
802-
* register again.
804+
* To detect this race: We saved a baseline read of TXSTMPL_0
805+
* before TXTT_0 check. After performing the workaround read of
806+
* TXSTMPH_0, we read TXSTMPL_0 again. Since consecutive
807+
* timestamps never share the same nanosecond value, a change
808+
* between the baseline and new TXSTMPL_0 indicates a timestamp
809+
* arrived during the race window. If so, read the complete
810+
* timestamp.
803811
*/
804-
u32 txstmpl_old, txstmpl_new;
812+
u32 txstmpl_new;
805813

806-
txstmpl_old = rd32(IGC_TXSTMPL);
807814
rd32(IGC_TXSTMPH);
808815
txstmpl_new = rd32(IGC_TXSTMPL);
809816

@@ -818,7 +825,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
818825

819826
done:
820827
/* Now that the problematic first register was handled, we can
821-
* use retrieve the timestamps from the other registers
828+
* retrieve the timestamps from the other registers
822829
* (starting from '1') with less complications.
823830
*/
824831
for (i = 1; i < IGC_MAX_TX_TSTAMP_REGS; i++) {

0 commit comments

Comments
 (0)