• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Intel MIC Platform Software Stack (MPSS)
4  *
5  * Copyright(c) 2013 Intel Corporation.
6  *
7  * Intel MIC Host driver.
8  */
9 #include <linux/fs.h>
10 #include <linux/module.h>
11 #include <linux/pci.h>
12 #include <linux/poll.h>
13 
14 #include <linux/mic_common.h>
15 #include "../common/mic_dev.h"
16 #include "mic_device.h"
17 #include "mic_x100.h"
18 #include "mic_smpt.h"
19 
20 static const char mic_driver_name[] = "mic";
21 
22 static const struct pci_device_id mic_pci_tbl[] = {
23 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
24 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
25 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
26 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)},
27 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)},
28 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)},
29 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)},
30 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)},
31 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)},
32 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)},
33 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)},
34 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)},
35 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)},
36 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)},
37 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)},
38 
39 	/* required last entry */
40 	{ 0, }
41 };
42 
43 MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
44 
45 /* ID allocator for MIC devices */
46 static struct ida g_mic_ida;
47 
48 /* Initialize the device page */
mic_dp_init(struct mic_device * mdev)49 static int mic_dp_init(struct mic_device *mdev)
50 {
51 	mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL);
52 	if (!mdev->dp)
53 		return -ENOMEM;
54 
55 	mdev->dp_dma_addr = mic_map_single(mdev,
56 		mdev->dp, MIC_DP_SIZE);
57 	if (mic_map_error(mdev->dp_dma_addr)) {
58 		kfree(mdev->dp);
59 		dev_err(&mdev->pdev->dev, "%s %d err %d\n",
60 			__func__, __LINE__, -ENOMEM);
61 		return -ENOMEM;
62 	}
63 	mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
64 	mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
65 	return 0;
66 }
67 
68 /* Uninitialize the device page */
mic_dp_uninit(struct mic_device * mdev)69 static void mic_dp_uninit(struct mic_device *mdev)
70 {
71 	mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE);
72 	kfree(mdev->dp);
73 }
74 
75 /**
76  * mic_ops_init: Initialize HW specific operation tables.
77  *
78  * @mdev: pointer to mic_device instance
79  *
80  * returns none.
81  */
mic_ops_init(struct mic_device * mdev)82 static void mic_ops_init(struct mic_device *mdev)
83 {
84 	switch (mdev->family) {
85 	case MIC_FAMILY_X100:
86 		mdev->ops = &mic_x100_ops;
87 		mdev->intr_ops = &mic_x100_intr_ops;
88 		mdev->smpt_ops = &mic_x100_smpt_ops;
89 		break;
90 	default:
91 		break;
92 	}
93 }
94 
95 /**
96  * mic_get_family - Determine hardware family to which this MIC belongs.
97  *
98  * @pdev: The pci device structure
99  *
100  * returns family.
101  */
mic_get_family(struct pci_dev * pdev)102 static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
103 {
104 	enum mic_hw_family family;
105 
106 	switch (pdev->device) {
107 	case MIC_X100_PCI_DEVICE_2250:
108 	case MIC_X100_PCI_DEVICE_2251:
109 	case MIC_X100_PCI_DEVICE_2252:
110 	case MIC_X100_PCI_DEVICE_2253:
111 	case MIC_X100_PCI_DEVICE_2254:
112 	case MIC_X100_PCI_DEVICE_2255:
113 	case MIC_X100_PCI_DEVICE_2256:
114 	case MIC_X100_PCI_DEVICE_2257:
115 	case MIC_X100_PCI_DEVICE_2258:
116 	case MIC_X100_PCI_DEVICE_2259:
117 	case MIC_X100_PCI_DEVICE_225a:
118 	case MIC_X100_PCI_DEVICE_225b:
119 	case MIC_X100_PCI_DEVICE_225c:
120 	case MIC_X100_PCI_DEVICE_225d:
121 	case MIC_X100_PCI_DEVICE_225e:
122 		family = MIC_FAMILY_X100;
123 		break;
124 	default:
125 		family = MIC_FAMILY_UNKNOWN;
126 		break;
127 	}
128 	return family;
129 }
130 
131 /**
132  * mic_device_init - Allocates and initializes the MIC device structure
133  *
134  * @mdev: pointer to mic_device instance
135  * @pdev: The pci device structure
136  *
137  * returns none.
138  */
139 static void
mic_device_init(struct mic_device * mdev,struct pci_dev * pdev)140 mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
141 {
142 	mdev->pdev = pdev;
143 	mdev->family = mic_get_family(pdev);
144 	mdev->stepping = pdev->revision;
145 	mic_ops_init(mdev);
146 	mutex_init(&mdev->mic_mutex);
147 	mdev->irq_info.next_avail_src = 0;
148 }
149 
150 /**
151  * mic_probe - Device Initialization Routine
152  *
153  * @pdev: PCI device structure
154  * @ent: entry in mic_pci_tbl
155  *
156  * returns 0 on success, < 0 on failure.
157  */
mic_probe(struct pci_dev * pdev,const struct pci_device_id * ent)158 static int mic_probe(struct pci_dev *pdev,
159 		     const struct pci_device_id *ent)
160 {
161 	int rc;
162 	struct mic_device *mdev;
163 
164 	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
165 	if (!mdev) {
166 		rc = -ENOMEM;
167 		dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc);
168 		goto mdev_alloc_fail;
169 	}
170 	mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL);
171 	if (mdev->id < 0) {
172 		rc = mdev->id;
173 		dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc);
174 		goto ida_fail;
175 	}
176 
177 	mic_device_init(mdev, pdev);
178 
179 	rc = pci_enable_device(pdev);
180 	if (rc) {
181 		dev_err(&pdev->dev, "failed to enable pci device.\n");
182 		goto ida_remove;
183 	}
184 
185 	pci_set_master(pdev);
186 
187 	rc = pci_request_regions(pdev, mic_driver_name);
188 	if (rc) {
189 		dev_err(&pdev->dev, "failed to get pci regions.\n");
190 		goto disable_device;
191 	}
192 
193 	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
194 	if (rc) {
195 		dev_err(&pdev->dev, "Cannot set DMA mask\n");
196 		goto release_regions;
197 	}
198 
199 	mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar);
200 	mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar);
201 	mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar);
202 	if (!mdev->mmio.va) {
203 		dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
204 		rc = -EIO;
205 		goto release_regions;
206 	}
207 
208 	mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar);
209 	mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar);
210 	mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len);
211 	if (!mdev->aper.va) {
212 		dev_err(&pdev->dev, "Cannot remap Aperture BAR\n");
213 		rc = -EIO;
214 		goto unmap_mmio;
215 	}
216 
217 	mdev->intr_ops->intr_init(mdev);
218 	rc = mic_setup_interrupts(mdev, pdev);
219 	if (rc) {
220 		dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc);
221 		goto unmap_aper;
222 	}
223 	rc = mic_smpt_init(mdev);
224 	if (rc) {
225 		dev_err(&pdev->dev, "smpt_init failed %d\n", rc);
226 		goto free_interrupts;
227 	}
228 
229 	pci_set_drvdata(pdev, mdev);
230 
231 	rc = mic_dp_init(mdev);
232 	if (rc) {
233 		dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc);
234 		goto smpt_uninit;
235 	}
236 	mic_bootparam_init(mdev);
237 	mic_create_debug_dir(mdev);
238 
239 	mdev->cosm_dev = cosm_register_device(&mdev->pdev->dev, &cosm_hw_ops);
240 	if (IS_ERR(mdev->cosm_dev)) {
241 		rc = PTR_ERR(mdev->cosm_dev);
242 		dev_err(&pdev->dev, "cosm_add_device failed rc %d\n", rc);
243 		goto cleanup_debug_dir;
244 	}
245 	return 0;
246 cleanup_debug_dir:
247 	mic_delete_debug_dir(mdev);
248 	mic_dp_uninit(mdev);
249 smpt_uninit:
250 	mic_smpt_uninit(mdev);
251 free_interrupts:
252 	mic_free_interrupts(mdev, pdev);
253 unmap_aper:
254 	iounmap(mdev->aper.va);
255 unmap_mmio:
256 	iounmap(mdev->mmio.va);
257 release_regions:
258 	pci_release_regions(pdev);
259 disable_device:
260 	pci_disable_device(pdev);
261 ida_remove:
262 	ida_simple_remove(&g_mic_ida, mdev->id);
263 ida_fail:
264 	kfree(mdev);
265 mdev_alloc_fail:
266 	dev_err(&pdev->dev, "Probe failed rc %d\n", rc);
267 	return rc;
268 }
269 
270 /**
271  * mic_remove - Device Removal Routine
272  * mic_remove is called by the PCI subsystem to alert the driver
273  * that it should release a PCI device.
274  *
275  * @pdev: PCI device structure
276  */
mic_remove(struct pci_dev * pdev)277 static void mic_remove(struct pci_dev *pdev)
278 {
279 	struct mic_device *mdev;
280 
281 	mdev = pci_get_drvdata(pdev);
282 	if (!mdev)
283 		return;
284 
285 	cosm_unregister_device(mdev->cosm_dev);
286 	mic_delete_debug_dir(mdev);
287 	mic_dp_uninit(mdev);
288 	mic_smpt_uninit(mdev);
289 	mic_free_interrupts(mdev, pdev);
290 	iounmap(mdev->aper.va);
291 	iounmap(mdev->mmio.va);
292 	pci_release_regions(pdev);
293 	pci_disable_device(pdev);
294 	ida_simple_remove(&g_mic_ida, mdev->id);
295 	kfree(mdev);
296 }
297 
298 static struct pci_driver mic_driver = {
299 	.name = mic_driver_name,
300 	.id_table = mic_pci_tbl,
301 	.probe = mic_probe,
302 	.remove = mic_remove
303 };
304 
mic_init(void)305 static int __init mic_init(void)
306 {
307 	int ret;
308 
309 	request_module("mic_x100_dma");
310 	mic_init_debugfs();
311 	ida_init(&g_mic_ida);
312 	ret = pci_register_driver(&mic_driver);
313 	if (ret) {
314 		pr_err("pci_register_driver failed ret %d\n", ret);
315 		goto cleanup_debugfs;
316 	}
317 	return 0;
318 cleanup_debugfs:
319 	ida_destroy(&g_mic_ida);
320 	mic_exit_debugfs();
321 	return ret;
322 }
323 
mic_exit(void)324 static void __exit mic_exit(void)
325 {
326 	pci_unregister_driver(&mic_driver);
327 	ida_destroy(&g_mic_ida);
328 	mic_exit_debugfs();
329 }
330 
331 module_init(mic_init);
332 module_exit(mic_exit);
333 
334 MODULE_AUTHOR("Intel Corporation");
335 MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver");
336 MODULE_LICENSE("GPL v2");
337