0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/pci.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/types.h>
0020 #include <linux/kernel.h>
0021 #include <linux/module.h>
0022 #include <linux/stddef.h>
0023 #include <linux/errno.h>
0024 #include <linux/aer.h>
0025
0026 #include "dfl.h"
0027
0028 #define DRV_VERSION "0.8"
0029 #define DRV_NAME "dfl-pci"
0030
0031 #define PCI_VSEC_ID_INTEL_DFLS 0x43
0032
0033 #define PCI_VNDR_DFLS_CNT 0x8
0034 #define PCI_VNDR_DFLS_RES 0xc
0035
0036 #define PCI_VNDR_DFLS_RES_BAR_MASK GENMASK(2, 0)
0037 #define PCI_VNDR_DFLS_RES_OFF_MASK GENMASK(31, 3)
0038
0039 struct cci_drvdata {
0040 struct dfl_fpga_cdev *cdev;
0041 };
0042
0043 static void __iomem *cci_pci_ioremap_bar0(struct pci_dev *pcidev)
0044 {
0045 if (pcim_iomap_regions(pcidev, BIT(0), DRV_NAME))
0046 return NULL;
0047
0048 return pcim_iomap_table(pcidev)[0];
0049 }
0050
0051 static int cci_pci_alloc_irq(struct pci_dev *pcidev)
0052 {
0053 int ret, nvec = pci_msix_vec_count(pcidev);
0054
0055 if (nvec <= 0) {
0056 dev_dbg(&pcidev->dev, "fpga interrupt not supported\n");
0057 return 0;
0058 }
0059
0060 ret = pci_alloc_irq_vectors(pcidev, nvec, nvec, PCI_IRQ_MSIX);
0061 if (ret < 0)
0062 return ret;
0063
0064 return nvec;
0065 }
0066
0067 static void cci_pci_free_irq(struct pci_dev *pcidev)
0068 {
0069 pci_free_irq_vectors(pcidev);
0070 }
0071
0072
0073 #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
0074 #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
0075 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
0076 #define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
0077 #define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
0078 #define PCIE_DEVICE_ID_SILICOM_PAC_N5010 0x1000
0079 #define PCIE_DEVICE_ID_SILICOM_PAC_N5011 0x1001
0080
0081
0082 #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
0083 #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
0084 #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
0085 #define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
0086
0087 static struct pci_device_id cci_pcie_id_tbl[] = {
0088 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
0089 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X),},
0090 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X),},
0091 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),},
0092 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
0093 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
0094 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
0095 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
0096 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
0097 {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
0098 {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
0099 {0,}
0100 };
0101 MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
0102
0103 static int cci_init_drvdata(struct pci_dev *pcidev)
0104 {
0105 struct cci_drvdata *drvdata;
0106
0107 drvdata = devm_kzalloc(&pcidev->dev, sizeof(*drvdata), GFP_KERNEL);
0108 if (!drvdata)
0109 return -ENOMEM;
0110
0111 pci_set_drvdata(pcidev, drvdata);
0112
0113 return 0;
0114 }
0115
0116 static void cci_remove_feature_devs(struct pci_dev *pcidev)
0117 {
0118 struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
0119
0120
0121 dfl_fpga_feature_devs_remove(drvdata->cdev);
0122 cci_pci_free_irq(pcidev);
0123 }
0124
0125 static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec)
0126 {
0127 unsigned int i;
0128 int *table;
0129
0130 table = kcalloc(nvec, sizeof(int), GFP_KERNEL);
0131 if (!table)
0132 return table;
0133
0134 for (i = 0; i < nvec; i++)
0135 table[i] = pci_irq_vector(pcidev, i);
0136
0137 return table;
0138 }
0139
0140 static int find_dfls_by_vsec(struct pci_dev *pcidev, struct dfl_fpga_enum_info *info)
0141 {
0142 u32 bir, offset, vndr_hdr, dfl_cnt, dfl_res;
0143 int dfl_res_off, i, bars, voff = 0;
0144 resource_size_t start, len;
0145
0146 while ((voff = pci_find_next_ext_capability(pcidev, voff, PCI_EXT_CAP_ID_VNDR))) {
0147 vndr_hdr = 0;
0148 pci_read_config_dword(pcidev, voff + PCI_VNDR_HEADER, &vndr_hdr);
0149
0150 if (PCI_VNDR_HEADER_ID(vndr_hdr) == PCI_VSEC_ID_INTEL_DFLS &&
0151 pcidev->vendor == PCI_VENDOR_ID_INTEL)
0152 break;
0153 }
0154
0155 if (!voff) {
0156 dev_dbg(&pcidev->dev, "%s no DFL VSEC found\n", __func__);
0157 return -ENODEV;
0158 }
0159
0160 dfl_cnt = 0;
0161 pci_read_config_dword(pcidev, voff + PCI_VNDR_DFLS_CNT, &dfl_cnt);
0162 if (dfl_cnt > PCI_STD_NUM_BARS) {
0163 dev_err(&pcidev->dev, "%s too many DFLs %d > %d\n",
0164 __func__, dfl_cnt, PCI_STD_NUM_BARS);
0165 return -EINVAL;
0166 }
0167
0168 dfl_res_off = voff + PCI_VNDR_DFLS_RES;
0169 if (dfl_res_off + (dfl_cnt * sizeof(u32)) > PCI_CFG_SPACE_EXP_SIZE) {
0170 dev_err(&pcidev->dev, "%s DFL VSEC too big for PCIe config space\n",
0171 __func__);
0172 return -EINVAL;
0173 }
0174
0175 for (i = 0, bars = 0; i < dfl_cnt; i++, dfl_res_off += sizeof(u32)) {
0176 dfl_res = GENMASK(31, 0);
0177 pci_read_config_dword(pcidev, dfl_res_off, &dfl_res);
0178
0179 bir = dfl_res & PCI_VNDR_DFLS_RES_BAR_MASK;
0180 if (bir >= PCI_STD_NUM_BARS) {
0181 dev_err(&pcidev->dev, "%s bad bir number %d\n",
0182 __func__, bir);
0183 return -EINVAL;
0184 }
0185
0186 if (bars & BIT(bir)) {
0187 dev_err(&pcidev->dev, "%s DFL for BAR %d already specified\n",
0188 __func__, bir);
0189 return -EINVAL;
0190 }
0191
0192 bars |= BIT(bir);
0193
0194 len = pci_resource_len(pcidev, bir);
0195 offset = dfl_res & PCI_VNDR_DFLS_RES_OFF_MASK;
0196 if (offset >= len) {
0197 dev_err(&pcidev->dev, "%s bad offset %u >= %pa\n",
0198 __func__, offset, &len);
0199 return -EINVAL;
0200 }
0201
0202 dev_dbg(&pcidev->dev, "%s BAR %d offset 0x%x\n", __func__, bir, offset);
0203
0204 len -= offset;
0205
0206 start = pci_resource_start(pcidev, bir) + offset;
0207
0208 dfl_fpga_enum_info_add_dfl(info, start, len);
0209 }
0210
0211 return 0;
0212 }
0213
0214
0215 static int find_dfls_by_default(struct pci_dev *pcidev,
0216 struct dfl_fpga_enum_info *info)
0217 {
0218 int port_num, bar, i, ret = 0;
0219 resource_size_t start, len;
0220 void __iomem *base;
0221 u32 offset;
0222 u64 v;
0223
0224
0225 base = cci_pci_ioremap_bar0(pcidev);
0226 if (!base)
0227 return -ENOMEM;
0228
0229
0230
0231
0232
0233
0234 if (dfl_feature_is_fme(base)) {
0235 start = pci_resource_start(pcidev, 0);
0236 len = pci_resource_len(pcidev, 0);
0237
0238 dfl_fpga_enum_info_add_dfl(info, start, len);
0239
0240
0241
0242
0243
0244 v = readq(base + FME_HDR_CAP);
0245 port_num = FIELD_GET(FME_CAP_NUM_PORTS, v);
0246
0247 WARN_ON(port_num > MAX_DFL_FPGA_PORT_NUM);
0248
0249 for (i = 0; i < port_num; i++) {
0250 v = readq(base + FME_HDR_PORT_OFST(i));
0251
0252
0253 if (!(v & FME_PORT_OFST_IMP))
0254 continue;
0255
0256
0257
0258
0259
0260 bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v);
0261 offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v);
0262 if (bar == FME_PORT_OFST_BAR_SKIP) {
0263 continue;
0264 } else if (bar >= PCI_STD_NUM_BARS) {
0265 dev_err(&pcidev->dev, "bad BAR %d for port %d\n",
0266 bar, i);
0267 ret = -EINVAL;
0268 break;
0269 }
0270
0271 start = pci_resource_start(pcidev, bar) + offset;
0272 len = pci_resource_len(pcidev, bar) - offset;
0273
0274 dfl_fpga_enum_info_add_dfl(info, start, len);
0275 }
0276 } else if (dfl_feature_is_port(base)) {
0277 start = pci_resource_start(pcidev, 0);
0278 len = pci_resource_len(pcidev, 0);
0279
0280 dfl_fpga_enum_info_add_dfl(info, start, len);
0281 } else {
0282 ret = -ENODEV;
0283 }
0284
0285
0286 pcim_iounmap_regions(pcidev, BIT(0));
0287
0288 return ret;
0289 }
0290
0291
0292 static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
0293 {
0294 struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
0295 struct dfl_fpga_enum_info *info;
0296 struct dfl_fpga_cdev *cdev;
0297 int nvec, ret = 0;
0298 int *irq_table;
0299
0300
0301 info = dfl_fpga_enum_info_alloc(&pcidev->dev);
0302 if (!info)
0303 return -ENOMEM;
0304
0305
0306 nvec = cci_pci_alloc_irq(pcidev);
0307 if (nvec < 0) {
0308 dev_err(&pcidev->dev, "Fail to alloc irq %d.\n", nvec);
0309 ret = nvec;
0310 goto enum_info_free_exit;
0311 } else if (nvec) {
0312 irq_table = cci_pci_create_irq_table(pcidev, nvec);
0313 if (!irq_table) {
0314 ret = -ENOMEM;
0315 goto irq_free_exit;
0316 }
0317
0318 ret = dfl_fpga_enum_info_add_irq(info, nvec, irq_table);
0319 kfree(irq_table);
0320 if (ret)
0321 goto irq_free_exit;
0322 }
0323
0324 ret = find_dfls_by_vsec(pcidev, info);
0325 if (ret == -ENODEV)
0326 ret = find_dfls_by_default(pcidev, info);
0327
0328 if (ret)
0329 goto irq_free_exit;
0330
0331
0332 cdev = dfl_fpga_feature_devs_enumerate(info);
0333 if (IS_ERR(cdev)) {
0334 dev_err(&pcidev->dev, "Enumeration failure\n");
0335 ret = PTR_ERR(cdev);
0336 goto irq_free_exit;
0337 }
0338
0339 drvdata->cdev = cdev;
0340
0341 irq_free_exit:
0342 if (ret)
0343 cci_pci_free_irq(pcidev);
0344 enum_info_free_exit:
0345 dfl_fpga_enum_info_free(info);
0346
0347 return ret;
0348 }
0349
0350 static
0351 int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
0352 {
0353 int ret;
0354
0355 ret = pcim_enable_device(pcidev);
0356 if (ret < 0) {
0357 dev_err(&pcidev->dev, "Failed to enable device %d.\n", ret);
0358 return ret;
0359 }
0360
0361 ret = pci_enable_pcie_error_reporting(pcidev);
0362 if (ret && ret != -EINVAL)
0363 dev_info(&pcidev->dev, "PCIE AER unavailable %d.\n", ret);
0364
0365 pci_set_master(pcidev);
0366
0367 ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64));
0368 if (ret)
0369 ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32));
0370 if (ret) {
0371 dev_err(&pcidev->dev, "No suitable DMA support available.\n");
0372 goto disable_error_report_exit;
0373 }
0374
0375 ret = cci_init_drvdata(pcidev);
0376 if (ret) {
0377 dev_err(&pcidev->dev, "Fail to init drvdata %d.\n", ret);
0378 goto disable_error_report_exit;
0379 }
0380
0381 ret = cci_enumerate_feature_devs(pcidev);
0382 if (!ret)
0383 return ret;
0384
0385 dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
0386
0387 disable_error_report_exit:
0388 pci_disable_pcie_error_reporting(pcidev);
0389 return ret;
0390 }
0391
0392 static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
0393 {
0394 struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
0395 struct dfl_fpga_cdev *cdev = drvdata->cdev;
0396
0397 if (!num_vfs) {
0398
0399
0400
0401
0402 pci_disable_sriov(pcidev);
0403
0404 dfl_fpga_cdev_config_ports_pf(cdev);
0405
0406 } else {
0407 int ret;
0408
0409
0410
0411
0412
0413 ret = dfl_fpga_cdev_config_ports_vf(cdev, num_vfs);
0414 if (ret)
0415 return ret;
0416
0417 ret = pci_enable_sriov(pcidev, num_vfs);
0418 if (ret) {
0419 dfl_fpga_cdev_config_ports_pf(cdev);
0420 return ret;
0421 }
0422 }
0423
0424 return num_vfs;
0425 }
0426
0427 static void cci_pci_remove(struct pci_dev *pcidev)
0428 {
0429 if (dev_is_pf(&pcidev->dev))
0430 cci_pci_sriov_configure(pcidev, 0);
0431
0432 cci_remove_feature_devs(pcidev);
0433 pci_disable_pcie_error_reporting(pcidev);
0434 }
0435
0436 static struct pci_driver cci_pci_driver = {
0437 .name = DRV_NAME,
0438 .id_table = cci_pcie_id_tbl,
0439 .probe = cci_pci_probe,
0440 .remove = cci_pci_remove,
0441 .sriov_configure = cci_pci_sriov_configure,
0442 };
0443
0444 module_pci_driver(cci_pci_driver);
0445
0446 MODULE_DESCRIPTION("FPGA DFL PCIe Device Driver");
0447 MODULE_AUTHOR("Intel Corporation");
0448 MODULE_LICENSE("GPL v2");