Skip to content

Commit a9dd49e

Browse files
jacob-kellergregkh
authored andcommitted
ice: use fixed adapter index for E825C embedded devices
[ Upstream commit 5c5e5b5 ] The ice_adapter structure is used by the ice driver to connect multiple physical functions of a device in software. It was introduced by commit 0e2bddf ("ice: add ice_adapter for shared data across PFs on the same NIC") and is primarily used for PTP support, as well as for handling certain cross-PF synchronization. The original design of ice_adapter used PCI address information to determine which devices should be connected. This was extended to support E825C devices by commit fdb7f54 ("ice: Initial support for E825C hardware in ice_adapter"), which used the device ID for E825C devices instead of the PCI address. Later, commit 0093cb1 ("ice: use DSN instead of PCI BDF for ice_adapter index") replaced the use of Bus/Device/Function addressing with use of the device serial number. E825C devices may appear in "Dual NAC" configuration which has multiple physical devices tied to the same clock source and which need to use the same ice_adapter. Unfortunately, each "NAC" has its own NVM which has its own unique Device Serial Number. Thus, use of the DSN for connecting ice_adapter does not work properly. It "worked" in the pre-production systems because the DSN was not initialized on the test NVMs and all the NACs had the same zero'd serial number. Since we cannot rely on the DSN, lets fall back to the logic in the original E825C support which used the device ID. This is safe for E825C only because of the embedded nature of the device. It isn't a discreet adapter that can be plugged into an arbitrary system. All E825C devices on a given system are connected to the same clock source and need to be configured through the same PTP clock. To make this separation clear, reserve bit 63 of the 64-bit index values as a "fixed index" indicator. Always clear this bit when using the device serial number as an index. For E825C, use a fixed value defined as the 0x579C E825C backplane device ID bitwise ORed with the fixed index indicator. This is slightly different than the original logic of just using the device ID directly. Doing so prevents a potential issue with systems where only one of the NACs is connected with an external PHY over SGMII. In that case, one NAC would have the E825C_SGMII device ID, but the other would not. Separate the determination of the full 64-bit index from the 32-bit reduction logic. Provide both ice_adapter_index() and a wrapping ice_adapter_xa_index() which handles reducing the index to a long on 32-bit systems. As before, cache the full index value in the adapter structure to warn about collisions. This fixes issues with E825C not initializing PTP on both NACs, due to failure to connect the appropriate devices to the same ice_adapter. Fixes: 0093cb1 ("ice: use DSN instead of PCI BDF for ice_adapter index") Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 379e7ef commit a9dd49e

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

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
refcount_set(&adapter->refcount, 1);
3665

@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
6392
*/
6493
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
6594
{
66-
u64 dsn = pci_get_dsn(pdev);
6795
struct ice_adapter *adapter;
6896
unsigned long index;
6997
int err;
7098

71-
index = ice_adapter_index(dsn);
99+
index = ice_adapter_xa_index(pdev);
72100
scoped_guard(mutex, &ice_adapters_mutex) {
73101
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
74102
if (err == -EBUSY) {
75103
adapter = xa_load(&ice_adapters, index);
76104
refcount_inc(&adapter->refcount);
77-
WARN_ON_ONCE(adapter->device_serial_number != dsn);
105+
WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
78106
return adapter;
79107
}
80108
if (err)
81109
return ERR_PTR(err);
82110

83-
adapter = ice_adapter_new(dsn);
111+
adapter = ice_adapter_new(pdev);
84112
if (!adapter)
85113
return ERR_PTR(-ENOMEM);
86114
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
99127
*/
100128
void ice_adapter_put(struct pci_dev *pdev)
101129
{
102-
u64 dsn = pci_get_dsn(pdev);
103130
struct ice_adapter *adapter;
104131
unsigned long index;
105132

106-
index = ice_adapter_index(dsn);
133+
index = ice_adapter_xa_index(pdev);
107134
scoped_guard(mutex, &ice_adapters_mutex) {
108135
adapter = xa_load(&ice_adapters, index);
109136
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
@@ -32,7 +32,7 @@ struct ice_port_list {
3232
* @refcount: Reference count. struct ice_pf objects hold the references.
3333
* @ctrl_pf: Control PF of the adapter
3434
* @ports: Ports list
35-
* @device_serial_number: DSN cached for collision detection on 32bit systems
35+
* @index: 64-bit index cached for collision detection on 32bit systems
3636
*/
3737
struct ice_adapter {
3838
refcount_t refcount;
@@ -41,7 +41,7 @@ struct ice_adapter {
4141

4242
struct ice_pf *ctrl_pf;
4343
struct ice_port_list ports;
44-
u64 device_serial_number;
44+
u64 index;
4545
};
4646

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

0 commit comments

Comments
 (0)