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

pds_core: add initial VF device handling

This is the initial VF PCI driver framework for the new
pds_vdpa VF device, which will work in conjunction with an
auxiliary_bus client of the pds_core driver. This does the
very basics of registering for the new VF device, setting
up debugfs entries, and registering with devlink.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Shannon Nelson and committed by
David S. Miller
f53d9311 65e0185a

+56 -1
+9
drivers/net/ethernet/amd/pds_core/core.h
··· 30 30 int res_index; 31 31 }; 32 32 33 + struct pdsc_vf { 34 + struct pds_auxiliary_dev *padev; 35 + u16 index; 36 + __le16 vif_types[PDS_DEV_TYPE_MAX]; 37 + }; 38 + 33 39 struct pdsc_devinfo { 34 40 u8 asic_type; 35 41 u8 asic_rev; ··· 153 147 struct dentry *dentry; 154 148 struct device *dev; 155 149 struct pdsc_dev_bar bars[PDS_CORE_BARS_MAX]; 150 + struct pdsc_vf *vfs; 151 + int num_vfs; 152 + int vf_id; 156 153 int hw_index; 157 154 int uid; 158 155
+47 -1
drivers/net/ethernet/amd/pds_core/main.c
··· 16 16 /* Supported devices */ 17 17 static const struct pci_device_id pdsc_id_table[] = { 18 18 { PCI_VDEVICE(PENSANDO, PCI_DEVICE_ID_PENSANDO_CORE_PF) }, 19 + { PCI_VDEVICE(PENSANDO, PCI_DEVICE_ID_PENSANDO_VDPA_VF) }, 19 20 { 0, } /* end of table */ 20 21 }; 21 22 MODULE_DEVICE_TABLE(pci, pdsc_id_table); ··· 133 132 (u64)page_num << PAGE_SHIFT, PAGE_SIZE); 134 133 } 135 134 135 + static int pdsc_sriov_configure(struct pci_dev *pdev, int num_vfs) 136 + { 137 + struct pdsc *pdsc = pci_get_drvdata(pdev); 138 + struct device *dev = pdsc->dev; 139 + int ret = 0; 140 + 141 + if (num_vfs > 0) { 142 + pdsc->vfs = kcalloc(num_vfs, sizeof(struct pdsc_vf), 143 + GFP_KERNEL); 144 + if (!pdsc->vfs) 145 + return -ENOMEM; 146 + pdsc->num_vfs = num_vfs; 147 + 148 + ret = pci_enable_sriov(pdev, num_vfs); 149 + if (ret) { 150 + dev_err(dev, "Cannot enable SRIOV: %pe\n", 151 + ERR_PTR(ret)); 152 + goto no_vfs; 153 + } 154 + 155 + return num_vfs; 156 + } 157 + 158 + no_vfs: 159 + pci_disable_sriov(pdev); 160 + 161 + kfree(pdsc->vfs); 162 + pdsc->vfs = NULL; 163 + pdsc->num_vfs = 0; 164 + 165 + return ret; 166 + } 167 + 136 168 static int pdsc_init_vf(struct pdsc *vf) 137 169 { 138 - return -1; 170 + struct devlink *dl; 171 + 172 + vf->vf_id = pci_iov_vf_id(vf->pdev); 173 + 174 + dl = priv_to_devlink(vf); 175 + devl_lock(dl); 176 + devl_register(dl); 177 + devl_unlock(dl); 178 + 179 + return 0; 139 180 } 140 181 141 182 static const struct devlink_health_reporter_ops pdsc_fw_reporter_ops = { ··· 366 323 devl_unlock(dl); 367 324 368 325 if (!pdev->is_virtfn) { 326 + pdsc_sriov_configure(pdev, 0); 327 + 369 328 del_timer_sync(&pdsc->wdtimer); 370 329 if (pdsc->wq) 371 330 destroy_workqueue(pdsc->wq); ··· 399 354 .id_table = pdsc_id_table, 400 355 .probe = pdsc_probe, 401 356 .remove = pdsc_remove, 357 + .sriov_configure = pdsc_sriov_configure, 402 358 }; 403 359 404 360 static int __init pdsc_init_module(void)