138fe3975SBrett Creeley // SPDX-License-Identifier: GPL-2.0 238fe3975SBrett Creeley /* Copyright(c) 2023 Advanced Micro Devices, Inc. */ 338fe3975SBrett Creeley 438fe3975SBrett Creeley #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 538fe3975SBrett Creeley 638fe3975SBrett Creeley #include <linux/module.h> 738fe3975SBrett Creeley #include <linux/pci.h> 838fe3975SBrett Creeley #include <linux/types.h> 938fe3975SBrett Creeley #include <linux/vfio.h> 1038fe3975SBrett Creeley 1163f77a71SBrett Creeley #include <linux/pds/pds_common.h> 1238fe3975SBrett Creeley #include <linux/pds/pds_core_if.h> 1363f77a71SBrett Creeley #include <linux/pds/pds_adminq.h> 1438fe3975SBrett Creeley 1538fe3975SBrett Creeley #include "vfio_dev.h" 1663f77a71SBrett Creeley #include "pci_drv.h" 1763f77a71SBrett Creeley #include "cmds.h" 1838fe3975SBrett Creeley 1938fe3975SBrett Creeley #define PDS_VFIO_DRV_DESCRIPTION "AMD/Pensando VFIO Device Driver" 2038fe3975SBrett Creeley #define PCI_VENDOR_ID_PENSANDO 0x1dd8 2138fe3975SBrett Creeley 2238fe3975SBrett Creeley static int pds_vfio_pci_probe(struct pci_dev *pdev, 2338fe3975SBrett Creeley const struct pci_device_id *id) 2438fe3975SBrett Creeley { 2538fe3975SBrett Creeley struct pds_vfio_pci_device *pds_vfio; 2638fe3975SBrett Creeley int err; 2738fe3975SBrett Creeley 2838fe3975SBrett Creeley pds_vfio = vfio_alloc_device(pds_vfio_pci_device, vfio_coredev.vdev, 2938fe3975SBrett Creeley &pdev->dev, pds_vfio_ops_info()); 3038fe3975SBrett Creeley if (IS_ERR(pds_vfio)) 3138fe3975SBrett Creeley return PTR_ERR(pds_vfio); 3238fe3975SBrett Creeley 3338fe3975SBrett Creeley dev_set_drvdata(&pdev->dev, &pds_vfio->vfio_coredev); 3438fe3975SBrett Creeley 3538fe3975SBrett Creeley err = vfio_pci_core_register_device(&pds_vfio->vfio_coredev); 3638fe3975SBrett Creeley if (err) 3738fe3975SBrett Creeley goto out_put_vdev; 3838fe3975SBrett Creeley 3963f77a71SBrett Creeley err = pds_vfio_register_client_cmd(pds_vfio); 4063f77a71SBrett Creeley if (err) { 4163f77a71SBrett Creeley dev_err(&pdev->dev, "failed to register as client: %pe\n", 4263f77a71SBrett Creeley ERR_PTR(err)); 4363f77a71SBrett Creeley goto out_unregister_coredev; 4463f77a71SBrett Creeley } 4563f77a71SBrett Creeley 4638fe3975SBrett Creeley return 0; 4738fe3975SBrett Creeley 4863f77a71SBrett Creeley out_unregister_coredev: 4963f77a71SBrett Creeley vfio_pci_core_unregister_device(&pds_vfio->vfio_coredev); 5038fe3975SBrett Creeley out_put_vdev: 5138fe3975SBrett Creeley vfio_put_device(&pds_vfio->vfio_coredev.vdev); 5238fe3975SBrett Creeley return err; 5338fe3975SBrett Creeley } 5438fe3975SBrett Creeley 5538fe3975SBrett Creeley static void pds_vfio_pci_remove(struct pci_dev *pdev) 5638fe3975SBrett Creeley { 5738fe3975SBrett Creeley struct pds_vfio_pci_device *pds_vfio = pds_vfio_pci_drvdata(pdev); 5838fe3975SBrett Creeley 5963f77a71SBrett Creeley pds_vfio_unregister_client_cmd(pds_vfio); 6038fe3975SBrett Creeley vfio_pci_core_unregister_device(&pds_vfio->vfio_coredev); 6138fe3975SBrett Creeley vfio_put_device(&pds_vfio->vfio_coredev.vdev); 6238fe3975SBrett Creeley } 6338fe3975SBrett Creeley 6438fe3975SBrett Creeley static const struct pci_device_id pds_vfio_pci_table[] = { 6538fe3975SBrett Creeley { PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_VENDOR_ID_PENSANDO, 0x1003) }, /* Ethernet VF */ 6638fe3975SBrett Creeley { 0, } 6738fe3975SBrett Creeley }; 6838fe3975SBrett Creeley MODULE_DEVICE_TABLE(pci, pds_vfio_pci_table); 6938fe3975SBrett Creeley 70*bb500dbeSBrett Creeley static void pds_vfio_pci_aer_reset_done(struct pci_dev *pdev) 71*bb500dbeSBrett Creeley { 72*bb500dbeSBrett Creeley struct pds_vfio_pci_device *pds_vfio = pds_vfio_pci_drvdata(pdev); 73*bb500dbeSBrett Creeley 74*bb500dbeSBrett Creeley pds_vfio_reset(pds_vfio); 75*bb500dbeSBrett Creeley } 76*bb500dbeSBrett Creeley 77*bb500dbeSBrett Creeley static const struct pci_error_handlers pds_vfio_pci_err_handlers = { 78*bb500dbeSBrett Creeley .reset_done = pds_vfio_pci_aer_reset_done, 79*bb500dbeSBrett Creeley .error_detected = vfio_pci_core_aer_err_detected, 80*bb500dbeSBrett Creeley }; 81*bb500dbeSBrett Creeley 8238fe3975SBrett Creeley static struct pci_driver pds_vfio_pci_driver = { 8338fe3975SBrett Creeley .name = KBUILD_MODNAME, 8438fe3975SBrett Creeley .id_table = pds_vfio_pci_table, 8538fe3975SBrett Creeley .probe = pds_vfio_pci_probe, 8638fe3975SBrett Creeley .remove = pds_vfio_pci_remove, 87*bb500dbeSBrett Creeley .err_handler = &pds_vfio_pci_err_handlers, 8838fe3975SBrett Creeley .driver_managed_dma = true, 8938fe3975SBrett Creeley }; 9038fe3975SBrett Creeley 9138fe3975SBrett Creeley module_pci_driver(pds_vfio_pci_driver); 9238fe3975SBrett Creeley 9338fe3975SBrett Creeley MODULE_DESCRIPTION(PDS_VFIO_DRV_DESCRIPTION); 9438fe3975SBrett Creeley MODULE_AUTHOR("Brett Creeley <brett.creeley@amd.com>"); 9538fe3975SBrett Creeley MODULE_LICENSE("GPL"); 96