| .. | .. |
|---|
| 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 | | - */ |
|---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
|---|
| 2 | +/* Copyright (C) 2015-2018 Netronome Systems, Inc. */ |
|---|
| 33 | 3 | |
|---|
| 34 | 4 | /* |
|---|
| 35 | 5 | * nfp_main.c |
|---|
| .. | .. |
|---|
| 44 | 14 | #include <linux/mutex.h> |
|---|
| 45 | 15 | #include <linux/pci.h> |
|---|
| 46 | 16 | #include <linux/firmware.h> |
|---|
| 47 | | -#include <linux/vermagic.h> |
|---|
| 48 | 17 | #include <linux/vmalloc.h> |
|---|
| 49 | 18 | #include <net/devlink.h> |
|---|
| 50 | 19 | |
|---|
| .. | .. |
|---|
| 61 | 30 | #include "nfp_net.h" |
|---|
| 62 | 31 | |
|---|
| 63 | 32 | static const char nfp_driver_name[] = "nfp"; |
|---|
| 64 | | -const char nfp_driver_version[] = VERMAGIC_STRING; |
|---|
| 65 | 33 | |
|---|
| 66 | 34 | static const struct pci_device_id nfp_pci_device_ids[] = { |
|---|
| 67 | 35 | { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000, |
|---|
| 36 | + PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID, |
|---|
| 37 | + PCI_ANY_ID, 0, |
|---|
| 38 | + }, |
|---|
| 39 | + { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP5000, |
|---|
| 68 | 40 | PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID, |
|---|
| 69 | 41 | PCI_ANY_ID, 0, |
|---|
| 70 | 42 | }, |
|---|
| .. | .. |
|---|
| 112 | 84 | int nfp_mbox_cmd(struct nfp_pf *pf, u32 cmd, void *in_data, u64 in_length, |
|---|
| 113 | 85 | void *out_data, u64 out_length) |
|---|
| 114 | 86 | { |
|---|
| 115 | | - unsigned long long addr; |
|---|
| 116 | 87 | unsigned long err_at; |
|---|
| 117 | 88 | u64 max_data_sz; |
|---|
| 118 | 89 | u32 val = 0; |
|---|
| 119 | | - u32 cpp_id; |
|---|
| 120 | 90 | int n, err; |
|---|
| 121 | 91 | |
|---|
| 122 | 92 | if (!pf->mbox) |
|---|
| 123 | 93 | return -EOPNOTSUPP; |
|---|
| 124 | 94 | |
|---|
| 125 | | - cpp_id = NFP_CPP_ISLAND_ID(pf->mbox->target, NFP_CPP_ACTION_RW, 0, |
|---|
| 126 | | - pf->mbox->domain); |
|---|
| 127 | | - addr = pf->mbox->addr; |
|---|
| 128 | | - max_data_sz = pf->mbox->size - NFP_MBOX_SYM_MIN_SIZE; |
|---|
| 95 | + max_data_sz = nfp_rtsym_size(pf->mbox) - NFP_MBOX_SYM_MIN_SIZE; |
|---|
| 129 | 96 | |
|---|
| 130 | 97 | /* Check if cmd field is clear */ |
|---|
| 131 | | - err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, &val); |
|---|
| 98 | + err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_CMD, &val); |
|---|
| 132 | 99 | if (err || val) { |
|---|
| 133 | 100 | nfp_warn(pf->cpp, "failed to issue command (%u): %u, err: %d\n", |
|---|
| 134 | 101 | cmd, val, err); |
|---|
| .. | .. |
|---|
| 136 | 103 | } |
|---|
| 137 | 104 | |
|---|
| 138 | 105 | in_length = min(in_length, max_data_sz); |
|---|
| 139 | | - n = nfp_cpp_write(pf->cpp, cpp_id, addr + NFP_MBOX_DATA, |
|---|
| 140 | | - in_data, in_length); |
|---|
| 106 | + n = nfp_rtsym_write(pf->cpp, pf->mbox, NFP_MBOX_DATA, in_data, |
|---|
| 107 | + in_length); |
|---|
| 141 | 108 | if (n != in_length) |
|---|
| 142 | 109 | return -EIO; |
|---|
| 143 | 110 | /* Write data_len and wipe reserved */ |
|---|
| 144 | | - err = nfp_cpp_writeq(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN, |
|---|
| 145 | | - in_length); |
|---|
| 111 | + err = nfp_rtsym_writeq(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, in_length); |
|---|
| 146 | 112 | if (err) |
|---|
| 147 | 113 | return err; |
|---|
| 148 | 114 | |
|---|
| 149 | 115 | /* Read back for ordering */ |
|---|
| 150 | | - err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN, &val); |
|---|
| 116 | + err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, &val); |
|---|
| 151 | 117 | if (err) |
|---|
| 152 | 118 | return err; |
|---|
| 153 | 119 | |
|---|
| 154 | 120 | /* Write cmd and wipe return value */ |
|---|
| 155 | | - err = nfp_cpp_writeq(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, cmd); |
|---|
| 121 | + err = nfp_rtsym_writeq(pf->cpp, pf->mbox, NFP_MBOX_CMD, cmd); |
|---|
| 156 | 122 | if (err) |
|---|
| 157 | 123 | return err; |
|---|
| 158 | 124 | |
|---|
| 159 | 125 | err_at = jiffies + 5 * HZ; |
|---|
| 160 | 126 | while (true) { |
|---|
| 161 | 127 | /* Wait for command to go to 0 (NFP_MBOX_NO_CMD) */ |
|---|
| 162 | | - err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, &val); |
|---|
| 128 | + err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_CMD, &val); |
|---|
| 163 | 129 | if (err) |
|---|
| 164 | 130 | return err; |
|---|
| 165 | 131 | if (!val) |
|---|
| .. | .. |
|---|
| 172 | 138 | } |
|---|
| 173 | 139 | |
|---|
| 174 | 140 | /* Copy output if any (could be error info, do it before reading ret) */ |
|---|
| 175 | | - err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN, &val); |
|---|
| 141 | + err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, &val); |
|---|
| 176 | 142 | if (err) |
|---|
| 177 | 143 | return err; |
|---|
| 178 | 144 | |
|---|
| 179 | 145 | out_length = min_t(u32, val, min(out_length, max_data_sz)); |
|---|
| 180 | | - n = nfp_cpp_read(pf->cpp, cpp_id, addr + NFP_MBOX_DATA, |
|---|
| 181 | | - out_data, out_length); |
|---|
| 146 | + n = nfp_rtsym_read(pf->cpp, pf->mbox, NFP_MBOX_DATA, |
|---|
| 147 | + out_data, out_length); |
|---|
| 182 | 148 | if (n != out_length) |
|---|
| 183 | 149 | return -EIO; |
|---|
| 184 | 150 | |
|---|
| 185 | 151 | /* Check if there is an error */ |
|---|
| 186 | | - err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_RET, &val); |
|---|
| 152 | + err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_RET, &val); |
|---|
| 187 | 153 | if (err) |
|---|
| 188 | 154 | return err; |
|---|
| 189 | 155 | if (val) |
|---|
| .. | .. |
|---|
| 326 | 292 | |
|---|
| 327 | 293 | static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs) |
|---|
| 328 | 294 | { |
|---|
| 295 | + if (!pci_get_drvdata(pdev)) |
|---|
| 296 | + return -ENOENT; |
|---|
| 297 | + |
|---|
| 329 | 298 | if (num_vfs == 0) |
|---|
| 330 | 299 | return nfp_pcie_sriov_disable(pdev); |
|---|
| 331 | 300 | else |
|---|
| 332 | 301 | return nfp_pcie_sriov_enable(pdev, num_vfs); |
|---|
| 302 | +} |
|---|
| 303 | + |
|---|
| 304 | +int nfp_flash_update_common(struct nfp_pf *pf, const char *path, |
|---|
| 305 | + struct netlink_ext_ack *extack) |
|---|
| 306 | +{ |
|---|
| 307 | + struct device *dev = &pf->pdev->dev; |
|---|
| 308 | + const struct firmware *fw; |
|---|
| 309 | + struct nfp_nsp *nsp; |
|---|
| 310 | + int err; |
|---|
| 311 | + |
|---|
| 312 | + nsp = nfp_nsp_open(pf->cpp); |
|---|
| 313 | + if (IS_ERR(nsp)) { |
|---|
| 314 | + err = PTR_ERR(nsp); |
|---|
| 315 | + if (extack) |
|---|
| 316 | + NL_SET_ERR_MSG_MOD(extack, "can't access NSP"); |
|---|
| 317 | + else |
|---|
| 318 | + dev_err(dev, "Failed to access the NSP: %d\n", err); |
|---|
| 319 | + return err; |
|---|
| 320 | + } |
|---|
| 321 | + |
|---|
| 322 | + err = request_firmware_direct(&fw, path, dev); |
|---|
| 323 | + if (err) { |
|---|
| 324 | + NL_SET_ERR_MSG_MOD(extack, |
|---|
| 325 | + "unable to read flash file from disk"); |
|---|
| 326 | + goto exit_close_nsp; |
|---|
| 327 | + } |
|---|
| 328 | + |
|---|
| 329 | + dev_info(dev, "Please be patient while writing flash image: %s\n", |
|---|
| 330 | + path); |
|---|
| 331 | + |
|---|
| 332 | + err = nfp_nsp_write_flash(nsp, fw); |
|---|
| 333 | + if (err < 0) |
|---|
| 334 | + goto exit_release_fw; |
|---|
| 335 | + dev_info(dev, "Finished writing flash image\n"); |
|---|
| 336 | + err = 0; |
|---|
| 337 | + |
|---|
| 338 | +exit_release_fw: |
|---|
| 339 | + release_firmware(fw); |
|---|
| 340 | +exit_close_nsp: |
|---|
| 341 | + nfp_nsp_close(nsp); |
|---|
| 342 | + return err; |
|---|
| 333 | 343 | } |
|---|
| 334 | 344 | |
|---|
| 335 | 345 | static const struct firmware * |
|---|
| .. | .. |
|---|
| 340 | 350 | |
|---|
| 341 | 351 | err = request_firmware_direct(&fw, name, &pdev->dev); |
|---|
| 342 | 352 | nfp_info(pf->cpp, " %s: %s\n", |
|---|
| 343 | | - name, err ? "not found" : "found, loading..."); |
|---|
| 353 | + name, err ? "not found" : "found"); |
|---|
| 344 | 354 | if (err) |
|---|
| 345 | 355 | return NULL; |
|---|
| 346 | 356 | |
|---|
| .. | .. |
|---|
| 418 | 428 | return nfp_net_fw_request(pdev, pf, fw_name); |
|---|
| 419 | 429 | } |
|---|
| 420 | 430 | |
|---|
| 431 | +static int |
|---|
| 432 | +nfp_get_fw_policy_value(struct pci_dev *pdev, struct nfp_nsp *nsp, |
|---|
| 433 | + const char *key, const char *default_val, int max_val, |
|---|
| 434 | + int *value) |
|---|
| 435 | +{ |
|---|
| 436 | + char hwinfo[64]; |
|---|
| 437 | + long hi_val; |
|---|
| 438 | + int err; |
|---|
| 439 | + |
|---|
| 440 | + snprintf(hwinfo, sizeof(hwinfo), key); |
|---|
| 441 | + err = nfp_nsp_hwinfo_lookup_optional(nsp, hwinfo, sizeof(hwinfo), |
|---|
| 442 | + default_val); |
|---|
| 443 | + if (err) |
|---|
| 444 | + return err; |
|---|
| 445 | + |
|---|
| 446 | + err = kstrtol(hwinfo, 0, &hi_val); |
|---|
| 447 | + if (err || hi_val < 0 || hi_val > max_val) { |
|---|
| 448 | + dev_warn(&pdev->dev, |
|---|
| 449 | + "Invalid value '%s' from '%s', ignoring\n", |
|---|
| 450 | + hwinfo, key); |
|---|
| 451 | + err = kstrtol(default_val, 0, &hi_val); |
|---|
| 452 | + } |
|---|
| 453 | + |
|---|
| 454 | + *value = hi_val; |
|---|
| 455 | + return err; |
|---|
| 456 | +} |
|---|
| 457 | + |
|---|
| 421 | 458 | /** |
|---|
| 422 | | - * nfp_net_fw_load() - Load the firmware image |
|---|
| 459 | + * nfp_fw_load() - Load the firmware image |
|---|
| 423 | 460 | * @pdev: PCI Device structure |
|---|
| 424 | 461 | * @pf: NFP PF Device structure |
|---|
| 425 | 462 | * @nsp: NFP SP handle |
|---|
| .. | .. |
|---|
| 429 | 466 | static int |
|---|
| 430 | 467 | nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp) |
|---|
| 431 | 468 | { |
|---|
| 432 | | - const struct firmware *fw; |
|---|
| 469 | + bool do_reset, fw_loaded = false; |
|---|
| 470 | + const struct firmware *fw = NULL; |
|---|
| 471 | + int err, reset, policy, ifcs = 0; |
|---|
| 472 | + char *token, *ptr; |
|---|
| 473 | + char hwinfo[64]; |
|---|
| 433 | 474 | u16 interface; |
|---|
| 434 | | - int err; |
|---|
| 475 | + |
|---|
| 476 | + snprintf(hwinfo, sizeof(hwinfo), "abi_drv_load_ifc"); |
|---|
| 477 | + err = nfp_nsp_hwinfo_lookup_optional(nsp, hwinfo, sizeof(hwinfo), |
|---|
| 478 | + NFP_NSP_DRV_LOAD_IFC_DEFAULT); |
|---|
| 479 | + if (err) |
|---|
| 480 | + return err; |
|---|
| 435 | 481 | |
|---|
| 436 | 482 | interface = nfp_cpp_interface(pf->cpp); |
|---|
| 437 | | - if (NFP_CPP_INTERFACE_UNIT_of(interface) != 0) { |
|---|
| 438 | | - /* Only Unit 0 should reset or load firmware */ |
|---|
| 483 | + ptr = hwinfo; |
|---|
| 484 | + while ((token = strsep(&ptr, ","))) { |
|---|
| 485 | + unsigned long interface_hi; |
|---|
| 486 | + |
|---|
| 487 | + err = kstrtoul(token, 0, &interface_hi); |
|---|
| 488 | + if (err) { |
|---|
| 489 | + dev_err(&pdev->dev, |
|---|
| 490 | + "Failed to parse interface '%s': %d\n", |
|---|
| 491 | + token, err); |
|---|
| 492 | + return err; |
|---|
| 493 | + } |
|---|
| 494 | + |
|---|
| 495 | + ifcs++; |
|---|
| 496 | + if (interface == interface_hi) |
|---|
| 497 | + break; |
|---|
| 498 | + } |
|---|
| 499 | + |
|---|
| 500 | + if (!token) { |
|---|
| 439 | 501 | dev_info(&pdev->dev, "Firmware will be loaded by partner\n"); |
|---|
| 440 | 502 | return 0; |
|---|
| 441 | 503 | } |
|---|
| 442 | 504 | |
|---|
| 505 | + err = nfp_get_fw_policy_value(pdev, nsp, "abi_drv_reset", |
|---|
| 506 | + NFP_NSP_DRV_RESET_DEFAULT, |
|---|
| 507 | + NFP_NSP_DRV_RESET_NEVER, &reset); |
|---|
| 508 | + if (err) |
|---|
| 509 | + return err; |
|---|
| 510 | + |
|---|
| 511 | + err = nfp_get_fw_policy_value(pdev, nsp, "app_fw_from_flash", |
|---|
| 512 | + NFP_NSP_APP_FW_LOAD_DEFAULT, |
|---|
| 513 | + NFP_NSP_APP_FW_LOAD_PREF, &policy); |
|---|
| 514 | + if (err) |
|---|
| 515 | + return err; |
|---|
| 516 | + |
|---|
| 443 | 517 | fw = nfp_net_fw_find(pdev, pf); |
|---|
| 444 | | - if (!fw) |
|---|
| 445 | | - return 0; |
|---|
| 518 | + do_reset = reset == NFP_NSP_DRV_RESET_ALWAYS || |
|---|
| 519 | + (fw && reset == NFP_NSP_DRV_RESET_DISK); |
|---|
| 446 | 520 | |
|---|
| 447 | | - dev_info(&pdev->dev, "Soft-reset, loading FW image\n"); |
|---|
| 448 | | - err = nfp_nsp_device_soft_reset(nsp); |
|---|
| 449 | | - if (err < 0) { |
|---|
| 450 | | - dev_err(&pdev->dev, "Failed to soft reset the NFP: %d\n", |
|---|
| 451 | | - err); |
|---|
| 452 | | - goto exit_release_fw; |
|---|
| 521 | + if (do_reset) { |
|---|
| 522 | + dev_info(&pdev->dev, "Soft-resetting the NFP\n"); |
|---|
| 523 | + err = nfp_nsp_device_soft_reset(nsp); |
|---|
| 524 | + if (err < 0) { |
|---|
| 525 | + dev_err(&pdev->dev, |
|---|
| 526 | + "Failed to soft reset the NFP: %d\n", err); |
|---|
| 527 | + goto exit_release_fw; |
|---|
| 528 | + } |
|---|
| 453 | 529 | } |
|---|
| 454 | 530 | |
|---|
| 455 | | - err = nfp_nsp_load_fw(nsp, fw); |
|---|
| 531 | + if (fw && policy != NFP_NSP_APP_FW_LOAD_FLASH) { |
|---|
| 532 | + if (nfp_nsp_has_fw_loaded(nsp) && nfp_nsp_fw_loaded(nsp)) |
|---|
| 533 | + goto exit_release_fw; |
|---|
| 456 | 534 | |
|---|
| 457 | | - if (err < 0) { |
|---|
| 458 | | - dev_err(&pdev->dev, "FW loading failed: %d\n", err); |
|---|
| 459 | | - goto exit_release_fw; |
|---|
| 535 | + err = nfp_nsp_load_fw(nsp, fw); |
|---|
| 536 | + if (err < 0) { |
|---|
| 537 | + dev_err(&pdev->dev, "FW loading failed: %d\n", |
|---|
| 538 | + err); |
|---|
| 539 | + goto exit_release_fw; |
|---|
| 540 | + } |
|---|
| 541 | + dev_info(&pdev->dev, "Finished loading FW image\n"); |
|---|
| 542 | + fw_loaded = true; |
|---|
| 543 | + } else if (policy != NFP_NSP_APP_FW_LOAD_DISK && |
|---|
| 544 | + nfp_nsp_has_stored_fw_load(nsp)) { |
|---|
| 545 | + |
|---|
| 546 | + /* Don't propagate this error to stick with legacy driver |
|---|
| 547 | + * behavior, failure will be detected later during init. |
|---|
| 548 | + */ |
|---|
| 549 | + if (!nfp_nsp_load_stored_fw(nsp)) |
|---|
| 550 | + dev_info(&pdev->dev, "Finished loading stored FW image\n"); |
|---|
| 551 | + |
|---|
| 552 | + /* Don't flag the fw_loaded in this case since other devices |
|---|
| 553 | + * may reuse the firmware when configured this way |
|---|
| 554 | + */ |
|---|
| 555 | + } else { |
|---|
| 556 | + dev_warn(&pdev->dev, "Didn't load firmware, please update flash or reconfigure card\n"); |
|---|
| 460 | 557 | } |
|---|
| 461 | | - |
|---|
| 462 | | - dev_info(&pdev->dev, "Finished loading FW image\n"); |
|---|
| 463 | 558 | |
|---|
| 464 | 559 | exit_release_fw: |
|---|
| 465 | 560 | release_firmware(fw); |
|---|
| 466 | 561 | |
|---|
| 467 | | - return err < 0 ? err : 1; |
|---|
| 562 | + /* We don't want to unload firmware when other devices may still be |
|---|
| 563 | + * dependent on it, which could be the case if there are multiple |
|---|
| 564 | + * devices that could load firmware. |
|---|
| 565 | + */ |
|---|
| 566 | + if (fw_loaded && ifcs == 1) |
|---|
| 567 | + pf->unload_fw_on_remove = true; |
|---|
| 568 | + |
|---|
| 569 | + return err < 0 ? err : fw_loaded; |
|---|
| 468 | 570 | } |
|---|
| 469 | 571 | |
|---|
| 470 | 572 | static void |
|---|
| .. | .. |
|---|
| 566 | 668 | /* Optional per-PCI PF mailbox */ |
|---|
| 567 | 669 | snprintf(pf_symbol, sizeof(pf_symbol), NFP_MBOX_SYM_NAME, pf_id); |
|---|
| 568 | 670 | pf->mbox = nfp_rtsym_lookup(pf->rtbl, pf_symbol); |
|---|
| 569 | | - if (pf->mbox && pf->mbox->size < NFP_MBOX_SYM_MIN_SIZE) { |
|---|
| 671 | + if (pf->mbox && nfp_rtsym_size(pf->mbox) < NFP_MBOX_SYM_MIN_SIZE) { |
|---|
| 570 | 672 | nfp_err(pf->cpp, "PF mailbox symbol too small: %llu < %d\n", |
|---|
| 571 | | - pf->mbox->size, NFP_MBOX_SYM_MIN_SIZE); |
|---|
| 673 | + nfp_rtsym_size(pf->mbox), NFP_MBOX_SYM_MIN_SIZE); |
|---|
| 572 | 674 | return -EINVAL; |
|---|
| 573 | 675 | } |
|---|
| 574 | 676 | |
|---|
| .. | .. |
|---|
| 581 | 683 | struct devlink *devlink; |
|---|
| 582 | 684 | struct nfp_pf *pf; |
|---|
| 583 | 685 | int err; |
|---|
| 686 | + |
|---|
| 687 | + if (pdev->vendor == PCI_VENDOR_ID_NETRONOME && |
|---|
| 688 | + pdev->device == PCI_DEVICE_ID_NETRONOME_NFP6000_VF) |
|---|
| 689 | + dev_warn(&pdev->dev, "Binding NFP VF device to the NFP PF driver, the VF driver is called 'nfp_netvf'\n"); |
|---|
| 584 | 690 | |
|---|
| 585 | 691 | err = pci_enable_device(pdev); |
|---|
| 586 | 692 | if (err < 0) |
|---|
| .. | .. |
|---|
| 686 | 792 | err_fw_unload: |
|---|
| 687 | 793 | kfree(pf->rtbl); |
|---|
| 688 | 794 | nfp_mip_close(pf->mip); |
|---|
| 689 | | - if (pf->fw_loaded) |
|---|
| 795 | + if (pf->unload_fw_on_remove) |
|---|
| 690 | 796 | nfp_fw_unload(pf); |
|---|
| 691 | 797 | kfree(pf->eth_tbl); |
|---|
| 692 | 798 | kfree(pf->nspi); |
|---|
| .. | .. |
|---|
| 709 | 815 | return err; |
|---|
| 710 | 816 | } |
|---|
| 711 | 817 | |
|---|
| 712 | | -static void nfp_pci_remove(struct pci_dev *pdev) |
|---|
| 818 | +static void __nfp_pci_shutdown(struct pci_dev *pdev, bool unload_fw) |
|---|
| 713 | 819 | { |
|---|
| 714 | | - struct nfp_pf *pf = pci_get_drvdata(pdev); |
|---|
| 820 | + struct nfp_pf *pf; |
|---|
| 821 | + |
|---|
| 822 | + pf = pci_get_drvdata(pdev); |
|---|
| 823 | + if (!pf) |
|---|
| 824 | + return; |
|---|
| 715 | 825 | |
|---|
| 716 | 826 | nfp_hwmon_unregister(pf); |
|---|
| 717 | 827 | |
|---|
| .. | .. |
|---|
| 722 | 832 | vfree(pf->dumpspec); |
|---|
| 723 | 833 | kfree(pf->rtbl); |
|---|
| 724 | 834 | nfp_mip_close(pf->mip); |
|---|
| 725 | | - if (pf->fw_loaded) |
|---|
| 835 | + if (unload_fw && pf->unload_fw_on_remove) |
|---|
| 726 | 836 | nfp_fw_unload(pf); |
|---|
| 727 | 837 | |
|---|
| 728 | 838 | destroy_workqueue(pf->wq); |
|---|
| .. | .. |
|---|
| 738 | 848 | pci_disable_device(pdev); |
|---|
| 739 | 849 | } |
|---|
| 740 | 850 | |
|---|
| 851 | +static void nfp_pci_remove(struct pci_dev *pdev) |
|---|
| 852 | +{ |
|---|
| 853 | + __nfp_pci_shutdown(pdev, true); |
|---|
| 854 | +} |
|---|
| 855 | + |
|---|
| 856 | +static void nfp_pci_shutdown(struct pci_dev *pdev) |
|---|
| 857 | +{ |
|---|
| 858 | + __nfp_pci_shutdown(pdev, false); |
|---|
| 859 | +} |
|---|
| 860 | + |
|---|
| 741 | 861 | static struct pci_driver nfp_pci_driver = { |
|---|
| 742 | 862 | .name = nfp_driver_name, |
|---|
| 743 | 863 | .id_table = nfp_pci_device_ids, |
|---|
| 744 | 864 | .probe = nfp_pci_probe, |
|---|
| 745 | 865 | .remove = nfp_pci_remove, |
|---|
| 866 | + .shutdown = nfp_pci_shutdown, |
|---|
| 746 | 867 | .sriov_configure = nfp_pcie_sriov_configure, |
|---|
| 747 | 868 | }; |
|---|
| 748 | 869 | |
|---|
| .. | .. |
|---|
| 782 | 903 | module_init(nfp_main_init); |
|---|
| 783 | 904 | module_exit(nfp_main_exit); |
|---|
| 784 | 905 | |
|---|
| 906 | +MODULE_FIRMWARE("netronome/nic_AMDA0058-0011_2x40.nffw"); |
|---|
| 907 | +MODULE_FIRMWARE("netronome/nic_AMDA0058-0012_2x40.nffw"); |
|---|
| 785 | 908 | MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_1x40.nffw"); |
|---|
| 786 | 909 | MODULE_FIRMWARE("netronome/nic_AMDA0081-0001_4x10.nffw"); |
|---|
| 787 | 910 | MODULE_FIRMWARE("netronome/nic_AMDA0096-0001_2x10.nffw"); |
|---|
| .. | .. |
|---|
| 795 | 918 | MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); |
|---|
| 796 | 919 | MODULE_LICENSE("GPL"); |
|---|
| 797 | 920 | MODULE_DESCRIPTION("The Netronome Flow Processor (NFP) driver."); |
|---|
| 798 | | -MODULE_VERSION(UTS_RELEASE); |
|---|