Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

idpf: add support for IDPF PCI programming interface

At present IDPF supports only 0x1452 and 0x145C as PF and VF device IDs
on our current generation hardware. Future hardware exposes a new set of
device IDs for each generation. To avoid adding a new device ID for each
generation and to make the driver forward and backward compatible,
make use of the IDPF PCI programming interface to load the driver.

Write and read the VF_ARQBAL mailbox register to find if the current
device is a PF or a VF.

PCI SIG allocated a new programming interface for the IDPF compliant
ethernet network controller devices. It can be found at:
https://members.pcisig.com/wg/PCI-SIG/document/20113
with the document titled as 'PCI Code and ID Assignment Revision 1.16'
or any latest revisions.

Tested this patch by doing a simple driver load/unload on Intel IPU E2000
hardware which supports 0x1452 and 0x145C device IDs and new hardware
which supports the IDPF PCI programming interface.

Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com>
Signed-off-by: Madhu Chittim <madhu.chittim@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Marek Landowski <marek.landowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20251103224631.595527-1-anthony.l.nguyen@intel.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Pavan Kumar Linga and committed by
Paolo Abeni
13068e9d 0cc4b846

+88 -17
+88 -17
drivers/net/ethernet/intel/idpf/idpf_main.c
··· 3 3 4 4 #include "idpf.h" 5 5 #include "idpf_devids.h" 6 + #include "idpf_lan_vf_regs.h" 6 7 #include "idpf_virtchnl.h" 7 8 8 9 #define DRV_SUMMARY "Intel(R) Infrastructure Data Path Function Linux Driver" 10 + 11 + #define IDPF_NETWORK_ETHERNET_PROGIF 0x01 12 + #define IDPF_CLASS_NETWORK_ETHERNET_PROGIF \ 13 + (PCI_CLASS_NETWORK_ETHERNET << 8 | IDPF_NETWORK_ETHERNET_PROGIF) 14 + #define IDPF_VF_TEST_VAL 0xfeed0000u 9 15 10 16 MODULE_DESCRIPTION(DRV_SUMMARY); 11 17 MODULE_IMPORT_NS("LIBETH"); 12 18 MODULE_IMPORT_NS("LIBETH_XDP"); 13 19 MODULE_LICENSE("GPL"); 20 + 21 + /** 22 + * idpf_get_device_type - Helper to find if it is a VF or PF device 23 + * @pdev: PCI device information struct 24 + * 25 + * Return: PF/VF device ID or -%errno on failure. 26 + */ 27 + static int idpf_get_device_type(struct pci_dev *pdev) 28 + { 29 + void __iomem *addr; 30 + int ret; 31 + 32 + addr = ioremap(pci_resource_start(pdev, 0) + VF_ARQBAL, 4); 33 + if (!addr) { 34 + pci_err(pdev, "Failed to allocate BAR0 mbx region\n"); 35 + return -EIO; 36 + } 37 + 38 + writel(IDPF_VF_TEST_VAL, addr); 39 + if (readl(addr) == IDPF_VF_TEST_VAL) 40 + ret = IDPF_DEV_ID_VF; 41 + else 42 + ret = IDPF_DEV_ID_PF; 43 + 44 + iounmap(addr); 45 + 46 + return ret; 47 + } 48 + 49 + /** 50 + * idpf_dev_init - Initialize device specific parameters 51 + * @adapter: adapter to initialize 52 + * @ent: entry in idpf_pci_tbl 53 + * 54 + * Return: %0 on success, -%errno on failure. 55 + */ 56 + static int idpf_dev_init(struct idpf_adapter *adapter, 57 + const struct pci_device_id *ent) 58 + { 59 + int ret; 60 + 61 + if (ent->class == IDPF_CLASS_NETWORK_ETHERNET_PROGIF) { 62 + ret = idpf_get_device_type(adapter->pdev); 63 + switch (ret) { 64 + case IDPF_DEV_ID_VF: 65 + idpf_vf_dev_ops_init(adapter); 66 + adapter->crc_enable = true; 67 + break; 68 + case IDPF_DEV_ID_PF: 69 + idpf_dev_ops_init(adapter); 70 + break; 71 + default: 72 + return ret; 73 + } 74 + 75 + return 0; 76 + } 77 + 78 + switch (ent->device) { 79 + case IDPF_DEV_ID_PF: 80 + idpf_dev_ops_init(adapter); 81 + break; 82 + case IDPF_DEV_ID_VF: 83 + idpf_vf_dev_ops_init(adapter); 84 + adapter->crc_enable = true; 85 + break; 86 + default: 87 + return -ENODEV; 88 + } 89 + 90 + return 0; 91 + } 14 92 15 93 /** 16 94 * idpf_remove - Device removal routine ··· 243 165 adapter->req_tx_splitq = true; 244 166 adapter->req_rx_splitq = true; 245 167 246 - switch (ent->device) { 247 - case IDPF_DEV_ID_PF: 248 - idpf_dev_ops_init(adapter); 249 - break; 250 - case IDPF_DEV_ID_VF: 251 - idpf_vf_dev_ops_init(adapter); 252 - adapter->crc_enable = true; 253 - break; 254 - default: 255 - err = -ENODEV; 256 - dev_err(&pdev->dev, "Unexpected dev ID 0x%x in idpf probe\n", 257 - ent->device); 258 - goto err_free; 259 - } 260 - 261 168 adapter->pdev = pdev; 262 169 err = pcim_enable_device(pdev); 263 170 if (err) ··· 322 259 /* setup msglvl */ 323 260 adapter->msg_enable = netif_msg_init(-1, IDPF_AVAIL_NETIF_M); 324 261 262 + err = idpf_dev_init(adapter, ent); 263 + if (err) { 264 + dev_err(&pdev->dev, "Unexpected dev ID 0x%x in idpf probe\n", 265 + ent->device); 266 + goto destroy_vc_event_wq; 267 + } 268 + 325 269 err = idpf_cfg_hw(adapter); 326 270 if (err) { 327 271 dev_err(dev, "Failed to configure HW structure for adapter: %d\n", 328 272 err); 329 - goto err_cfg_hw; 273 + goto destroy_vc_event_wq; 330 274 } 331 275 332 276 mutex_init(&adapter->vport_ctrl_lock); ··· 354 284 355 285 return 0; 356 286 357 - err_cfg_hw: 287 + destroy_vc_event_wq: 358 288 destroy_workqueue(adapter->vc_event_wq); 359 289 err_vc_event_wq_alloc: 360 290 destroy_workqueue(adapter->stats_wq); ··· 374 304 static const struct pci_device_id idpf_pci_tbl[] = { 375 305 { PCI_VDEVICE(INTEL, IDPF_DEV_ID_PF)}, 376 306 { PCI_VDEVICE(INTEL, IDPF_DEV_ID_VF)}, 307 + { PCI_DEVICE_CLASS(IDPF_CLASS_NETWORK_ETHERNET_PROGIF, ~0)}, 377 308 { /* Sentinel */ } 378 309 }; 379 310 MODULE_DEVICE_TABLE(pci, idpf_pci_tbl);