]>
Commit | Line | Data |
---|---|---|
2633beb9 JK |
1 | /* |
2 | * Copyright (C) 2015-2017 Netronome Systems, Inc. | |
3 | * | |
4 | * This software is dual licensed under the GNU General License Version 2, | |
5 | * June 1991 as shown in the file COPYING in the top-level directory of this | |
6 | * source tree or the BSD 2-Clause License provided below. You have the | |
7 | * option to license this software under the complete terms of either license. | |
8 | * | |
9 | * The BSD 2-Clause License: | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or | |
12 | * without modification, are permitted provided that the following | |
13 | * conditions are met: | |
14 | * | |
15 | * 1. Redistributions of source code must retain the above | |
16 | * copyright notice, this list of conditions and the following | |
17 | * disclaimer. | |
18 | * | |
19 | * 2. Redistributions in binary form must reproduce the above | |
20 | * copyright notice, this list of conditions and the following | |
21 | * disclaimer in the documentation and/or other materials | |
22 | * provided with the distribution. | |
23 | * | |
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
31 | * SOFTWARE. | |
32 | */ | |
33 | ||
34 | /* | |
35 | * nfp_main.c | |
36 | * Authors: Jakub Kicinski <jakub.kicinski@netronome.com> | |
37 | * Alejandro Lucero <alejandro.lucero@netronome.com> | |
38 | * Jason McMullan <jason.mcmullan@netronome.com> | |
39 | * Rolf Neugebauer <rolf.neugebauer@netronome.com> | |
40 | */ | |
41 | ||
42 | #include <linux/kernel.h> | |
43 | #include <linux/module.h> | |
346cfe84 | 44 | #include <linux/mutex.h> |
2633beb9 JK |
45 | #include <linux/pci.h> |
46 | #include <linux/firmware.h> | |
47 | #include <linux/vermagic.h> | |
1851f93f | 48 | #include <net/devlink.h> |
2633beb9 | 49 | |
63461a02 JK |
50 | #include "nfpcore/nfp.h" |
51 | #include "nfpcore/nfp_cpp.h" | |
0bc3827f | 52 | #include "nfpcore/nfp_nffw.h" |
ce22f5a2 | 53 | #include "nfpcore/nfp_nsp.h" |
63461a02 JK |
54 | |
55 | #include "nfpcore/nfp6000_pcie.h" | |
56 | ||
758238f2 | 57 | #include "nfp_app.h" |
2633beb9 JK |
58 | #include "nfp_main.h" |
59 | #include "nfp_net.h" | |
60 | ||
61 | static const char nfp_driver_name[] = "nfp"; | |
62 | const char nfp_driver_version[] = VERMAGIC_STRING; | |
63 | ||
63461a02 | 64 | static const struct pci_device_id nfp_pci_device_ids[] = { |
3b473528 | 65 | { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000, |
63461a02 JK |
66 | PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID, |
67 | PCI_ANY_ID, 0, | |
68 | }, | |
3b473528 | 69 | { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP4000, |
63461a02 JK |
70 | PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID, |
71 | PCI_ANY_ID, 0, | |
72 | }, | |
73 | { 0, } /* Required last entry. */ | |
74 | }; | |
75 | MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids); | |
76 | ||
651e1f2f | 77 | static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) |
0bc3827f | 78 | { |
0bc3827f JK |
79 | int err; |
80 | ||
af4fa7ea | 81 | pf->limit_vfs = nfp_rtsym_read_le(pf->rtbl, "nfd_vf_cfg_max_vfs", &err); |
0bc3827f | 82 | if (!err) |
651e1f2f | 83 | return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); |
0bc3827f JK |
84 | |
85 | pf->limit_vfs = ~0; | |
651e1f2f | 86 | pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */ |
0bc3827f | 87 | /* Allow any setting for backwards compatibility if symbol not found */ |
651e1f2f JK |
88 | if (err == -ENOENT) |
89 | return 0; | |
90 | ||
91 | nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err); | |
92 | return err; | |
0bc3827f JK |
93 | } |
94 | ||
63461a02 JK |
95 | static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs) |
96 | { | |
97 | #ifdef CONFIG_PCI_IOV | |
98 | struct nfp_pf *pf = pci_get_drvdata(pdev); | |
99 | int err; | |
100 | ||
758238f2 SH |
101 | mutex_lock(&pf->lock); |
102 | ||
0bc3827f JK |
103 | if (num_vfs > pf->limit_vfs) { |
104 | nfp_info(pf->cpp, "Firmware limits number of VFs to %u\n", | |
105 | pf->limit_vfs); | |
758238f2 SH |
106 | err = -EINVAL; |
107 | goto err_unlock; | |
108 | } | |
109 | ||
e3f28473 | 110 | err = pci_enable_sriov(pdev, num_vfs); |
758238f2 | 111 | if (err) { |
e3f28473 | 112 | dev_warn(&pdev->dev, "Failed to enable PCI SR-IOV: %d\n", err); |
758238f2 | 113 | goto err_unlock; |
0bc3827f JK |
114 | } |
115 | ||
e3f28473 | 116 | err = nfp_app_sriov_enable(pf->app, num_vfs); |
63461a02 | 117 | if (err) { |
e3f28473 JK |
118 | dev_warn(&pdev->dev, |
119 | "App specific PCI SR-IOV configuration failed: %d\n", | |
120 | err); | |
121 | goto err_sriov_disable; | |
63461a02 JK |
122 | } |
123 | ||
124 | pf->num_vfs = num_vfs; | |
125 | ||
126 | dev_dbg(&pdev->dev, "Created %d VFs.\n", pf->num_vfs); | |
127 | ||
758238f2 | 128 | mutex_unlock(&pf->lock); |
63461a02 | 129 | return num_vfs; |
758238f2 | 130 | |
e3f28473 JK |
131 | err_sriov_disable: |
132 | pci_disable_sriov(pdev); | |
758238f2 SH |
133 | err_unlock: |
134 | mutex_unlock(&pf->lock); | |
135 | return err; | |
63461a02 JK |
136 | #endif |
137 | return 0; | |
138 | } | |
139 | ||
e3f28473 | 140 | static int nfp_pcie_sriov_disable(struct pci_dev *pdev) |
63461a02 JK |
141 | { |
142 | #ifdef CONFIG_PCI_IOV | |
143 | struct nfp_pf *pf = pci_get_drvdata(pdev); | |
144 | ||
e3f28473 JK |
145 | mutex_lock(&pf->lock); |
146 | ||
63461a02 JK |
147 | /* If the VFs are assigned we cannot shut down SR-IOV without |
148 | * causing issues, so just leave the hardware available but | |
149 | * disabled | |
150 | */ | |
151 | if (pci_vfs_assigned(pdev)) { | |
152 | dev_warn(&pdev->dev, "Disabling while VFs assigned - VFs will not be deallocated\n"); | |
e3f28473 | 153 | mutex_unlock(&pf->lock); |
63461a02 JK |
154 | return -EPERM; |
155 | } | |
156 | ||
758238f2 SH |
157 | nfp_app_sriov_disable(pf->app); |
158 | ||
63461a02 JK |
159 | pf->num_vfs = 0; |
160 | ||
161 | pci_disable_sriov(pdev); | |
162 | dev_dbg(&pdev->dev, "Removed VFs.\n"); | |
63461a02 | 163 | |
758238f2 | 164 | mutex_unlock(&pf->lock); |
e3f28473 JK |
165 | #endif |
166 | return 0; | |
758238f2 SH |
167 | } |
168 | ||
63461a02 JK |
169 | static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs) |
170 | { | |
171 | if (num_vfs == 0) | |
172 | return nfp_pcie_sriov_disable(pdev); | |
173 | else | |
174 | return nfp_pcie_sriov_enable(pdev, num_vfs); | |
175 | } | |
176 | ||
177 | /** | |
178 | * nfp_net_fw_find() - Find the correct firmware image for netdev mode | |
179 | * @pdev: PCI Device structure | |
180 | * @pf: NFP PF Device structure | |
181 | * | |
182 | * Return: firmware if found and requested successfully. | |
183 | */ | |
184 | static const struct firmware * | |
185 | nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf) | |
186 | { | |
187 | const struct firmware *fw = NULL; | |
188 | struct nfp_eth_table_port *port; | |
189 | const char *fw_model; | |
190 | char fw_name[256]; | |
191 | int spc, err = 0; | |
192 | int i, j; | |
193 | ||
194 | if (!pf->eth_tbl) { | |
195 | dev_err(&pdev->dev, "Error: can't identify media config\n"); | |
196 | return NULL; | |
197 | } | |
198 | ||
9baa4885 | 199 | fw_model = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"); |
63461a02 JK |
200 | if (!fw_model) { |
201 | dev_err(&pdev->dev, "Error: can't read part number\n"); | |
202 | return NULL; | |
203 | } | |
204 | ||
205 | spc = ARRAY_SIZE(fw_name); | |
206 | spc -= snprintf(fw_name, spc, "netronome/nic_%s", fw_model); | |
207 | ||
208 | for (i = 0; spc > 0 && i < pf->eth_tbl->count; i += j) { | |
209 | port = &pf->eth_tbl->ports[i]; | |
210 | j = 1; | |
211 | while (i + j < pf->eth_tbl->count && | |
212 | port->speed == port[j].speed) | |
213 | j++; | |
214 | ||
215 | spc -= snprintf(&fw_name[ARRAY_SIZE(fw_name) - spc], spc, | |
216 | "_%dx%d", j, port->speed / 1000); | |
217 | } | |
218 | ||
219 | if (spc <= 0) | |
220 | return NULL; | |
221 | ||
222 | spc -= snprintf(&fw_name[ARRAY_SIZE(fw_name) - spc], spc, ".nffw"); | |
223 | if (spc <= 0) | |
224 | return NULL; | |
225 | ||
226 | err = request_firmware(&fw, fw_name, &pdev->dev); | |
227 | if (err) | |
228 | return NULL; | |
229 | ||
230 | dev_info(&pdev->dev, "Loading FW image: %s\n", fw_name); | |
231 | ||
232 | return fw; | |
233 | } | |
234 | ||
235 | /** | |
236 | * nfp_net_fw_load() - Load the firmware image | |
237 | * @pdev: PCI Device structure | |
238 | * @pf: NFP PF Device structure | |
239 | * @nsp: NFP SP handle | |
240 | * | |
241 | * Return: -ERRNO, 0 for no firmware loaded, 1 for firmware loaded | |
242 | */ | |
243 | static int | |
244 | nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp) | |
245 | { | |
246 | const struct firmware *fw; | |
247 | u16 interface; | |
248 | int err; | |
249 | ||
250 | interface = nfp_cpp_interface(pf->cpp); | |
251 | if (NFP_CPP_INTERFACE_UNIT_of(interface) != 0) { | |
252 | /* Only Unit 0 should reset or load firmware */ | |
253 | dev_info(&pdev->dev, "Firmware will be loaded by partner\n"); | |
254 | return 0; | |
255 | } | |
256 | ||
257 | fw = nfp_net_fw_find(pdev, pf); | |
258 | if (!fw) | |
259 | return 0; | |
260 | ||
261 | dev_info(&pdev->dev, "Soft-reset, loading FW image\n"); | |
262 | err = nfp_nsp_device_soft_reset(nsp); | |
263 | if (err < 0) { | |
264 | dev_err(&pdev->dev, "Failed to soft reset the NFP: %d\n", | |
265 | err); | |
266 | goto exit_release_fw; | |
267 | } | |
268 | ||
269 | err = nfp_nsp_load_fw(nsp, fw); | |
270 | ||
271 | if (err < 0) { | |
272 | dev_err(&pdev->dev, "FW loading failed: %d\n", err); | |
273 | goto exit_release_fw; | |
274 | } | |
275 | ||
276 | dev_info(&pdev->dev, "Finished loading FW image\n"); | |
277 | ||
278 | exit_release_fw: | |
279 | release_firmware(fw); | |
280 | ||
281 | return err < 0 ? err : 1; | |
282 | } | |
283 | ||
a9c83f7b JK |
284 | static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf) |
285 | { | |
286 | struct nfp_nsp *nsp; | |
287 | int err; | |
288 | ||
289 | nsp = nfp_nsp_open(pf->cpp); | |
290 | if (IS_ERR(nsp)) { | |
291 | err = PTR_ERR(nsp); | |
292 | dev_err(&pdev->dev, "Failed to access the NSP: %d\n", err); | |
293 | return err; | |
294 | } | |
295 | ||
296 | err = nfp_nsp_wait(nsp); | |
297 | if (err < 0) | |
298 | goto exit_close_nsp; | |
299 | ||
300 | pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp); | |
301 | ||
eefbde7e DB |
302 | pf->nspi = __nfp_nsp_identify(nsp); |
303 | if (pf->nspi) | |
304 | dev_info(&pdev->dev, "BSP: %s\n", pf->nspi->version); | |
010e2f9c | 305 | |
a9c83f7b JK |
306 | err = nfp_fw_load(pdev, pf, nsp); |
307 | if (err < 0) { | |
47eaa23b | 308 | kfree(pf->nspi); |
a9c83f7b JK |
309 | kfree(pf->eth_tbl); |
310 | dev_err(&pdev->dev, "Failed to load FW\n"); | |
311 | goto exit_close_nsp; | |
312 | } | |
313 | ||
314 | pf->fw_loaded = !!err; | |
315 | err = 0; | |
316 | ||
317 | exit_close_nsp: | |
318 | nfp_nsp_close(nsp); | |
319 | ||
320 | return err; | |
321 | } | |
322 | ||
63461a02 JK |
323 | static void nfp_fw_unload(struct nfp_pf *pf) |
324 | { | |
325 | struct nfp_nsp *nsp; | |
326 | int err; | |
327 | ||
328 | nsp = nfp_nsp_open(pf->cpp); | |
329 | if (IS_ERR(nsp)) { | |
330 | nfp_err(pf->cpp, "Reset failed, can't open NSP\n"); | |
331 | return; | |
332 | } | |
333 | ||
334 | err = nfp_nsp_device_soft_reset(nsp); | |
335 | if (err < 0) | |
336 | dev_warn(&pf->pdev->dev, "Couldn't unload firmware: %d\n", err); | |
337 | else | |
338 | dev_info(&pf->pdev->dev, "Firmware safely unloaded\n"); | |
339 | ||
340 | nfp_nsp_close(nsp); | |
341 | } | |
342 | ||
343 | static int nfp_pci_probe(struct pci_dev *pdev, | |
344 | const struct pci_device_id *pci_id) | |
345 | { | |
1851f93f | 346 | struct devlink *devlink; |
63461a02 JK |
347 | struct nfp_pf *pf; |
348 | int err; | |
349 | ||
350 | err = pci_enable_device(pdev); | |
351 | if (err < 0) | |
352 | return err; | |
353 | ||
354 | pci_set_master(pdev); | |
355 | ||
356 | err = dma_set_mask_and_coherent(&pdev->dev, | |
357 | DMA_BIT_MASK(NFP_NET_MAX_DMA_BITS)); | |
358 | if (err) | |
359 | goto err_pci_disable; | |
360 | ||
361 | err = pci_request_regions(pdev, nfp_driver_name); | |
362 | if (err < 0) { | |
363 | dev_err(&pdev->dev, "Unable to reserve pci resources.\n"); | |
364 | goto err_pci_disable; | |
365 | } | |
366 | ||
1851f93f SH |
367 | devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf)); |
368 | if (!devlink) { | |
63461a02 JK |
369 | err = -ENOMEM; |
370 | goto err_rel_regions; | |
371 | } | |
1851f93f | 372 | pf = devlink_priv(devlink); |
d4e7f092 | 373 | INIT_LIST_HEAD(&pf->vnics); |
3eb3b74a | 374 | INIT_LIST_HEAD(&pf->ports); |
346cfe84 | 375 | mutex_init(&pf->lock); |
63461a02 JK |
376 | pci_set_drvdata(pdev, pf); |
377 | pf->pdev = pdev; | |
378 | ||
6d48ceb2 JK |
379 | pf->wq = alloc_workqueue("nfp-%s", 0, 2, pci_name(pdev)); |
380 | if (!pf->wq) { | |
381 | err = -ENOMEM; | |
382 | goto err_pci_priv_unset; | |
383 | } | |
384 | ||
63461a02 JK |
385 | pf->cpp = nfp_cpp_from_nfp6000_pcie(pdev); |
386 | if (IS_ERR_OR_NULL(pf->cpp)) { | |
387 | err = PTR_ERR(pf->cpp); | |
388 | if (err >= 0) | |
389 | err = -ENOMEM; | |
390 | goto err_disable_msix; | |
391 | } | |
392 | ||
9baa4885 JK |
393 | pf->hwinfo = nfp_hwinfo_read(pf->cpp); |
394 | ||
64db09ed | 395 | dev_info(&pdev->dev, "Assembly: %s%s%s-%s CPLD: %s\n", |
9baa4885 JK |
396 | nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor"), |
397 | nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"), | |
398 | nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial"), | |
399 | nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"), | |
400 | nfp_hwinfo_lookup(pf->hwinfo, "cpld.version")); | |
64db09ed | 401 | |
1851f93f | 402 | err = devlink_register(devlink, &pdev->dev); |
a9c83f7b | 403 | if (err) |
9baa4885 | 404 | goto err_hwinfo_free; |
63461a02 | 405 | |
1851f93f SH |
406 | err = nfp_nsp_init(pdev, pf); |
407 | if (err) | |
408 | goto err_devlink_unreg; | |
409 | ||
0be40e66 JK |
410 | pf->mip = nfp_mip_open(pf->cpp); |
411 | pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip); | |
af4fa7ea | 412 | |
651e1f2f JK |
413 | err = nfp_pcie_sriov_read_nfd_limit(pf); |
414 | if (err) | |
415 | goto err_fw_unload; | |
0bc3827f | 416 | |
0dc78621 JK |
417 | pf->num_vfs = pci_num_vf(pdev); |
418 | if (pf->num_vfs > pf->limit_vfs) { | |
419 | dev_err(&pdev->dev, | |
420 | "Error: %d VFs already enabled, but loaded FW can only support %d\n", | |
421 | pf->num_vfs, pf->limit_vfs); | |
422 | goto err_fw_unload; | |
423 | } | |
424 | ||
63461a02 JK |
425 | err = nfp_net_pci_probe(pf); |
426 | if (err) | |
651e1f2f | 427 | goto err_sriov_unlimit; |
63461a02 | 428 | |
eefbde7e DB |
429 | err = nfp_hwmon_register(pf); |
430 | if (err) { | |
431 | dev_err(&pdev->dev, "Failed to register hwmon info\n"); | |
432 | goto err_net_remove; | |
433 | } | |
434 | ||
63461a02 JK |
435 | return 0; |
436 | ||
eefbde7e DB |
437 | err_net_remove: |
438 | nfp_net_pci_remove(pf); | |
651e1f2f JK |
439 | err_sriov_unlimit: |
440 | pci_sriov_set_totalvfs(pf->pdev, 0); | |
63461a02 | 441 | err_fw_unload: |
af4fa7ea | 442 | kfree(pf->rtbl); |
0be40e66 | 443 | nfp_mip_close(pf->mip); |
63461a02 JK |
444 | if (pf->fw_loaded) |
445 | nfp_fw_unload(pf); | |
63461a02 | 446 | kfree(pf->eth_tbl); |
eefbde7e | 447 | kfree(pf->nspi); |
1851f93f SH |
448 | err_devlink_unreg: |
449 | devlink_unregister(devlink); | |
9baa4885 JK |
450 | err_hwinfo_free: |
451 | kfree(pf->hwinfo); | |
63461a02 JK |
452 | nfp_cpp_free(pf->cpp); |
453 | err_disable_msix: | |
6d48ceb2 JK |
454 | destroy_workqueue(pf->wq); |
455 | err_pci_priv_unset: | |
63461a02 | 456 | pci_set_drvdata(pdev, NULL); |
346cfe84 | 457 | mutex_destroy(&pf->lock); |
1851f93f | 458 | devlink_free(devlink); |
63461a02 JK |
459 | err_rel_regions: |
460 | pci_release_regions(pdev); | |
461 | err_pci_disable: | |
462 | pci_disable_device(pdev); | |
463 | ||
464 | return err; | |
465 | } | |
466 | ||
467 | static void nfp_pci_remove(struct pci_dev *pdev) | |
468 | { | |
469 | struct nfp_pf *pf = pci_get_drvdata(pdev); | |
1851f93f SH |
470 | struct devlink *devlink; |
471 | ||
eefbde7e DB |
472 | nfp_hwmon_unregister(pf); |
473 | ||
1851f93f | 474 | devlink = priv_to_devlink(pf); |
63461a02 | 475 | |
e3f28473 JK |
476 | nfp_net_pci_remove(pf); |
477 | ||
63461a02 | 478 | nfp_pcie_sriov_disable(pdev); |
651e1f2f | 479 | pci_sriov_set_totalvfs(pf->pdev, 0); |
63461a02 | 480 | |
1851f93f SH |
481 | devlink_unregister(devlink); |
482 | ||
af4fa7ea | 483 | kfree(pf->rtbl); |
0be40e66 | 484 | nfp_mip_close(pf->mip); |
63461a02 JK |
485 | if (pf->fw_loaded) |
486 | nfp_fw_unload(pf); | |
487 | ||
6d48ceb2 | 488 | destroy_workqueue(pf->wq); |
63461a02 | 489 | pci_set_drvdata(pdev, NULL); |
9baa4885 | 490 | kfree(pf->hwinfo); |
63461a02 JK |
491 | nfp_cpp_free(pf->cpp); |
492 | ||
493 | kfree(pf->eth_tbl); | |
eefbde7e | 494 | kfree(pf->nspi); |
346cfe84 | 495 | mutex_destroy(&pf->lock); |
1851f93f | 496 | devlink_free(devlink); |
63461a02 JK |
497 | pci_release_regions(pdev); |
498 | pci_disable_device(pdev); | |
499 | } | |
500 | ||
501 | static struct pci_driver nfp_pci_driver = { | |
502 | .name = nfp_driver_name, | |
503 | .id_table = nfp_pci_device_ids, | |
504 | .probe = nfp_pci_probe, | |
505 | .remove = nfp_pci_remove, | |
506 | .sriov_configure = nfp_pcie_sriov_configure, | |
507 | }; | |
508 | ||
2633beb9 JK |
509 | static int __init nfp_main_init(void) |
510 | { | |
511 | int err; | |
512 | ||
513 | pr_info("%s: NFP PCIe Driver, Copyright (C) 2014-2017 Netronome Systems\n", | |
514 | nfp_driver_name); | |
515 | ||
516 | nfp_net_debugfs_create(); | |
517 | ||
63461a02 JK |
518 | err = pci_register_driver(&nfp_pci_driver); |
519 | if (err < 0) | |
520 | goto err_destroy_debugfs; | |
521 | ||
2633beb9 JK |
522 | err = pci_register_driver(&nfp_netvf_pci_driver); |
523 | if (err) | |
63461a02 | 524 | goto err_unreg_pf; |
2633beb9 JK |
525 | |
526 | return err; | |
527 | ||
63461a02 JK |
528 | err_unreg_pf: |
529 | pci_unregister_driver(&nfp_pci_driver); | |
2633beb9 JK |
530 | err_destroy_debugfs: |
531 | nfp_net_debugfs_destroy(); | |
532 | return err; | |
533 | } | |
534 | ||
535 | static void __exit nfp_main_exit(void) | |
536 | { | |
537 | pci_unregister_driver(&nfp_netvf_pci_driver); | |
63461a02 | 538 | pci_unregister_driver(&nfp_pci_driver); |
2633beb9 JK |
539 | nfp_net_debugfs_destroy(); |
540 | } | |
541 | ||
542 | module_init(nfp_main_init); | |
543 | module_exit(nfp_main_exit); | |
544 | ||
63461a02 JK |
545 | MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_1x40.nffw"); |
546 | MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_4x10.nffw"); | |
547 | MODULE_FIRMWARE("netronome/nic_AMDA0096-0001_2x10.nffw"); | |
548 | MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_2x40.nffw"); | |
549 | MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_4x10_1x40.nffw"); | |
550 | MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_8x10.nffw"); | |
551 | MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x10.nffw"); | |
552 | MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw"); | |
553 | ||
2633beb9 JK |
554 | MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); |
555 | MODULE_LICENSE("GPL"); | |
556 | MODULE_DESCRIPTION("The Netronome Flow Processor (NFP) driver."); |