Skip to content

Commit 79987ce

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-30 (ice, i40e) This series contains updates to ice and i40e drivers. Grzegorz and Jake resolve issues around timing for E825 that can cause Tx timestamps to be missed/interrupts not generated on ice. Aaron Ma defers restart of PTP work until after after VSIs are rebuilt to prevent NULL pointer dereference for ice. Mohammad Heib removes calls to udp_tunnel_get_rx_info() in ice and i40e which violates locking expectations and is unneeded. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: i40e: drop udp_tunnel_get_rx_info() call from i40e_open() ice: drop udp_tunnel_get_rx_info() call from ndo_open() ice: Fix PTP NULL pointer dereference during VSI rebuild ice: PTP: fix missing timestamps on E825 hardware ice: fix missing TX timestamps interrupts on E825 devices ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents d9f5824 + 4085719 commit 79987ce

4 files changed

Lines changed: 136 additions & 88 deletions

File tree

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9030,7 +9030,6 @@ int i40e_open(struct net_device *netdev)
90309030
TCP_FLAG_FIN |
90319031
TCP_FLAG_CWR) >> 16);
90329032
wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
9033-
udp_tunnel_get_rx_info(netdev);
90349033

90359034
return 0;
90369035
}

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

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,18 +3314,20 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
33143314
if (ice_is_reset_in_progress(pf->state))
33153315
goto skip_irq;
33163316

3317-
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
3318-
/* Process outstanding Tx timestamps. If there is more work,
3319-
* re-arm the interrupt to trigger again.
3320-
*/
3321-
if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) {
3322-
wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
3323-
ice_flush(hw);
3324-
}
3325-
}
3317+
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread))
3318+
ice_ptp_process_ts(pf);
33263319

33273320
skip_irq:
33283321
ice_irq_dynamic_ena(hw, NULL, NULL);
3322+
ice_flush(hw);
3323+
3324+
if (ice_ptp_tx_tstamps_pending(pf)) {
3325+
/* If any new Tx timestamps happened while in interrupt,
3326+
* re-arm the interrupt to trigger it again.
3327+
*/
3328+
wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
3329+
ice_flush(hw);
3330+
}
33293331

33303332
return IRQ_HANDLED;
33313333
}
@@ -7807,6 +7809,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
78077809

78087810
/* Restore timestamp mode settings after VSI rebuild */
78097811
ice_ptp_restore_timestamp_mode(pf);
7812+
7813+
/* Start PTP periodic work after VSI is fully rebuilt */
7814+
ice_ptp_queue_work(pf);
78107815
return;
78117816

78127817
err_vsi_rebuild:
@@ -9657,9 +9662,6 @@ int ice_open_internal(struct net_device *netdev)
96579662
netdev_err(netdev, "Failed to open VSI 0x%04X on switch 0x%04X\n",
96589663
vsi->vsi_num, vsi->vsw->sw_id);
96599664

9660-
/* Update existing tunnels information */
9661-
udp_tunnel_get_rx_info(netdev);
9662-
96639665
return err;
96649666
}
96659667

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

Lines changed: 109 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
573573
pf = ptp_port_to_pf(ptp_port);
574574
hw = &pf->hw;
575575

576+
if (!tx->init)
577+
return;
578+
576579
/* Read the Tx ready status first */
577580
if (tx->has_ready_bitmap) {
578581
err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
@@ -674,14 +677,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
674677
pf->ptp.tx_hwtstamp_good += tstamp_good;
675678
}
676679

677-
/**
678-
* ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device
679-
* @pf: Board private structure
680-
*/
681-
static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
680+
static void ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
682681
{
683682
struct ice_ptp_port *port;
684-
unsigned int i;
685683

686684
mutex_lock(&pf->adapter->ports.lock);
687685
list_for_each_entry(port, &pf->adapter->ports.ports, list_node) {
@@ -693,49 +691,6 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
693691
ice_ptp_process_tx_tstamp(tx);
694692
}
695693
mutex_unlock(&pf->adapter->ports.lock);
696-
697-
for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
698-
u64 tstamp_ready;
699-
int err;
700-
701-
/* Read the Tx ready status first */
702-
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
703-
if (err)
704-
break;
705-
else if (tstamp_ready)
706-
return ICE_TX_TSTAMP_WORK_PENDING;
707-
}
708-
709-
return ICE_TX_TSTAMP_WORK_DONE;
710-
}
711-
712-
/**
713-
* ice_ptp_tx_tstamp - Process Tx timestamps for this function.
714-
* @tx: Tx tracking structure to initialize
715-
*
716-
* Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding incomplete
717-
* Tx timestamps, or ICE_TX_TSTAMP_WORK_DONE otherwise.
718-
*/
719-
static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
720-
{
721-
bool more_timestamps;
722-
unsigned long flags;
723-
724-
if (!tx->init)
725-
return ICE_TX_TSTAMP_WORK_DONE;
726-
727-
/* Process the Tx timestamp tracker */
728-
ice_ptp_process_tx_tstamp(tx);
729-
730-
/* Check if there are outstanding Tx timestamps */
731-
spin_lock_irqsave(&tx->lock, flags);
732-
more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len);
733-
spin_unlock_irqrestore(&tx->lock, flags);
734-
735-
if (more_timestamps)
736-
return ICE_TX_TSTAMP_WORK_PENDING;
737-
738-
return ICE_TX_TSTAMP_WORK_DONE;
739694
}
740695

741696
/**
@@ -1347,9 +1302,12 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
13471302
/* Do not reconfigure E810 or E830 PHY */
13481303
return;
13491304
case ICE_MAC_GENERIC:
1350-
case ICE_MAC_GENERIC_3K_E825:
13511305
ice_ptp_port_phy_restart(ptp_port);
13521306
return;
1307+
case ICE_MAC_GENERIC_3K_E825:
1308+
if (linkup)
1309+
ice_ptp_port_phy_restart(ptp_port);
1310+
return;
13531311
default:
13541312
dev_warn(ice_pf_to_dev(pf), "%s: Unknown PHY type\n", __func__);
13551313
}
@@ -2663,30 +2621,92 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
26632621
return idx + tx->offset;
26642622
}
26652623

2666-
/**
2667-
* ice_ptp_process_ts - Process the PTP Tx timestamps
2668-
* @pf: Board private structure
2669-
*
2670-
* Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding Tx
2671-
* timestamps that need processing, and ICE_TX_TSTAMP_WORK_DONE otherwise.
2672-
*/
2673-
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
2624+
void ice_ptp_process_ts(struct ice_pf *pf)
26742625
{
26752626
switch (pf->ptp.tx_interrupt_mode) {
26762627
case ICE_PTP_TX_INTERRUPT_NONE:
26772628
/* This device has the clock owner handle timestamps for it */
2678-
return ICE_TX_TSTAMP_WORK_DONE;
2629+
return;
26792630
case ICE_PTP_TX_INTERRUPT_SELF:
26802631
/* This device handles its own timestamps */
2681-
return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
2632+
ice_ptp_process_tx_tstamp(&pf->ptp.port.tx);
2633+
return;
26822634
case ICE_PTP_TX_INTERRUPT_ALL:
26832635
/* This device handles timestamps for all ports */
2684-
return ice_ptp_tx_tstamp_owner(pf);
2636+
ice_ptp_tx_tstamp_owner(pf);
2637+
return;
2638+
default:
2639+
WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n",
2640+
pf->ptp.tx_interrupt_mode);
2641+
return;
2642+
}
2643+
}
2644+
2645+
static bool ice_port_has_timestamps(struct ice_ptp_tx *tx)
2646+
{
2647+
bool more_timestamps;
2648+
2649+
scoped_guard(spinlock_irqsave, &tx->lock) {
2650+
if (!tx->init)
2651+
return false;
2652+
2653+
more_timestamps = !bitmap_empty(tx->in_use, tx->len);
2654+
}
2655+
2656+
return more_timestamps;
2657+
}
2658+
2659+
static bool ice_any_port_has_timestamps(struct ice_pf *pf)
2660+
{
2661+
struct ice_ptp_port *port;
2662+
2663+
scoped_guard(mutex, &pf->adapter->ports.lock) {
2664+
list_for_each_entry(port, &pf->adapter->ports.ports,
2665+
list_node) {
2666+
struct ice_ptp_tx *tx = &port->tx;
2667+
2668+
if (ice_port_has_timestamps(tx))
2669+
return true;
2670+
}
2671+
}
2672+
2673+
return false;
2674+
}
2675+
2676+
bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
2677+
{
2678+
struct ice_hw *hw = &pf->hw;
2679+
unsigned int i;
2680+
2681+
/* Check software indicator */
2682+
switch (pf->ptp.tx_interrupt_mode) {
2683+
case ICE_PTP_TX_INTERRUPT_NONE:
2684+
return false;
2685+
case ICE_PTP_TX_INTERRUPT_SELF:
2686+
if (ice_port_has_timestamps(&pf->ptp.port.tx))
2687+
return true;
2688+
break;
2689+
case ICE_PTP_TX_INTERRUPT_ALL:
2690+
if (ice_any_port_has_timestamps(pf))
2691+
return true;
2692+
break;
26852693
default:
26862694
WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n",
26872695
pf->ptp.tx_interrupt_mode);
2688-
return ICE_TX_TSTAMP_WORK_DONE;
2696+
break;
2697+
}
2698+
2699+
/* Check hardware indicator */
2700+
for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
2701+
u64 tstamp_ready = 0;
2702+
int err;
2703+
2704+
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
2705+
if (err || tstamp_ready)
2706+
return true;
26892707
}
2708+
2709+
return false;
26902710
}
26912711

26922712
/**
@@ -2738,7 +2758,9 @@ irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf)
27382758
return IRQ_WAKE_THREAD;
27392759
case ICE_MAC_E830:
27402760
/* E830 can read timestamps in the top half using rd32() */
2741-
if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) {
2761+
ice_ptp_process_ts(pf);
2762+
2763+
if (ice_ptp_tx_tstamps_pending(pf)) {
27422764
/* Process outstanding Tx timestamps. If there
27432765
* is more work, re-arm the interrupt to trigger again.
27442766
*/
@@ -2817,6 +2839,20 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
28172839
msecs_to_jiffies(err ? 10 : 500));
28182840
}
28192841

2842+
/**
2843+
* ice_ptp_queue_work - Queue PTP periodic work for a PF
2844+
* @pf: Board private structure
2845+
*
2846+
* Helper function to queue PTP periodic work after VSI rebuild completes.
2847+
* This ensures that PTP work only runs when VSI structures are ready.
2848+
*/
2849+
void ice_ptp_queue_work(struct ice_pf *pf)
2850+
{
2851+
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags) &&
2852+
pf->ptp.state == ICE_PTP_READY)
2853+
kthread_queue_delayed_work(pf->ptp.kworker, &pf->ptp.work, 0);
2854+
}
2855+
28202856
/**
28212857
* ice_ptp_prepare_rebuild_sec - Prepare second NAC for PTP reset or rebuild
28222858
* @pf: Board private structure
@@ -2835,10 +2871,15 @@ static void ice_ptp_prepare_rebuild_sec(struct ice_pf *pf, bool rebuild,
28352871
struct ice_pf *peer_pf = ptp_port_to_pf(port);
28362872

28372873
if (!ice_is_primary(&peer_pf->hw)) {
2838-
if (rebuild)
2874+
if (rebuild) {
2875+
/* TODO: When implementing rebuild=true:
2876+
* 1. Ensure secondary PFs' VSIs are rebuilt
2877+
* 2. Call ice_ptp_queue_work(peer_pf) after VSI rebuild
2878+
*/
28392879
ice_ptp_rebuild(peer_pf, reset_type);
2840-
else
2880+
} else {
28412881
ice_ptp_prepare_for_reset(peer_pf, reset_type);
2882+
}
28422883
}
28432884
}
28442885
}
@@ -2984,9 +3025,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
29843025

29853026
ptp->state = ICE_PTP_READY;
29863027

2987-
/* Start periodic work going */
2988-
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
2989-
29903028
dev_info(ice_pf_to_dev(pf), "PTP reset successful\n");
29913029
return;
29923030

@@ -3191,8 +3229,9 @@ static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
31913229
{
31923230
switch (pf->hw.mac_type) {
31933231
case ICE_MAC_GENERIC:
3194-
/* E822 based PHY has the clock owner process the interrupt
3195-
* for all ports.
3232+
case ICE_MAC_GENERIC_3K_E825:
3233+
/* E82x hardware has the clock owner process timestamps for
3234+
* all ports.
31963235
*/
31973236
if (ice_pf_src_tmr_owned(pf))
31983237
pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL;

drivers/net/ethernet/intel/ice/ice_ptp.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,9 @@ void ice_ptp_extts_event(struct ice_pf *pf);
304304
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
305305
void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx);
306306
void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx);
307-
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
307+
void ice_ptp_process_ts(struct ice_pf *pf);
308308
irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf);
309+
bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf);
309310
u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf,
310311
struct ptp_system_timestamp *sts);
311312

@@ -317,6 +318,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf,
317318
void ice_ptp_init(struct ice_pf *pf);
318319
void ice_ptp_release(struct ice_pf *pf);
319320
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
321+
void ice_ptp_queue_work(struct ice_pf *pf);
320322
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
321323

322324
static inline int ice_ptp_hwtstamp_get(struct net_device *netdev,
@@ -345,16 +347,18 @@ static inline void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
345347

346348
static inline void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { }
347349

348-
static inline bool ice_ptp_process_ts(struct ice_pf *pf)
349-
{
350-
return true;
351-
}
350+
static inline void ice_ptp_process_ts(struct ice_pf *pf) { }
352351

353352
static inline irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf)
354353
{
355354
return IRQ_HANDLED;
356355
}
357356

357+
static inline bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
358+
{
359+
return false;
360+
}
361+
358362
static inline u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf,
359363
struct ptp_system_timestamp *sts)
360364
{
@@ -383,6 +387,10 @@ static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
383387
{
384388
}
385389

390+
static inline void ice_ptp_queue_work(struct ice_pf *pf)
391+
{
392+
}
393+
386394
static inline int ice_ptp_clock_index(struct ice_pf *pf)
387395
{
388396
return -1;

0 commit comments

Comments
 (0)