Skip to content

Commit aa125f0

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 2025-08-25 (ice, ixgbe) For ice: Emil adds a check to ensure auxiliary device was created before tear down to prevent NULL a pointer dereference. Jake reworks flow for failed Tx scheduler configuration to allow for proper recovery and operation. He also adjusts ice_adapter index for E825C devices as use of DSN is incompatible with this device. Michal corrects tracking of buffer allocation failure in ice_clean_rx_irq(). For ixgbe: Jedrzej adds __packed attribute to ixgbe_orom_civd_info to compatibility with device OROM data. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: ixgbe: fix ixgbe_orom_civd_info struct layout ice: fix incorrect counter for buffer allocation failures ice: use fixed adapter index for E825C embedded devices ice: don't leave device non-functional if Tx scheduler config fails ice: fix NULL pointer dereference in ice_unplug_aux_dev() on reset ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents e69880c + ed913b3 commit aa125f0

File tree

9 files changed

+93
-37
lines changed

9 files changed

+93
-37
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ enum ice_pf_flags {
510510
ICE_FLAG_LINK_LENIENT_MODE_ENA,
511511
ICE_FLAG_PLUG_AUX_DEV,
512512
ICE_FLAG_UNPLUG_AUX_DEV,
513+
ICE_FLAG_AUX_DEV_CREATED,
513514
ICE_FLAG_MTU_CHANGED,
514515
ICE_FLAG_GNSS, /* GNSS successfully initialized */
515516
ICE_FLAG_DPLL, /* SyncE/PTP dplls initialized */

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

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,53 @@
1313
static DEFINE_XARRAY(ice_adapters);
1414
static DEFINE_MUTEX(ice_adapters_mutex);
1515

16-
static unsigned long ice_adapter_index(u64 dsn)
16+
#define ICE_ADAPTER_FIXED_INDEX BIT_ULL(63)
17+
18+
#define ICE_ADAPTER_INDEX_E825C \
19+
(ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
20+
21+
static u64 ice_adapter_index(struct pci_dev *pdev)
1722
{
23+
switch (pdev->device) {
24+
case ICE_DEV_ID_E825C_BACKPLANE:
25+
case ICE_DEV_ID_E825C_QSFP:
26+
case ICE_DEV_ID_E825C_SFP:
27+
case ICE_DEV_ID_E825C_SGMII:
28+
/* E825C devices have multiple NACs which are connected to the
29+
* same clock source, and which must share the same
30+
* ice_adapter structure. We can't use the serial number since
31+
* each NAC has its own NVM generated with its own unique
32+
* Device Serial Number. Instead, rely on the embedded nature
33+
* of the E825C devices, and use a fixed index. This relies on
34+
* the fact that all E825C physical functions in a given
35+
* system are part of the same overall device.
36+
*/
37+
return ICE_ADAPTER_INDEX_E825C;
38+
default:
39+
return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
40+
}
41+
}
42+
43+
static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
44+
{
45+
u64 index = ice_adapter_index(pdev);
46+
1847
#if BITS_PER_LONG == 64
19-
return dsn;
48+
return index;
2049
#else
21-
return (u32)dsn ^ (u32)(dsn >> 32);
50+
return (u32)index ^ (u32)(index >> 32);
2251
#endif
2352
}
2453

25-
static struct ice_adapter *ice_adapter_new(u64 dsn)
54+
static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
2655
{
2756
struct ice_adapter *adapter;
2857

2958
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
3059
if (!adapter)
3160
return NULL;
3261

33-
adapter->device_serial_number = dsn;
62+
adapter->index = ice_adapter_index(pdev);
3463
spin_lock_init(&adapter->ptp_gltsyn_time_lock);
3564
spin_lock_init(&adapter->txq_ctx_lock);
3665
refcount_set(&adapter->refcount, 1);
@@ -64,24 +93,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
6493
*/
6594
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
6695
{
67-
u64 dsn = pci_get_dsn(pdev);
6896
struct ice_adapter *adapter;
6997
unsigned long index;
7098
int err;
7199

72-
index = ice_adapter_index(dsn);
100+
index = ice_adapter_xa_index(pdev);
73101
scoped_guard(mutex, &ice_adapters_mutex) {
74102
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
75103
if (err == -EBUSY) {
76104
adapter = xa_load(&ice_adapters, index);
77105
refcount_inc(&adapter->refcount);
78-
WARN_ON_ONCE(adapter->device_serial_number != dsn);
106+
WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
79107
return adapter;
80108
}
81109
if (err)
82110
return ERR_PTR(err);
83111

84-
adapter = ice_adapter_new(dsn);
112+
adapter = ice_adapter_new(pdev);
85113
if (!adapter)
86114
return ERR_PTR(-ENOMEM);
87115
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
@@ -100,11 +128,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
100128
*/
101129
void ice_adapter_put(struct pci_dev *pdev)
102130
{
103-
u64 dsn = pci_get_dsn(pdev);
104131
struct ice_adapter *adapter;
105132
unsigned long index;
106133

107-
index = ice_adapter_index(dsn);
134+
index = ice_adapter_xa_index(pdev);
108135
scoped_guard(mutex, &ice_adapters_mutex) {
109136
adapter = xa_load(&ice_adapters, index);
110137
if (WARN_ON(!adapter))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct ice_port_list {
3333
* @txq_ctx_lock: Spinlock protecting access to the GLCOMM_QTX_CNTX_CTL register
3434
* @ctrl_pf: Control PF of the adapter
3535
* @ports: Ports list
36-
* @device_serial_number: DSN cached for collision detection on 32bit systems
36+
* @index: 64-bit index cached for collision detection on 32bit systems
3737
*/
3838
struct ice_adapter {
3939
refcount_t refcount;
@@ -44,7 +44,7 @@ struct ice_adapter {
4444

4545
struct ice_pf *ctrl_pf;
4646
struct ice_port_list ports;
47-
u64 device_serial_number;
47+
u64 index;
4848
};
4949

5050
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);

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

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,7 +2377,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
23772377
* The function will apply the new Tx topology from the package buffer
23782378
* if available.
23792379
*
2380-
* Return: zero when update was successful, negative values otherwise.
2380+
* Return:
2381+
* * 0 - Successfully applied topology configuration.
2382+
* * -EBUSY - Failed to acquire global configuration lock.
2383+
* * -EEXIST - Topology configuration has already been applied.
2384+
* * -EIO - Unable to apply topology configuration.
2385+
* * -ENODEV - Failed to re-initialize device after applying configuration.
2386+
* * Other negative error codes indicate unexpected failures.
23812387
*/
23822388
int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
23832389
{
@@ -2410,7 +2416,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
24102416

24112417
if (status) {
24122418
ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
2413-
return status;
2419+
return -EIO;
24142420
}
24152421

24162422
/* Is default topology already applied ? */
@@ -2497,31 +2503,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
24972503
ICE_GLOBAL_CFG_LOCK_TIMEOUT);
24982504
if (status) {
24992505
ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
2500-
return status;
2506+
return -EBUSY;
25012507
}
25022508

25032509
/* Check if reset was triggered already. */
25042510
reg = rd32(hw, GLGEN_RSTAT);
25052511
if (reg & GLGEN_RSTAT_DEVSTATE_M) {
2506-
/* Reset is in progress, re-init the HW again */
25072512
ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");
25082513
ice_check_reset(hw);
2509-
return 0;
2514+
/* Reset is in progress, re-init the HW again */
2515+
goto reinit_hw;
25102516
}
25112517

25122518
/* Set new topology */
25132519
status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
25142520
if (status) {
2515-
ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
2516-
return status;
2521+
ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n",
2522+
ERR_PTR(status));
2523+
/* only report -EIO here as the caller checks the error value
2524+
* and reports an informational error message informing that
2525+
* the driver failed to program Tx topology.
2526+
*/
2527+
status = -EIO;
25172528
}
25182529

2519-
/* New topology is updated, delay 1 second before issuing the CORER */
2530+
/* Even if Tx topology config failed, we need to CORE reset here to
2531+
* clear the global configuration lock. Delay 1 second to allow
2532+
* hardware to settle then issue a CORER
2533+
*/
25202534
msleep(1000);
25212535
ice_reset(hw, ICE_RESET_CORER);
2522-
/* CORER will clear the global lock, so no explicit call
2523-
* required for release.
2524-
*/
2536+
ice_check_reset(hw);
2537+
2538+
reinit_hw:
2539+
/* Since we triggered a CORER, re-initialize hardware */
2540+
ice_deinit_hw(hw);
2541+
if (ice_init_hw(hw)) {
2542+
ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n");
2543+
return -ENODEV;
2544+
}
25252545

2526-
return 0;
2546+
return status;
25272547
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ int ice_plug_aux_dev(struct ice_pf *pf)
336336
mutex_lock(&pf->adev_mutex);
337337
cdev->adev = adev;
338338
mutex_unlock(&pf->adev_mutex);
339+
set_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags);
339340

340341
return 0;
341342
}
@@ -347,15 +348,16 @@ void ice_unplug_aux_dev(struct ice_pf *pf)
347348
{
348349
struct auxiliary_device *adev;
349350

351+
if (!test_and_clear_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags))
352+
return;
353+
350354
mutex_lock(&pf->adev_mutex);
351355
adev = pf->cdev_info->adev;
352356
pf->cdev_info->adev = NULL;
353357
mutex_unlock(&pf->adev_mutex);
354358

355-
if (adev) {
356-
auxiliary_device_delete(adev);
357-
auxiliary_device_uninit(adev);
358-
}
359+
auxiliary_device_delete(adev);
360+
auxiliary_device_uninit(adev);
359361
}
360362

361363
/**

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4536,17 +4536,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
45364536
dev_info(dev, "Tx scheduling layers switching feature disabled\n");
45374537
else
45384538
dev_info(dev, "Tx scheduling layers switching feature enabled\n");
4539-
/* if there was a change in topology ice_cfg_tx_topo triggered
4540-
* a CORER and we need to re-init hw
4539+
return 0;
4540+
} else if (err == -ENODEV) {
4541+
/* If we failed to re-initialize the device, we can no longer
4542+
* continue loading.
45414543
*/
4542-
ice_deinit_hw(hw);
4543-
err = ice_init_hw(hw);
4544-
4544+
dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n");
45454545
return err;
45464546
} else if (err == -EIO) {
45474547
dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
4548+
return 0;
4549+
} else if (err == -EEXIST) {
4550+
return 0;
45484551
}
45494552

4553+
/* Do not treat this as a fatal error. */
4554+
dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
4555+
ERR_PTR(err));
45504556
return 0;
45514557
}
45524558

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ static int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
13521352
skb = ice_construct_skb(rx_ring, xdp);
13531353
/* exit if we failed to retrieve a buffer */
13541354
if (!skb) {
1355-
rx_ring->ring_stats->rx_stats.alloc_page_failed++;
1355+
rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
13561356
xdp_verdict = ICE_XDP_CONSUMED;
13571357
}
13581358
ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);

drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,7 @@ static int ixgbe_get_orom_ver_info(struct ixgbe_hw *hw,
31253125
if (err)
31263126
return err;
31273127

3128-
combo_ver = le32_to_cpu(civd.combo_ver);
3128+
combo_ver = get_unaligned_le32(&civd.combo_ver);
31293129

31303130
orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver);
31313131
orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver);

drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ struct ixgbe_orom_civd_info {
932932
__le32 combo_ver; /* Combo Image Version number */
933933
u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */
934934
__le16 combo_name[32]; /* Unicode string representing the Combo Image version */
935-
};
935+
} __packed;
936936

937937
/* Function specific capabilities */
938938
struct ixgbe_hw_func_caps {

0 commit comments

Comments
 (0)