104 lines
2.8 KiB
C
104 lines
2.8 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
/*
|
||
|
* Driver for FPGA Device Feature List (DFL) PCIe device
|
||
|
*
|
||
|
* Copyright (C) 2017-2018 Intel Corporation, Inc.
|
||
|
*
|
||
|
* Authors:
|
||
|
* Zhang Yi <Yi.Z.Zhang@intel.com>
|
||
|
* Xiao Guangrong <guangrong.xiao@linux.intel.com>
|
||
|
* Joseph Grecco <joe.grecco@intel.com>
|
||
|
* Enno Luebbers <enno.luebbers@intel.com>
|
||
|
* Tim Whisonant <tim.whisonant@intel.com>
|
||
|
* Ananda Ravuri <ananda.ravuri@intel.com>
|
||
|
* Henry Mitchel <henry.mitchel@intel.com>
|
||
|
*/
|
||
|
|
||
|
#include <linux/pci.h>
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/stddef.h>
|
||
|
#include <linux/errno.h>
|
||
|
#include <linux/aer.h>
|
||
|
|
||
|
#define DRV_VERSION "0.8"
|
||
|
#define DRV_NAME "dfl-pci"
|
||
|
|
||
|
/* PCI Device ID */
|
||
|
#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
|
||
|
#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
|
||
|
#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
|
||
|
/* VF Device */
|
||
|
#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
|
||
|
#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
|
||
|
#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
|
||
|
|
||
|
static struct pci_device_id cci_pcie_id_tbl[] = {
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X),},
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X),},
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),},
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
|
||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
|
||
|
{0,}
|
||
|
};
|
||
|
MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
|
||
|
|
||
|
static
|
||
|
int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
ret = pcim_enable_device(pcidev);
|
||
|
if (ret < 0) {
|
||
|
dev_err(&pcidev->dev, "Failed to enable device %d.\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ret = pci_enable_pcie_error_reporting(pcidev);
|
||
|
if (ret && ret != -EINVAL)
|
||
|
dev_info(&pcidev->dev, "PCIE AER unavailable %d.\n", ret);
|
||
|
|
||
|
pci_set_master(pcidev);
|
||
|
|
||
|
if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
|
||
|
ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
|
||
|
if (ret)
|
||
|
goto disable_error_report_exit;
|
||
|
} else if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
|
||
|
ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
|
||
|
if (ret)
|
||
|
goto disable_error_report_exit;
|
||
|
} else {
|
||
|
ret = -EIO;
|
||
|
dev_err(&pcidev->dev, "No suitable DMA support available.\n");
|
||
|
goto disable_error_report_exit;
|
||
|
}
|
||
|
|
||
|
/* TODO: create and add the platform device per feature list */
|
||
|
return 0;
|
||
|
|
||
|
disable_error_report_exit:
|
||
|
pci_disable_pcie_error_reporting(pcidev);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static void cci_pci_remove(struct pci_dev *pcidev)
|
||
|
{
|
||
|
pci_disable_pcie_error_reporting(pcidev);
|
||
|
}
|
||
|
|
||
|
static struct pci_driver cci_pci_driver = {
|
||
|
.name = DRV_NAME,
|
||
|
.id_table = cci_pcie_id_tbl,
|
||
|
.probe = cci_pci_probe,
|
||
|
.remove = cci_pci_remove,
|
||
|
};
|
||
|
|
||
|
module_pci_driver(cci_pci_driver);
|
||
|
|
||
|
MODULE_DESCRIPTION("FPGA DFL PCIe Device Driver");
|
||
|
MODULE_AUTHOR("Intel Corporation");
|
||
|
MODULE_LICENSE("GPL v2");
|