xref: /linux/drivers/fpga/dfl-pci.c (revision 66bfc528a6fd5225e59ea4bbca0665aad38f1567)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Driver for FPGA Device Feature List (DFL) PCIe device
4   *
5   * Copyright (C) 2017-2018 Intel Corporation, Inc.
6   *
7   * Authors:
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>
15   */
16  
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>
24  
25  #include "dfl.h"
26  
27  #define DRV_VERSION	"0.8"
28  #define DRV_NAME	"dfl-pci"
29  
30  #define PCI_VSEC_ID_INTEL_DFLS 0x43
31  
32  #define PCI_VNDR_DFLS_CNT 0x8
33  #define PCI_VNDR_DFLS_RES 0xc
34  
35  #define PCI_VNDR_DFLS_RES_BAR_MASK GENMASK(2, 0)
36  #define PCI_VNDR_DFLS_RES_OFF_MASK GENMASK(31, 3)
37  
38  struct cci_drvdata {
39  	struct dfl_fpga_cdev *cdev;	/* container device */
40  };
41  
42  static void __iomem *cci_pci_ioremap_bar0(struct pci_dev *pcidev)
43  {
44  	if (pcim_iomap_regions(pcidev, BIT(0), DRV_NAME))
45  		return NULL;
46  
47  	return pcim_iomap_table(pcidev)[0];
48  }
49  
50  static int cci_pci_alloc_irq(struct pci_dev *pcidev)
51  {
52  	int ret, nvec = pci_msix_vec_count(pcidev);
53  
54  	if (nvec <= 0) {
55  		dev_dbg(&pcidev->dev, "fpga interrupt not supported\n");
56  		return 0;
57  	}
58  
59  	ret = pci_alloc_irq_vectors(pcidev, nvec, nvec, PCI_IRQ_MSIX);
60  	if (ret < 0)
61  		return ret;
62  
63  	return nvec;
64  }
65  
66  static void cci_pci_free_irq(struct pci_dev *pcidev)
67  {
68  	pci_free_irq_vectors(pcidev);
69  }
70  
71  /* PCI Device ID */
72  #define PCIE_DEVICE_ID_PF_INT_5_X		0xBCBD
73  #define PCIE_DEVICE_ID_PF_INT_6_X		0xBCC0
74  #define PCIE_DEVICE_ID_PF_DSC_1_X		0x09C4
75  #define PCIE_DEVICE_ID_INTEL_PAC_N3000		0x0B30
76  #define PCIE_DEVICE_ID_INTEL_PAC_D5005		0x0B2B
77  #define PCIE_DEVICE_ID_SILICOM_PAC_N5010	0x1000
78  #define PCIE_DEVICE_ID_SILICOM_PAC_N5011	0x1001
79  #define PCIE_DEVICE_ID_INTEL_DFL		0xbcce
80  /* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
81  #define PCIE_SUBDEVICE_ID_INTEL_N6000		0x1770
82  #define PCIE_SUBDEVICE_ID_INTEL_N6001		0x1771
83  #define PCIE_SUBDEVICE_ID_INTEL_C6100		0x17d4
84  
85  /* VF Device */
86  #define PCIE_DEVICE_ID_VF_INT_5_X		0xBCBF
87  #define PCIE_DEVICE_ID_VF_INT_6_X		0xBCC1
88  #define PCIE_DEVICE_ID_VF_DSC_1_X		0x09C5
89  #define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF	0x0B2C
90  #define PCIE_DEVICE_ID_INTEL_DFL_VF		0xbccf
91  
92  static struct pci_device_id cci_pcie_id_tbl[] = {
93  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
94  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X),},
95  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X),},
96  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),},
97  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
98  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
99  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
100  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
101  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
102  	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
103  	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
104  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
105  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
106  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
107  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
108  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
109  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
110  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
111  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
112  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
113  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
114  	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
115  			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
116  	{0,}
117  };
118  MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
119  
120  static int cci_init_drvdata(struct pci_dev *pcidev)
121  {
122  	struct cci_drvdata *drvdata;
123  
124  	drvdata = devm_kzalloc(&pcidev->dev, sizeof(*drvdata), GFP_KERNEL);
125  	if (!drvdata)
126  		return -ENOMEM;
127  
128  	pci_set_drvdata(pcidev, drvdata);
129  
130  	return 0;
131  }
132  
133  static void cci_remove_feature_devs(struct pci_dev *pcidev)
134  {
135  	struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
136  
137  	/* remove all children feature devices */
138  	dfl_fpga_feature_devs_remove(drvdata->cdev);
139  	cci_pci_free_irq(pcidev);
140  }
141  
142  static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec)
143  {
144  	unsigned int i;
145  	int *table;
146  
147  	table = kcalloc(nvec, sizeof(int), GFP_KERNEL);
148  	if (!table)
149  		return table;
150  
151  	for (i = 0; i < nvec; i++)
152  		table[i] = pci_irq_vector(pcidev, i);
153  
154  	return table;
155  }
156  
157  static int find_dfls_by_vsec(struct pci_dev *pcidev, struct dfl_fpga_enum_info *info)
158  {
159  	u32 bir, offset, vndr_hdr, dfl_cnt, dfl_res;
160  	int dfl_res_off, i, bars, voff = 0;
161  	resource_size_t start, len;
162  
163  	while ((voff = pci_find_next_ext_capability(pcidev, voff, PCI_EXT_CAP_ID_VNDR))) {
164  		vndr_hdr = 0;
165  		pci_read_config_dword(pcidev, voff + PCI_VNDR_HEADER, &vndr_hdr);
166  
167  		if (PCI_VNDR_HEADER_ID(vndr_hdr) == PCI_VSEC_ID_INTEL_DFLS &&
168  		    pcidev->vendor == PCI_VENDOR_ID_INTEL)
169  			break;
170  	}
171  
172  	if (!voff) {
173  		dev_dbg(&pcidev->dev, "%s no DFL VSEC found\n", __func__);
174  		return -ENODEV;
175  	}
176  
177  	dfl_cnt = 0;
178  	pci_read_config_dword(pcidev, voff + PCI_VNDR_DFLS_CNT, &dfl_cnt);
179  	if (dfl_cnt > PCI_STD_NUM_BARS) {
180  		dev_err(&pcidev->dev, "%s too many DFLs %d > %d\n",
181  			__func__, dfl_cnt, PCI_STD_NUM_BARS);
182  		return -EINVAL;
183  	}
184  
185  	dfl_res_off = voff + PCI_VNDR_DFLS_RES;
186  	if (dfl_res_off + (dfl_cnt * sizeof(u32)) > PCI_CFG_SPACE_EXP_SIZE) {
187  		dev_err(&pcidev->dev, "%s DFL VSEC too big for PCIe config space\n",
188  			__func__);
189  		return -EINVAL;
190  	}
191  
192  	for (i = 0, bars = 0; i < dfl_cnt; i++, dfl_res_off += sizeof(u32)) {
193  		dfl_res = GENMASK(31, 0);
194  		pci_read_config_dword(pcidev, dfl_res_off, &dfl_res);
195  
196  		bir = dfl_res & PCI_VNDR_DFLS_RES_BAR_MASK;
197  		if (bir >= PCI_STD_NUM_BARS) {
198  			dev_err(&pcidev->dev, "%s bad bir number %d\n",
199  				__func__, bir);
200  			return -EINVAL;
201  		}
202  
203  		if (bars & BIT(bir)) {
204  			dev_err(&pcidev->dev, "%s DFL for BAR %d already specified\n",
205  				__func__, bir);
206  			return -EINVAL;
207  		}
208  
209  		bars |= BIT(bir);
210  
211  		len = pci_resource_len(pcidev, bir);
212  		offset = dfl_res & PCI_VNDR_DFLS_RES_OFF_MASK;
213  		if (offset >= len) {
214  			dev_err(&pcidev->dev, "%s bad offset %u >= %pa\n",
215  				__func__, offset, &len);
216  			return -EINVAL;
217  		}
218  
219  		dev_dbg(&pcidev->dev, "%s BAR %d offset 0x%x\n", __func__, bir, offset);
220  
221  		len -= offset;
222  
223  		start = pci_resource_start(pcidev, bir) + offset;
224  
225  		dfl_fpga_enum_info_add_dfl(info, start, len);
226  	}
227  
228  	return 0;
229  }
230  
231  /* default method of finding dfls starting at offset 0 of bar 0 */
232  static int find_dfls_by_default(struct pci_dev *pcidev,
233  				struct dfl_fpga_enum_info *info)
234  {
235  	int port_num, bar, i, ret = 0;
236  	resource_size_t start, len;
237  	void __iomem *base;
238  	u32 offset;
239  	u64 v;
240  
241  	/* start to find Device Feature List from Bar 0 */
242  	base = cci_pci_ioremap_bar0(pcidev);
243  	if (!base)
244  		return -ENOMEM;
245  
246  	/*
247  	 * PF device has FME and Ports/AFUs, and VF device only has one
248  	 * Port/AFU. Check them and add related "Device Feature List" info
249  	 * for the next step enumeration.
250  	 */
251  	if (dfl_feature_is_fme(base)) {
252  		start = pci_resource_start(pcidev, 0);
253  		len = pci_resource_len(pcidev, 0);
254  
255  		dfl_fpga_enum_info_add_dfl(info, start, len);
256  
257  		/*
258  		 * find more Device Feature Lists (e.g. Ports) per information
259  		 * indicated by FME module.
260  		 */
261  		v = readq(base + FME_HDR_CAP);
262  		port_num = FIELD_GET(FME_CAP_NUM_PORTS, v);
263  
264  		WARN_ON(port_num > MAX_DFL_FPGA_PORT_NUM);
265  
266  		for (i = 0; i < port_num; i++) {
267  			v = readq(base + FME_HDR_PORT_OFST(i));
268  
269  			/* skip ports which are not implemented. */
270  			if (!(v & FME_PORT_OFST_IMP))
271  				continue;
272  
273  			/*
274  			 * add Port's Device Feature List information for next
275  			 * step enumeration.
276  			 */
277  			bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v);
278  			offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v);
279  			if (bar == FME_PORT_OFST_BAR_SKIP) {
280  				continue;
281  			} else if (bar >= PCI_STD_NUM_BARS) {
282  				dev_err(&pcidev->dev, "bad BAR %d for port %d\n",
283  					bar, i);
284  				ret = -EINVAL;
285  				break;
286  			}
287  
288  			start = pci_resource_start(pcidev, bar) + offset;
289  			len = pci_resource_len(pcidev, bar) - offset;
290  
291  			dfl_fpga_enum_info_add_dfl(info, start, len);
292  		}
293  	} else if (dfl_feature_is_port(base)) {
294  		start = pci_resource_start(pcidev, 0);
295  		len = pci_resource_len(pcidev, 0);
296  
297  		dfl_fpga_enum_info_add_dfl(info, start, len);
298  	} else {
299  		ret = -ENODEV;
300  	}
301  
302  	/* release I/O mappings for next step enumeration */
303  	pcim_iounmap_regions(pcidev, BIT(0));
304  
305  	return ret;
306  }
307  
308  /* enumerate feature devices under pci device */
309  static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
310  {
311  	struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
312  	struct dfl_fpga_enum_info *info;
313  	struct dfl_fpga_cdev *cdev;
314  	int nvec, ret = 0;
315  	int *irq_table;
316  
317  	/* allocate enumeration info via pci_dev */
318  	info = dfl_fpga_enum_info_alloc(&pcidev->dev);
319  	if (!info)
320  		return -ENOMEM;
321  
322  	/* add irq info for enumeration if the device support irq */
323  	nvec = cci_pci_alloc_irq(pcidev);
324  	if (nvec < 0) {
325  		dev_err(&pcidev->dev, "Fail to alloc irq %d.\n", nvec);
326  		ret = nvec;
327  		goto enum_info_free_exit;
328  	} else if (nvec) {
329  		irq_table = cci_pci_create_irq_table(pcidev, nvec);
330  		if (!irq_table) {
331  			ret = -ENOMEM;
332  			goto irq_free_exit;
333  		}
334  
335  		ret = dfl_fpga_enum_info_add_irq(info, nvec, irq_table);
336  		kfree(irq_table);
337  		if (ret)
338  			goto irq_free_exit;
339  	}
340  
341  	ret = find_dfls_by_vsec(pcidev, info);
342  	if (ret == -ENODEV)
343  		ret = find_dfls_by_default(pcidev, info);
344  
345  	if (ret)
346  		goto irq_free_exit;
347  
348  	/* start enumeration with prepared enumeration information */
349  	cdev = dfl_fpga_feature_devs_enumerate(info);
350  	if (IS_ERR(cdev)) {
351  		dev_err(&pcidev->dev, "Enumeration failure\n");
352  		ret = PTR_ERR(cdev);
353  		goto irq_free_exit;
354  	}
355  
356  	drvdata->cdev = cdev;
357  
358  irq_free_exit:
359  	if (ret)
360  		cci_pci_free_irq(pcidev);
361  enum_info_free_exit:
362  	dfl_fpga_enum_info_free(info);
363  
364  	return ret;
365  }
366  
367  static
368  int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
369  {
370  	int ret;
371  
372  	ret = pcim_enable_device(pcidev);
373  	if (ret < 0) {
374  		dev_err(&pcidev->dev, "Failed to enable device %d.\n", ret);
375  		return ret;
376  	}
377  
378  	pci_set_master(pcidev);
379  
380  	ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64));
381  	if (ret)
382  		ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32));
383  	if (ret) {
384  		dev_err(&pcidev->dev, "No suitable DMA support available.\n");
385  		return ret;
386  	}
387  
388  	ret = cci_init_drvdata(pcidev);
389  	if (ret) {
390  		dev_err(&pcidev->dev, "Fail to init drvdata %d.\n", ret);
391  		return ret;
392  	}
393  
394  	ret = cci_enumerate_feature_devs(pcidev);
395  	if (ret) {
396  		dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
397  		return ret;
398  	}
399  
400  	return 0;
401  }
402  
403  static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
404  {
405  	struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
406  	struct dfl_fpga_cdev *cdev = drvdata->cdev;
407  
408  	if (!num_vfs) {
409  		/*
410  		 * disable SRIOV and then put released ports back to default
411  		 * PF access mode.
412  		 */
413  		pci_disable_sriov(pcidev);
414  
415  		dfl_fpga_cdev_config_ports_pf(cdev);
416  
417  	} else {
418  		int ret;
419  
420  		/*
421  		 * before enable SRIOV, put released ports into VF access mode
422  		 * first of all.
423  		 */
424  		ret = dfl_fpga_cdev_config_ports_vf(cdev, num_vfs);
425  		if (ret)
426  			return ret;
427  
428  		ret = pci_enable_sriov(pcidev, num_vfs);
429  		if (ret) {
430  			dfl_fpga_cdev_config_ports_pf(cdev);
431  			return ret;
432  		}
433  	}
434  
435  	return num_vfs;
436  }
437  
438  static void cci_pci_remove(struct pci_dev *pcidev)
439  {
440  	if (dev_is_pf(&pcidev->dev))
441  		cci_pci_sriov_configure(pcidev, 0);
442  
443  	cci_remove_feature_devs(pcidev);
444  }
445  
446  static struct pci_driver cci_pci_driver = {
447  	.name = DRV_NAME,
448  	.id_table = cci_pcie_id_tbl,
449  	.probe = cci_pci_probe,
450  	.remove = cci_pci_remove,
451  	.sriov_configure = cci_pci_sriov_configure,
452  };
453  
454  module_pci_driver(cci_pci_driver);
455  
456  MODULE_DESCRIPTION("FPGA DFL PCIe Device Driver");
457  MODULE_AUTHOR("Intel Corporation");
458  MODULE_LICENSE("GPL v2");
459