1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for FPGA Device Feature List (DFL) PCIe device
5 * Copyright (C) 2017-2018 Intel Corporation, Inc.
8 * Zhang Yi <Yi.Z.Zhang@intel.com>
9 * Xiao Guangrong <guangrong.xiao@linux.intel.com>
10 * Joseph Grecco <joe.grecco@intel.com>
11 * Enno Luebbers <enno.luebbers@intel.com>
12 * Tim Whisonant <tim.whisonant@intel.com>
13 * Ananda Ravuri <ananda.ravuri@intel.com>
14 * Henry Mitchel <henry.mitchel@intel.com>
17 #include <linux/pci.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/stddef.h>
23 #include <linux/errno.h>
27 #define DRV_VERSION "0.8"
28 #define DRV_NAME "dfl-pci"
30 #define PCI_VSEC_ID_INTEL_DFLS 0x43
32 #define PCI_VNDR_DFLS_CNT 0x8
33 #define PCI_VNDR_DFLS_RES 0xc
35 #define PCI_VNDR_DFLS_RES_BAR_MASK GENMASK(2, 0)
36 #define PCI_VNDR_DFLS_RES_OFF_MASK GENMASK(31, 3)
39 struct dfl_fpga_cdev
*cdev
; /* container device */
42 static int cci_pci_alloc_irq(struct pci_dev
*pcidev
)
44 int ret
, nvec
= pci_msix_vec_count(pcidev
);
47 dev_dbg(&pcidev
->dev
, "fpga interrupt not supported\n");
51 ret
= pci_alloc_irq_vectors(pcidev
, nvec
, nvec
, PCI_IRQ_MSIX
);
58 static void cci_pci_free_irq(struct pci_dev
*pcidev
)
60 pci_free_irq_vectors(pcidev
);
64 #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
65 #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
66 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
67 #define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
68 #define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
69 #define PCIE_DEVICE_ID_SILICOM_PAC_N5010 0x1000
70 #define PCIE_DEVICE_ID_SILICOM_PAC_N5011 0x1001
71 #define PCIE_DEVICE_ID_INTEL_DFL 0xbcce
72 /* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
73 #define PCIE_SUBDEVICE_ID_INTEL_D5005 0x138d
74 #define PCIE_SUBDEVICE_ID_INTEL_N6000 0x1770
75 #define PCIE_SUBDEVICE_ID_INTEL_N6001 0x1771
76 #define PCIE_SUBDEVICE_ID_INTEL_C6100 0x17d4
79 #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
80 #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
81 #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
82 #define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
83 #define PCIE_DEVICE_ID_INTEL_DFL_VF 0xbccf
85 static struct pci_device_id cci_pcie_id_tbl
[] = {
86 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_PF_INT_5_X
),},
87 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_VF_INT_5_X
),},
88 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_PF_INT_6_X
),},
89 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_VF_INT_6_X
),},
90 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_PF_DSC_1_X
),},
91 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_VF_DSC_1_X
),},
92 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_PAC_N3000
),},
93 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_PAC_D5005
),},
94 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF
),},
95 {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK
, PCIE_DEVICE_ID_SILICOM_PAC_N5010
),},
96 {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK
, PCIE_DEVICE_ID_SILICOM_PAC_N5011
),},
97 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL
,
98 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_D5005
),},
99 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL
,
100 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_N6000
),},
101 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL_VF
,
102 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_N6000
),},
103 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL
,
104 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_N6001
),},
105 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL_VF
,
106 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_N6001
),},
107 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL
,
108 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_C6100
),},
109 {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL
, PCIE_DEVICE_ID_INTEL_DFL_VF
,
110 PCI_VENDOR_ID_INTEL
, PCIE_SUBDEVICE_ID_INTEL_C6100
),},
113 MODULE_DEVICE_TABLE(pci
, cci_pcie_id_tbl
);
115 static int cci_init_drvdata(struct pci_dev
*pcidev
)
117 struct cci_drvdata
*drvdata
;
119 drvdata
= devm_kzalloc(&pcidev
->dev
, sizeof(*drvdata
), GFP_KERNEL
);
123 pci_set_drvdata(pcidev
, drvdata
);
128 static void cci_remove_feature_devs(struct pci_dev
*pcidev
)
130 struct cci_drvdata
*drvdata
= pci_get_drvdata(pcidev
);
132 /* remove all children feature devices */
133 dfl_fpga_feature_devs_remove(drvdata
->cdev
);
134 cci_pci_free_irq(pcidev
);
137 static int *cci_pci_create_irq_table(struct pci_dev
*pcidev
, unsigned int nvec
)
142 table
= kcalloc(nvec
, sizeof(int), GFP_KERNEL
);
146 for (i
= 0; i
< nvec
; i
++)
147 table
[i
] = pci_irq_vector(pcidev
, i
);
152 static int find_dfls_by_vsec(struct pci_dev
*pcidev
, struct dfl_fpga_enum_info
*info
)
154 u32 bir
, offset
, dfl_cnt
, dfl_res
;
155 int dfl_res_off
, i
, bars
, voff
;
156 resource_size_t start
, len
;
158 voff
= pci_find_vsec_capability(pcidev
, PCI_VENDOR_ID_INTEL
,
159 PCI_VSEC_ID_INTEL_DFLS
);
161 dev_dbg(&pcidev
->dev
, "%s no DFL VSEC found\n", __func__
);
166 pci_read_config_dword(pcidev
, voff
+ PCI_VNDR_DFLS_CNT
, &dfl_cnt
);
167 if (dfl_cnt
> PCI_STD_NUM_BARS
) {
168 dev_err(&pcidev
->dev
, "%s too many DFLs %d > %d\n",
169 __func__
, dfl_cnt
, PCI_STD_NUM_BARS
);
173 dfl_res_off
= voff
+ PCI_VNDR_DFLS_RES
;
174 if (dfl_res_off
+ (dfl_cnt
* sizeof(u32
)) > PCI_CFG_SPACE_EXP_SIZE
) {
175 dev_err(&pcidev
->dev
, "%s DFL VSEC too big for PCIe config space\n",
180 for (i
= 0, bars
= 0; i
< dfl_cnt
; i
++, dfl_res_off
+= sizeof(u32
)) {
181 dfl_res
= GENMASK(31, 0);
182 pci_read_config_dword(pcidev
, dfl_res_off
, &dfl_res
);
184 bir
= dfl_res
& PCI_VNDR_DFLS_RES_BAR_MASK
;
185 if (bir
>= PCI_STD_NUM_BARS
) {
186 dev_err(&pcidev
->dev
, "%s bad bir number %d\n",
191 if (bars
& BIT(bir
)) {
192 dev_err(&pcidev
->dev
, "%s DFL for BAR %d already specified\n",
199 len
= pci_resource_len(pcidev
, bir
);
200 offset
= dfl_res
& PCI_VNDR_DFLS_RES_OFF_MASK
;
202 dev_err(&pcidev
->dev
, "%s bad offset %u >= %pa\n",
203 __func__
, offset
, &len
);
207 dev_dbg(&pcidev
->dev
, "%s BAR %d offset 0x%x\n", __func__
, bir
, offset
);
211 start
= pci_resource_start(pcidev
, bir
) + offset
;
213 dfl_fpga_enum_info_add_dfl(info
, start
, len
);
219 /* default method of finding dfls starting at offset 0 of bar 0 */
220 static int find_dfls_by_default(struct pci_dev
*pcidev
,
221 struct dfl_fpga_enum_info
*info
)
223 int port_num
, bar
, i
, ret
= 0;
224 resource_size_t start
, len
;
229 /* start to find Device Feature List from Bar 0 */
230 base
= pcim_iomap_region(pcidev
, 0, DRV_NAME
);
232 return PTR_ERR(base
);
235 * PF device has FME and Ports/AFUs, and VF device only has one
236 * Port/AFU. Check them and add related "Device Feature List" info
237 * for the next step enumeration.
239 if (dfl_feature_is_fme(base
)) {
240 start
= pci_resource_start(pcidev
, 0);
241 len
= pci_resource_len(pcidev
, 0);
243 dfl_fpga_enum_info_add_dfl(info
, start
, len
);
246 * find more Device Feature Lists (e.g. Ports) per information
247 * indicated by FME module.
249 v
= readq(base
+ FME_HDR_CAP
);
250 port_num
= FIELD_GET(FME_CAP_NUM_PORTS
, v
);
252 WARN_ON(port_num
> MAX_DFL_FPGA_PORT_NUM
);
254 for (i
= 0; i
< port_num
; i
++) {
255 v
= readq(base
+ FME_HDR_PORT_OFST(i
));
257 /* skip ports which are not implemented. */
258 if (!(v
& FME_PORT_OFST_IMP
))
262 * add Port's Device Feature List information for next
265 bar
= FIELD_GET(FME_PORT_OFST_BAR_ID
, v
);
266 offset
= FIELD_GET(FME_PORT_OFST_DFH_OFST
, v
);
267 if (bar
== FME_PORT_OFST_BAR_SKIP
) {
269 } else if (bar
>= PCI_STD_NUM_BARS
) {
270 dev_err(&pcidev
->dev
, "bad BAR %d for port %d\n",
276 start
= pci_resource_start(pcidev
, bar
) + offset
;
277 len
= pci_resource_len(pcidev
, bar
) - offset
;
279 dfl_fpga_enum_info_add_dfl(info
, start
, len
);
281 } else if (dfl_feature_is_port(base
)) {
282 start
= pci_resource_start(pcidev
, 0);
283 len
= pci_resource_len(pcidev
, 0);
285 dfl_fpga_enum_info_add_dfl(info
, start
, len
);
290 /* release I/O mappings for next step enumeration */
291 pcim_iounmap_region(pcidev
, 0);
296 /* enumerate feature devices under pci device */
297 static int cci_enumerate_feature_devs(struct pci_dev
*pcidev
)
299 struct cci_drvdata
*drvdata
= pci_get_drvdata(pcidev
);
300 struct dfl_fpga_enum_info
*info
;
301 struct dfl_fpga_cdev
*cdev
;
305 /* allocate enumeration info via pci_dev */
306 info
= dfl_fpga_enum_info_alloc(&pcidev
->dev
);
310 /* add irq info for enumeration if the device support irq */
311 nvec
= cci_pci_alloc_irq(pcidev
);
313 dev_err(&pcidev
->dev
, "Fail to alloc irq %d.\n", nvec
);
315 goto enum_info_free_exit
;
317 irq_table
= cci_pci_create_irq_table(pcidev
, nvec
);
323 ret
= dfl_fpga_enum_info_add_irq(info
, nvec
, irq_table
);
329 ret
= find_dfls_by_vsec(pcidev
, info
);
331 ret
= find_dfls_by_default(pcidev
, info
);
336 /* start enumeration with prepared enumeration information */
337 cdev
= dfl_fpga_feature_devs_enumerate(info
);
339 dev_err(&pcidev
->dev
, "Enumeration failure\n");
344 drvdata
->cdev
= cdev
;
348 cci_pci_free_irq(pcidev
);
350 dfl_fpga_enum_info_free(info
);
356 int cci_pci_probe(struct pci_dev
*pcidev
, const struct pci_device_id
*pcidevid
)
360 ret
= pcim_enable_device(pcidev
);
362 dev_err(&pcidev
->dev
, "Failed to enable device %d.\n", ret
);
366 pci_set_master(pcidev
);
368 ret
= dma_set_mask_and_coherent(&pcidev
->dev
, DMA_BIT_MASK(64));
370 ret
= dma_set_mask_and_coherent(&pcidev
->dev
, DMA_BIT_MASK(32));
372 dev_err(&pcidev
->dev
, "No suitable DMA support available.\n");
376 ret
= cci_init_drvdata(pcidev
);
378 dev_err(&pcidev
->dev
, "Fail to init drvdata %d.\n", ret
);
382 ret
= cci_enumerate_feature_devs(pcidev
);
384 dev_err(&pcidev
->dev
, "enumeration failure %d.\n", ret
);
391 static int cci_pci_sriov_configure(struct pci_dev
*pcidev
, int num_vfs
)
393 struct cci_drvdata
*drvdata
= pci_get_drvdata(pcidev
);
394 struct dfl_fpga_cdev
*cdev
= drvdata
->cdev
;
398 * disable SRIOV and then put released ports back to default
401 pci_disable_sriov(pcidev
);
403 dfl_fpga_cdev_config_ports_pf(cdev
);
409 * before enable SRIOV, put released ports into VF access mode
412 ret
= dfl_fpga_cdev_config_ports_vf(cdev
, num_vfs
);
416 ret
= pci_enable_sriov(pcidev
, num_vfs
);
418 dfl_fpga_cdev_config_ports_pf(cdev
);
426 static void cci_pci_remove(struct pci_dev
*pcidev
)
428 if (dev_is_pf(&pcidev
->dev
))
429 cci_pci_sriov_configure(pcidev
, 0);
431 cci_remove_feature_devs(pcidev
);
434 static struct pci_driver cci_pci_driver
= {
436 .id_table
= cci_pcie_id_tbl
,
437 .probe
= cci_pci_probe
,
438 .remove
= cci_pci_remove
,
439 .sriov_configure
= cci_pci_sriov_configure
,
442 module_pci_driver(cci_pci_driver
);
444 MODULE_DESCRIPTION("FPGA DFL PCIe Device Driver");
445 MODULE_AUTHOR("Intel Corporation");
446 MODULE_LICENSE("GPL v2");