blob: cc570bb6563c6b5f88d95f6ce7c3fdd867143e8f [file] [log] [blame]
Jakub Kicinski2633beb2017-02-09 09:17:28 -08001/*
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 <[email protected]>
37 * Alejandro Lucero <[email protected]>
38 * Jason McMullan <[email protected]>
39 * Rolf Neugebauer <[email protected]>
40 */
41
42#include <linux/kernel.h>
43#include <linux/module.h>
Jakub Kicinski346cfe82017-05-26 01:03:31 -070044#include <linux/mutex.h>
Jakub Kicinski2633beb2017-02-09 09:17:28 -080045#include <linux/pci.h>
46#include <linux/firmware.h>
47#include <linux/vermagic.h>
Carl Heymannd79e19f2017-12-04 23:34:12 +010048#include <linux/vmalloc.h>
Simon Horman1851f93f2017-05-26 01:03:32 -070049#include <net/devlink.h>
Jakub Kicinski2633beb2017-02-09 09:17:28 -080050
Jakub Kicinski63461a02017-02-09 09:17:38 -080051#include "nfpcore/nfp.h"
52#include "nfpcore/nfp_cpp.h"
Jakub Kicinski0bc38272017-02-19 11:58:14 -080053#include "nfpcore/nfp_nffw.h"
Jakub Kicinskice22f5a2017-04-04 16:12:30 -070054#include "nfpcore/nfp_nsp.h"
Jakub Kicinski63461a02017-02-09 09:17:38 -080055
56#include "nfpcore/nfp6000_pcie.h"
57
Simon Horman758238f2017-06-23 22:12:04 +020058#include "nfp_app.h"
Jakub Kicinski2633beb2017-02-09 09:17:28 -080059#include "nfp_main.h"
60#include "nfp_net.h"
61
62static const char nfp_driver_name[] = "nfp";
63const char nfp_driver_version[] = VERMAGIC_STRING;
64
Jakub Kicinski63461a02017-02-09 09:17:38 -080065static const struct pci_device_id nfp_pci_device_ids[] = {
Simon Horman3b473522017-02-17 08:57:54 +010066 { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000,
Jakub Kicinski63461a02017-02-09 09:17:38 -080067 PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
68 PCI_ANY_ID, 0,
69 },
Simon Horman3b473522017-02-17 08:57:54 +010070 { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP4000,
Jakub Kicinski63461a02017-02-09 09:17:38 -080071 PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
72 PCI_ANY_ID, 0,
73 },
74 { 0, } /* Required last entry. */
75};
76MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids);
77
Jakub Kicinski4cbe94f2017-09-13 10:15:59 -070078static bool nfp_board_ready(struct nfp_pf *pf)
79{
80 const char *cp;
81 long state;
82 int err;
83
84 cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state");
85 if (!cp)
86 return false;
87
88 err = kstrtol(cp, 0, &state);
89 if (err < 0)
90 return false;
91
92 return state == 15;
93}
94
95static int nfp_pf_board_state_wait(struct nfp_pf *pf)
96{
97 const unsigned long wait_until = jiffies + 10 * HZ;
98
99 while (!nfp_board_ready(pf)) {
100 if (time_is_before_eq_jiffies(wait_until)) {
101 nfp_err(pf->cpp, "NFP board initialization timeout\n");
102 return -EINVAL;
103 }
104
105 nfp_info(pf->cpp, "waiting for board initialization\n");
106 if (msleep_interruptible(500))
107 return -ERESTARTSYS;
108
109 /* Refresh cached information */
110 kfree(pf->hwinfo);
111 pf->hwinfo = nfp_hwinfo_read(pf->cpp);
112 }
113
114 return 0;
115}
116
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700117static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800118{
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800119 int err;
120
Jakub Kicinskiaf4fa7e2017-06-08 20:56:11 -0700121 pf->limit_vfs = nfp_rtsym_read_le(pf->rtbl, "nfd_vf_cfg_max_vfs", &err);
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800122 if (!err)
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700123 return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800124
125 pf->limit_vfs = ~0;
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700126 pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800127 /* Allow any setting for backwards compatibility if symbol not found */
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700128 if (err == -ENOENT)
129 return 0;
130
131 nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err);
132 return err;
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800133}
134
Jakub Kicinski63461a02017-02-09 09:17:38 -0800135static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs)
136{
137#ifdef CONFIG_PCI_IOV
138 struct nfp_pf *pf = pci_get_drvdata(pdev);
139 int err;
140
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800141 if (num_vfs > pf->limit_vfs) {
142 nfp_info(pf->cpp, "Firmware limits number of VFs to %u\n",
143 pf->limit_vfs);
Jakub Kicinskid6e1ab92017-08-22 23:22:42 -0700144 return -EINVAL;
Simon Horman758238f2017-06-23 22:12:04 +0200145 }
146
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700147 err = pci_enable_sriov(pdev, num_vfs);
Simon Horman758238f2017-06-23 22:12:04 +0200148 if (err) {
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700149 dev_warn(&pdev->dev, "Failed to enable PCI SR-IOV: %d\n", err);
Jakub Kicinskid6e1ab92017-08-22 23:22:42 -0700150 return err;
Jakub Kicinski0bc38272017-02-19 11:58:14 -0800151 }
152
Jakub Kicinskid6e1ab92017-08-22 23:22:42 -0700153 mutex_lock(&pf->lock);
154
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700155 err = nfp_app_sriov_enable(pf->app, num_vfs);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800156 if (err) {
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700157 dev_warn(&pdev->dev,
158 "App specific PCI SR-IOV configuration failed: %d\n",
159 err);
160 goto err_sriov_disable;
Jakub Kicinski63461a02017-02-09 09:17:38 -0800161 }
162
163 pf->num_vfs = num_vfs;
164
165 dev_dbg(&pdev->dev, "Created %d VFs.\n", pf->num_vfs);
166
Simon Horman758238f2017-06-23 22:12:04 +0200167 mutex_unlock(&pf->lock);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800168 return num_vfs;
Simon Horman758238f2017-06-23 22:12:04 +0200169
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700170err_sriov_disable:
Simon Horman758238f2017-06-23 22:12:04 +0200171 mutex_unlock(&pf->lock);
Jakub Kicinskid6e1ab92017-08-22 23:22:42 -0700172 pci_disable_sriov(pdev);
Simon Horman758238f2017-06-23 22:12:04 +0200173 return err;
Jakub Kicinski63461a02017-02-09 09:17:38 -0800174#endif
175 return 0;
176}
177
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700178static int nfp_pcie_sriov_disable(struct pci_dev *pdev)
Jakub Kicinski63461a02017-02-09 09:17:38 -0800179{
180#ifdef CONFIG_PCI_IOV
181 struct nfp_pf *pf = pci_get_drvdata(pdev);
182
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700183 mutex_lock(&pf->lock);
184
Jakub Kicinski63461a02017-02-09 09:17:38 -0800185 /* If the VFs are assigned we cannot shut down SR-IOV without
186 * causing issues, so just leave the hardware available but
187 * disabled
188 */
189 if (pci_vfs_assigned(pdev)) {
190 dev_warn(&pdev->dev, "Disabling while VFs assigned - VFs will not be deallocated\n");
Jakub Kicinskie3f28472017-06-27 00:50:26 -0700191 mutex_unlock(&pf->lock);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800192 return -EPERM;
193 }
194
Simon Horman758238f2017-06-23 22:12:04 +0200195 nfp_app_sriov_disable(pf->app);
196
Jakub Kicinski63461a02017-02-09 09:17:38 -0800197 pf->num_vfs = 0;
198
Jakub Kicinskid6e1ab92017-08-22 23:22:42 -0700199 mutex_unlock(&pf->lock);
200
Jakub Kicinski63461a02017-02-09 09:17:38 -0800201 pci_disable_sriov(pdev);
202 dev_dbg(&pdev->dev, "Removed VFs.\n");
Jakub Kicinski63461a02017-02-09 09:17:38 -0800203#endif
204 return 0;
205}
206
207static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
208{
209 if (num_vfs == 0)
210 return nfp_pcie_sriov_disable(pdev);
211 else
212 return nfp_pcie_sriov_enable(pdev, num_vfs);
213}
214
Jakub Kicinski1680a372017-07-26 11:09:48 -0700215static const struct firmware *
216nfp_net_fw_request(struct pci_dev *pdev, struct nfp_pf *pf, const char *name)
217{
218 const struct firmware *fw = NULL;
219 int err;
220
221 err = request_firmware_direct(&fw, name, &pdev->dev);
222 nfp_info(pf->cpp, " %s: %s\n",
223 name, err ? "not found" : "found, loading...");
224 if (err)
225 return NULL;
226
227 return fw;
228}
229
Jakub Kicinski63461a02017-02-09 09:17:38 -0800230/**
231 * nfp_net_fw_find() - Find the correct firmware image for netdev mode
232 * @pdev: PCI Device structure
233 * @pf: NFP PF Device structure
234 *
235 * Return: firmware if found and requested successfully.
236 */
237static const struct firmware *
238nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
239{
Jakub Kicinski63461a02017-02-09 09:17:38 -0800240 struct nfp_eth_table_port *port;
Jakub Kicinski1680a372017-07-26 11:09:48 -0700241 const struct firmware *fw;
Jakub Kicinski63461a02017-02-09 09:17:38 -0800242 const char *fw_model;
243 char fw_name[256];
Jakub Kicinski9511f2982017-07-26 11:09:47 -0700244 const u8 *serial;
Jakub Kicinski9511f2982017-07-26 11:09:47 -0700245 u16 interface;
Jakub Kicinski1680a372017-07-26 11:09:48 -0700246 int spc, i, j;
247
248 nfp_info(pf->cpp, "Looking for firmware file in order of priority:\n");
Jakub Kicinski63461a02017-02-09 09:17:38 -0800249
Jakub Kicinski9511f2982017-07-26 11:09:47 -0700250 /* First try to find a firmware image specific for this device */
251 interface = nfp_cpp_interface(pf->cpp);
252 nfp_cpp_serial(pf->cpp, &serial);
253 sprintf(fw_name, "netronome/serial-%pMF-%02hhx-%02hhx.nffw",
254 serial, interface >> 8, interface & 0xff);
Jakub Kicinski1680a372017-07-26 11:09:48 -0700255 fw = nfp_net_fw_request(pdev, pf, fw_name);
256 if (fw)
257 return fw;
Jakub Kicinski9511f2982017-07-26 11:09:47 -0700258
259 /* Then try the PCI name */
260 sprintf(fw_name, "netronome/pci-%s.nffw", pci_name(pdev));
Jakub Kicinski1680a372017-07-26 11:09:48 -0700261 fw = nfp_net_fw_request(pdev, pf, fw_name);
262 if (fw)
263 return fw;
Jakub Kicinski9511f2982017-07-26 11:09:47 -0700264
265 /* Finally try the card type and media */
Jakub Kicinski63461a02017-02-09 09:17:38 -0800266 if (!pf->eth_tbl) {
267 dev_err(&pdev->dev, "Error: can't identify media config\n");
268 return NULL;
269 }
270
Jakub Kicinski9baa4882017-06-08 20:56:12 -0700271 fw_model = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno");
Jakub Kicinski63461a02017-02-09 09:17:38 -0800272 if (!fw_model) {
273 dev_err(&pdev->dev, "Error: can't read part number\n");
274 return NULL;
275 }
276
277 spc = ARRAY_SIZE(fw_name);
278 spc -= snprintf(fw_name, spc, "netronome/nic_%s", fw_model);
279
280 for (i = 0; spc > 0 && i < pf->eth_tbl->count; i += j) {
281 port = &pf->eth_tbl->ports[i];
282 j = 1;
283 while (i + j < pf->eth_tbl->count &&
284 port->speed == port[j].speed)
285 j++;
286
287 spc -= snprintf(&fw_name[ARRAY_SIZE(fw_name) - spc], spc,
288 "_%dx%d", j, port->speed / 1000);
289 }
290
291 if (spc <= 0)
292 return NULL;
293
294 spc -= snprintf(&fw_name[ARRAY_SIZE(fw_name) - spc], spc, ".nffw");
295 if (spc <= 0)
296 return NULL;
297
Jakub Kicinski1680a372017-07-26 11:09:48 -0700298 return nfp_net_fw_request(pdev, pf, fw_name);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800299}
300
301/**
302 * nfp_net_fw_load() - Load the firmware image
303 * @pdev: PCI Device structure
304 * @pf: NFP PF Device structure
305 * @nsp: NFP SP handle
306 *
307 * Return: -ERRNO, 0 for no firmware loaded, 1 for firmware loaded
308 */
309static int
310nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp)
311{
312 const struct firmware *fw;
313 u16 interface;
314 int err;
315
316 interface = nfp_cpp_interface(pf->cpp);
317 if (NFP_CPP_INTERFACE_UNIT_of(interface) != 0) {
318 /* Only Unit 0 should reset or load firmware */
319 dev_info(&pdev->dev, "Firmware will be loaded by partner\n");
320 return 0;
321 }
322
323 fw = nfp_net_fw_find(pdev, pf);
324 if (!fw)
325 return 0;
326
327 dev_info(&pdev->dev, "Soft-reset, loading FW image\n");
328 err = nfp_nsp_device_soft_reset(nsp);
329 if (err < 0) {
330 dev_err(&pdev->dev, "Failed to soft reset the NFP: %d\n",
331 err);
332 goto exit_release_fw;
333 }
334
335 err = nfp_nsp_load_fw(nsp, fw);
336
337 if (err < 0) {
338 dev_err(&pdev->dev, "FW loading failed: %d\n", err);
339 goto exit_release_fw;
340 }
341
342 dev_info(&pdev->dev, "Finished loading FW image\n");
343
344exit_release_fw:
345 release_firmware(fw);
346
347 return err < 0 ? err : 1;
348}
349
Jakub Kicinski7717c312017-11-04 16:48:55 +0100350static void
351nfp_nsp_init_ports(struct pci_dev *pdev, struct nfp_pf *pf,
352 struct nfp_nsp *nsp)
353{
354 bool needs_reinit = false;
355 int i;
356
357 pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
358 if (!pf->eth_tbl)
359 return;
360
361 if (!nfp_nsp_has_mac_reinit(nsp))
362 return;
363
364 for (i = 0; i < pf->eth_tbl->count; i++)
365 needs_reinit |= pf->eth_tbl->ports[i].override_changed;
366 if (!needs_reinit)
367 return;
368
369 kfree(pf->eth_tbl);
370 if (nfp_nsp_mac_reinit(nsp))
371 dev_warn(&pdev->dev, "MAC reinit failed\n");
372
373 pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
374}
375
Jakub Kicinskia9c83f72017-02-19 11:58:08 -0800376static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
377{
378 struct nfp_nsp *nsp;
379 int err;
380
Jakub Kicinski7dbd5b72017-09-13 10:16:00 -0700381 err = nfp_resource_wait(pf->cpp, NFP_RESOURCE_NSP, 30);
382 if (err)
383 return err;
384
Jakub Kicinskia9c83f72017-02-19 11:58:08 -0800385 nsp = nfp_nsp_open(pf->cpp);
386 if (IS_ERR(nsp)) {
387 err = PTR_ERR(nsp);
388 dev_err(&pdev->dev, "Failed to access the NSP: %d\n", err);
389 return err;
390 }
391
392 err = nfp_nsp_wait(nsp);
393 if (err < 0)
394 goto exit_close_nsp;
395
Jakub Kicinski7717c312017-11-04 16:48:55 +0100396 nfp_nsp_init_ports(pdev, pf, nsp);
Jakub Kicinskia9c83f72017-02-19 11:58:08 -0800397
David Bruneczeefbde72017-05-28 17:53:00 -0700398 pf->nspi = __nfp_nsp_identify(nsp);
399 if (pf->nspi)
400 dev_info(&pdev->dev, "BSP: %s\n", pf->nspi->version);
David Brunecz010e2f92017-04-22 20:17:54 -0700401
Jakub Kicinskia9c83f72017-02-19 11:58:08 -0800402 err = nfp_fw_load(pdev, pf, nsp);
403 if (err < 0) {
Jakub Kicinski47eaa232017-05-31 08:06:51 -0700404 kfree(pf->nspi);
Jakub Kicinskia9c83f72017-02-19 11:58:08 -0800405 kfree(pf->eth_tbl);
406 dev_err(&pdev->dev, "Failed to load FW\n");
407 goto exit_close_nsp;
408 }
409
410 pf->fw_loaded = !!err;
411 err = 0;
412
413exit_close_nsp:
414 nfp_nsp_close(nsp);
415
416 return err;
417}
418
Jakub Kicinski63461a02017-02-09 09:17:38 -0800419static void nfp_fw_unload(struct nfp_pf *pf)
420{
421 struct nfp_nsp *nsp;
422 int err;
423
424 nsp = nfp_nsp_open(pf->cpp);
425 if (IS_ERR(nsp)) {
426 nfp_err(pf->cpp, "Reset failed, can't open NSP\n");
427 return;
428 }
429
430 err = nfp_nsp_device_soft_reset(nsp);
431 if (err < 0)
432 dev_warn(&pf->pdev->dev, "Couldn't unload firmware: %d\n", err);
433 else
434 dev_info(&pf->pdev->dev, "Firmware safely unloaded\n");
435
436 nfp_nsp_close(nsp);
437}
438
439static int nfp_pci_probe(struct pci_dev *pdev,
440 const struct pci_device_id *pci_id)
441{
Simon Horman1851f93f2017-05-26 01:03:32 -0700442 struct devlink *devlink;
Jakub Kicinski63461a02017-02-09 09:17:38 -0800443 struct nfp_pf *pf;
444 int err;
445
446 err = pci_enable_device(pdev);
447 if (err < 0)
448 return err;
449
450 pci_set_master(pdev);
451
452 err = dma_set_mask_and_coherent(&pdev->dev,
453 DMA_BIT_MASK(NFP_NET_MAX_DMA_BITS));
454 if (err)
455 goto err_pci_disable;
456
457 err = pci_request_regions(pdev, nfp_driver_name);
458 if (err < 0) {
459 dev_err(&pdev->dev, "Unable to reserve pci resources.\n");
460 goto err_pci_disable;
461 }
462
Simon Horman1851f93f2017-05-26 01:03:32 -0700463 devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf));
464 if (!devlink) {
Jakub Kicinski63461a02017-02-09 09:17:38 -0800465 err = -ENOMEM;
466 goto err_rel_regions;
467 }
Simon Horman1851f93f2017-05-26 01:03:32 -0700468 pf = devlink_priv(devlink);
Jakub Kicinskid4e7f092017-05-22 10:59:24 -0700469 INIT_LIST_HEAD(&pf->vnics);
Jakub Kicinski3eb3b742017-05-22 10:59:31 -0700470 INIT_LIST_HEAD(&pf->ports);
Jakub Kicinski346cfe82017-05-26 01:03:31 -0700471 mutex_init(&pf->lock);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800472 pci_set_drvdata(pdev, pf);
473 pf->pdev = pdev;
474
Jakub Kicinski6d48ceb2017-06-27 00:50:27 -0700475 pf->wq = alloc_workqueue("nfp-%s", 0, 2, pci_name(pdev));
476 if (!pf->wq) {
477 err = -ENOMEM;
478 goto err_pci_priv_unset;
479 }
480
Jakub Kicinski63461a02017-02-09 09:17:38 -0800481 pf->cpp = nfp_cpp_from_nfp6000_pcie(pdev);
482 if (IS_ERR_OR_NULL(pf->cpp)) {
483 err = PTR_ERR(pf->cpp);
484 if (err >= 0)
485 err = -ENOMEM;
486 goto err_disable_msix;
487 }
488
Jakub Kicinski9baa4882017-06-08 20:56:12 -0700489 pf->hwinfo = nfp_hwinfo_read(pf->cpp);
490
Jakub Kicinski64db09e2017-02-19 11:58:09 -0800491 dev_info(&pdev->dev, "Assembly: %s%s%s-%s CPLD: %s\n",
Jakub Kicinski9baa4882017-06-08 20:56:12 -0700492 nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor"),
493 nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"),
494 nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial"),
495 nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"),
496 nfp_hwinfo_lookup(pf->hwinfo, "cpld.version"));
Jakub Kicinski64db09e2017-02-19 11:58:09 -0800497
Jakub Kicinski4cbe94f2017-09-13 10:15:59 -0700498 err = nfp_pf_board_state_wait(pf);
499 if (err)
500 goto err_hwinfo_free;
501
Simon Horman1851f93f2017-05-26 01:03:32 -0700502 err = nfp_nsp_init(pdev, pf);
503 if (err)
Jakub Kicinskibcc93a22018-01-17 18:50:57 -0800504 goto err_hwinfo_free;
Simon Horman1851f93f2017-05-26 01:03:32 -0700505
Jakub Kicinski0be40e62017-06-08 20:56:13 -0700506 pf->mip = nfp_mip_open(pf->cpp);
507 pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip);
Jakub Kicinskiaf4fa7e2017-06-08 20:56:11 -0700508
Carl Heymannd79e19f2017-12-04 23:34:12 +0100509 pf->dump_flag = NFP_DUMP_NSP_DIAG;
510 pf->dumpspec = nfp_net_dump_load_dumpspec(pf->cpp, pf->rtbl);
511
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700512 err = nfp_pcie_sriov_read_nfd_limit(pf);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800513 if (err)
514 goto err_fw_unload;
515
Jakub Kicinski0dc78622017-06-27 00:50:25 -0700516 pf->num_vfs = pci_num_vf(pdev);
517 if (pf->num_vfs > pf->limit_vfs) {
518 dev_err(&pdev->dev,
519 "Error: %d VFs already enabled, but loaded FW can only support %d\n",
520 pf->num_vfs, pf->limit_vfs);
Wei Yongjune58decc2018-01-23 02:10:27 +0000521 err = -EINVAL;
Jakub Kicinski0dc78622017-06-27 00:50:25 -0700522 goto err_fw_unload;
523 }
524
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700525 err = nfp_net_pci_probe(pf);
526 if (err)
527 goto err_sriov_unlimit;
528
David Bruneczeefbde72017-05-28 17:53:00 -0700529 err = nfp_hwmon_register(pf);
530 if (err) {
531 dev_err(&pdev->dev, "Failed to register hwmon info\n");
532 goto err_net_remove;
533 }
534
Jakub Kicinski63461a02017-02-09 09:17:38 -0800535 return 0;
536
David Bruneczeefbde72017-05-28 17:53:00 -0700537err_net_remove:
538 nfp_net_pci_remove(pf);
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700539err_sriov_unlimit:
540 pci_sriov_set_totalvfs(pf->pdev, 0);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800541err_fw_unload:
Jakub Kicinskiaf4fa7e2017-06-08 20:56:11 -0700542 kfree(pf->rtbl);
Jakub Kicinski0be40e62017-06-08 20:56:13 -0700543 nfp_mip_close(pf->mip);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800544 if (pf->fw_loaded)
545 nfp_fw_unload(pf);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800546 kfree(pf->eth_tbl);
David Bruneczeefbde72017-05-28 17:53:00 -0700547 kfree(pf->nspi);
Carl Heymannd79e19f2017-12-04 23:34:12 +0100548 vfree(pf->dumpspec);
Jakub Kicinski9baa4882017-06-08 20:56:12 -0700549err_hwinfo_free:
550 kfree(pf->hwinfo);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800551 nfp_cpp_free(pf->cpp);
552err_disable_msix:
Jakub Kicinski6d48ceb2017-06-27 00:50:27 -0700553 destroy_workqueue(pf->wq);
554err_pci_priv_unset:
Jakub Kicinski63461a02017-02-09 09:17:38 -0800555 pci_set_drvdata(pdev, NULL);
Jakub Kicinski346cfe82017-05-26 01:03:31 -0700556 mutex_destroy(&pf->lock);
Simon Horman1851f93f2017-05-26 01:03:32 -0700557 devlink_free(devlink);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800558err_rel_regions:
559 pci_release_regions(pdev);
560err_pci_disable:
561 pci_disable_device(pdev);
562
563 return err;
564}
565
566static void nfp_pci_remove(struct pci_dev *pdev)
567{
568 struct nfp_pf *pf = pci_get_drvdata(pdev);
Simon Horman1851f93f2017-05-26 01:03:32 -0700569
David Bruneczeefbde72017-05-28 17:53:00 -0700570 nfp_hwmon_unregister(pf);
571
Jakub Kicinski63461a02017-02-09 09:17:38 -0800572 nfp_pcie_sriov_disable(pdev);
Jakub Kicinski651e1f22017-05-28 17:52:54 -0700573 pci_sriov_set_totalvfs(pf->pdev, 0);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800574
Jakub Kicinskibcc93a22018-01-17 18:50:57 -0800575 nfp_net_pci_remove(pf);
Simon Horman1851f93f2017-05-26 01:03:32 -0700576
Carl Heymannd79e19f2017-12-04 23:34:12 +0100577 vfree(pf->dumpspec);
Jakub Kicinskiaf4fa7e2017-06-08 20:56:11 -0700578 kfree(pf->rtbl);
Jakub Kicinski0be40e62017-06-08 20:56:13 -0700579 nfp_mip_close(pf->mip);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800580 if (pf->fw_loaded)
581 nfp_fw_unload(pf);
582
Jakub Kicinski6d48ceb2017-06-27 00:50:27 -0700583 destroy_workqueue(pf->wq);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800584 pci_set_drvdata(pdev, NULL);
Jakub Kicinski9baa4882017-06-08 20:56:12 -0700585 kfree(pf->hwinfo);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800586 nfp_cpp_free(pf->cpp);
587
588 kfree(pf->eth_tbl);
David Bruneczeefbde72017-05-28 17:53:00 -0700589 kfree(pf->nspi);
Jakub Kicinski346cfe82017-05-26 01:03:31 -0700590 mutex_destroy(&pf->lock);
Jakub Kicinskibcc93a22018-01-17 18:50:57 -0800591 devlink_free(priv_to_devlink(pf));
Jakub Kicinski63461a02017-02-09 09:17:38 -0800592 pci_release_regions(pdev);
593 pci_disable_device(pdev);
594}
595
596static struct pci_driver nfp_pci_driver = {
597 .name = nfp_driver_name,
598 .id_table = nfp_pci_device_ids,
599 .probe = nfp_pci_probe,
600 .remove = nfp_pci_remove,
601 .sriov_configure = nfp_pcie_sriov_configure,
602};
603
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800604static int __init nfp_main_init(void)
605{
606 int err;
607
608 pr_info("%s: NFP PCIe Driver, Copyright (C) 2014-2017 Netronome Systems\n",
609 nfp_driver_name);
610
611 nfp_net_debugfs_create();
612
Jakub Kicinski63461a02017-02-09 09:17:38 -0800613 err = pci_register_driver(&nfp_pci_driver);
614 if (err < 0)
615 goto err_destroy_debugfs;
616
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800617 err = pci_register_driver(&nfp_netvf_pci_driver);
618 if (err)
Jakub Kicinski63461a02017-02-09 09:17:38 -0800619 goto err_unreg_pf;
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800620
621 return err;
622
Jakub Kicinski63461a02017-02-09 09:17:38 -0800623err_unreg_pf:
624 pci_unregister_driver(&nfp_pci_driver);
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800625err_destroy_debugfs:
626 nfp_net_debugfs_destroy();
627 return err;
628}
629
630static void __exit nfp_main_exit(void)
631{
632 pci_unregister_driver(&nfp_netvf_pci_driver);
Jakub Kicinski63461a02017-02-09 09:17:38 -0800633 pci_unregister_driver(&nfp_pci_driver);
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800634 nfp_net_debugfs_destroy();
635}
636
637module_init(nfp_main_init);
638module_exit(nfp_main_exit);
639
Jakub Kicinski63461a02017-02-09 09:17:38 -0800640MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_1x40.nffw");
641MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_4x10.nffw");
642MODULE_FIRMWARE("netronome/nic_AMDA0096-0001_2x10.nffw");
643MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_2x40.nffw");
644MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_4x10_1x40.nffw");
645MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_8x10.nffw");
646MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x10.nffw");
647MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw");
648
Jakub Kicinski2633beb2017-02-09 09:17:28 -0800649MODULE_AUTHOR("Netronome Systems <[email protected]>");
650MODULE_LICENSE("GPL");
651MODULE_DESCRIPTION("The Netronome Flow Processor (NFP) driver.");