diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 56ff8f6d31fc503598954811e495ac44dcefe597..7006f977c5b750013695322f51591cdfa468c4e4 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -148,3 +148,4 @@ source "drivers/pci/hotplug/Kconfig" source "drivers/pci/controller/Kconfig" source "drivers/pci/endpoint/Kconfig" source "drivers/pci/switch/Kconfig" +source "drivers/pci/iohub-sriov/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 1b2cfe51e8d719ce6cd6976fbaad485cc8143fd8..cfa0cd2763b80f40f2a52a404ed5e13c76554015 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -33,5 +33,6 @@ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ obj-y += controller/ obj-y += switch/ +obj-$(CONFIG_PCI_IOHUB_SRIOV) += iohub-sriov/ ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG diff --git a/drivers/pci/iohub-sriov/Kconfig b/drivers/pci/iohub-sriov/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..b1a32839bbaf415a9feb533ee4dacfff184c348e --- /dev/null +++ b/drivers/pci/iohub-sriov/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# # +# # PCI configuration +# # +# + +menu "PCIe IOHub" + +config PCI_IOHUB_SRIOV + tristate "Alibaba PCIe IOHub SRIOV Driver" + depends on PCI + help + Enables support for Alibaba PCIe IOHub SRIOV Driver, + It enables SRIOV of PCIe devices of Alibaba MOC, + then VFs can be used by other applications. + +endmenu diff --git a/drivers/pci/iohub-sriov/Makefile b/drivers/pci/iohub-sriov/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..21aca2b5fc36166e3a8a74f930c158eae2517c64 --- /dev/null +++ b/drivers/pci/iohub-sriov/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PCI_IOHUB_SRIOV) += iohub-sriov.o diff --git a/drivers/pci/iohub-sriov/iohub-sriov.c b/drivers/pci/iohub-sriov/iohub-sriov.c new file mode 100644 index 0000000000000000000000000000000000000000..1902f31cdbcae42f2f8e8616a7d19518a3ce923a --- /dev/null +++ b/drivers/pci/iohub-sriov/iohub-sriov.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Alibaba PCIe IOHub SRIOV support + * It enables SRIOV of PCIe devices of Alibaba MOC, + * then VFs can be used by other applications. + * + * Copyright (C) 2018 Alibaba Corporation, + * Shanghui.lsh + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PCI_VENDOR_ID_ALIBABA 0x1ded +#define PCI_DEVICE_ID_IOHUB_NETWORK_1 0x1000 +#define PCI_DEVICE_ID_IOHUB_BLOCK_1 0x1001 +#define PCI_DEVICE_ID_IOHUB_NETWORK_2 0x5002 +#define PCI_DEVICE_ID_IOHUB_BLOCK_2 0x5003 + +static int +xdragon_sriov_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int err = 0; + + dev_info(&dev->dev, "iohub device probe\n"); + + /* + * enable device: ask low-level code to enable I/O and + * memory + */ + err = pci_enable_device(dev); + if (err != 0) { + dev_err(&dev->dev, "Cannot enable PCI device\n"); + return err; + } + + /* enable bus mastering on the device */ + pci_set_master(dev); + + /* set 64-bit DMA mask */ + err = pci_set_dma_mask(dev, DMA_BIT_MASK(64)); + if (err != 0) { + dev_err(&dev->dev, "Cannot set DMA mask\n"); + goto error; + } + + err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64)); + if (err != 0) { + dev_err(&dev->dev, "Cannot set consistent DMA mask\n"); + goto error; + } + + /* VF number fixed as 255, will change to a parameter later */ + err = pci_enable_sriov(dev, 255); + if (err) { + dev_err(&dev->dev, "Failed to enable PCI sriov: %d\n", + err); + goto error; + } + + return 0; + + error: + pci_disable_device(dev); + + return err; +} + +static void +xdragon_sriov_pci_remove(struct pci_dev *dev) +{ + /* disable iov and allow time for transactions to clear */ + pci_disable_sriov(dev); + msleep(500); + + pci_disable_device(dev); +} + +static struct pci_device_id xdragon_pci_ids[] = { + { + .vendor = PCI_VENDOR_ID_ALIBABA, + .device = PCI_DEVICE_ID_IOHUB_NETWORK_1, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .vendor = PCI_VENDOR_ID_ALIBABA, + .device = PCI_DEVICE_ID_IOHUB_BLOCK_1, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .vendor = PCI_VENDOR_ID_ALIBABA, + .device = PCI_DEVICE_ID_IOHUB_NETWORK_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .vendor = PCI_VENDOR_ID_ALIBABA, + .device = PCI_DEVICE_ID_IOHUB_BLOCK_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + + { 0, } +}; + + +static struct pci_driver xdragon_sriov_pci_driver = { + .name = "iohub_sriov", + .id_table = xdragon_pci_ids, + .probe = xdragon_sriov_pci_probe, + .remove = xdragon_sriov_pci_remove, +}; + +static int __init +xdragon_sriov_pci_init_module(void) +{ + return pci_register_driver(&xdragon_sriov_pci_driver); +} + +static void __exit +xdragon_sriov_pci_exit_module(void) +{ + pci_unregister_driver(&xdragon_sriov_pci_driver); +} + +module_init(xdragon_sriov_pci_init_module); +module_exit(xdragon_sriov_pci_exit_module); +MODULE_DEVICE_TABLE(pci, xdragon_pci_ids); +MODULE_LICENSE("GPL v2");