xref: /linux/drivers/vfio/pci/pds/pci_drv.c (revision bb500dbe2ac622551d98c0bb2735a68f59489c98)
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