Skip to content

Commit 5c5e5b5

Browse files
jacob-kelleranguy11
authored andcommitted
ice: use fixed adapter index for E825C embedded devices
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 <[email protected]> Reviewed-by: Grzegorz Nitka <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Reviewed-by: Przemek Kitszel <[email protected]> Tested-by: Rinitha S <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 86aae43 commit 5c5e5b5

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
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);

0 commit comments

Comments
 (0)