Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (C) 2015-2018 Netronome Systems, Inc. */
0003 
0004 /*
0005  * nfp_net_main.c
0006  * Netronome network device driver: Main entry point
0007  * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
0008  *          Alejandro Lucero <alejandro.lucero@netronome.com>
0009  *          Jason McMullan <jason.mcmullan@netronome.com>
0010  *          Rolf Neugebauer <rolf.neugebauer@netronome.com>
0011  */
0012 
0013 #include <linux/etherdevice.h>
0014 #include <linux/kernel.h>
0015 #include <linux/init.h>
0016 #include <linux/lockdep.h>
0017 #include <linux/pci.h>
0018 #include <linux/pci_regs.h>
0019 #include <linux/msi.h>
0020 #include <linux/random.h>
0021 #include <linux/rtnetlink.h>
0022 
0023 #include "nfpcore/nfp.h"
0024 #include "nfpcore/nfp_cpp.h"
0025 #include "nfpcore/nfp_dev.h"
0026 #include "nfpcore/nfp_nffw.h"
0027 #include "nfpcore/nfp_nsp.h"
0028 #include "nfpcore/nfp6000_pcie.h"
0029 #include "nfp_app.h"
0030 #include "nfp_net_ctrl.h"
0031 #include "nfp_net_sriov.h"
0032 #include "nfp_net.h"
0033 #include "nfp_main.h"
0034 #include "nfp_port.h"
0035 
0036 #define NFP_PF_CSR_SLICE_SIZE   (32 * 1024)
0037 
0038 /**
0039  * nfp_net_get_mac_addr() - Get the MAC address.
0040  * @pf:       NFP PF handle
0041  * @netdev:   net_device to set MAC address on
0042  * @port:     NFP port structure
0043  *
0044  * First try to get the MAC address from NSP ETH table. If that
0045  * fails generate a random address.
0046  */
0047 void
0048 nfp_net_get_mac_addr(struct nfp_pf *pf, struct net_device *netdev,
0049              struct nfp_port *port)
0050 {
0051     struct nfp_eth_table_port *eth_port;
0052 
0053     eth_port = __nfp_port_get_eth_port(port);
0054     if (!eth_port) {
0055         eth_hw_addr_random(netdev);
0056         return;
0057     }
0058 
0059     eth_hw_addr_set(netdev, eth_port->mac_addr);
0060     ether_addr_copy(netdev->perm_addr, eth_port->mac_addr);
0061 }
0062 
0063 static struct nfp_eth_table_port *
0064 nfp_net_find_port(struct nfp_eth_table *eth_tbl, unsigned int index)
0065 {
0066     int i;
0067 
0068     for (i = 0; eth_tbl && i < eth_tbl->count; i++)
0069         if (eth_tbl->ports[i].index == index)
0070             return &eth_tbl->ports[i];
0071 
0072     return NULL;
0073 }
0074 
0075 static int nfp_net_pf_get_num_ports(struct nfp_pf *pf)
0076 {
0077     return nfp_pf_rtsym_read_optional(pf, "nfd_cfg_pf%u_num_ports", 1);
0078 }
0079 
0080 static int nfp_net_pf_get_app_id(struct nfp_pf *pf)
0081 {
0082     return nfp_pf_rtsym_read_optional(pf, "_pf%u_net_app_id",
0083                       NFP_APP_CORE_NIC);
0084 }
0085 
0086 static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
0087 {
0088     if (nfp_net_is_data_vnic(nn))
0089         nfp_app_vnic_free(pf->app, nn);
0090     nfp_port_free(nn->port);
0091     list_del(&nn->vnic_list);
0092     pf->num_vnics--;
0093     nfp_net_free(nn);
0094 }
0095 
0096 static void nfp_net_pf_free_vnics(struct nfp_pf *pf)
0097 {
0098     struct nfp_net *nn, *next;
0099 
0100     list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list)
0101         if (nfp_net_is_data_vnic(nn))
0102             nfp_net_pf_free_vnic(pf, nn);
0103 }
0104 
0105 static struct nfp_net *
0106 nfp_net_pf_alloc_vnic(struct nfp_pf *pf, bool needs_netdev,
0107               void __iomem *ctrl_bar, void __iomem *qc_bar,
0108               int stride, unsigned int id)
0109 {
0110     u32 tx_base, rx_base, n_tx_rings, n_rx_rings;
0111     struct nfp_net *nn;
0112     int err;
0113 
0114     tx_base = readl(ctrl_bar + NFP_NET_CFG_START_TXQ);
0115     rx_base = readl(ctrl_bar + NFP_NET_CFG_START_RXQ);
0116     n_tx_rings = readl(ctrl_bar + NFP_NET_CFG_MAX_TXRINGS);
0117     n_rx_rings = readl(ctrl_bar + NFP_NET_CFG_MAX_RXRINGS);
0118 
0119     /* Allocate and initialise the vNIC */
0120     nn = nfp_net_alloc(pf->pdev, pf->dev_info, ctrl_bar, needs_netdev,
0121                n_tx_rings, n_rx_rings);
0122     if (IS_ERR(nn))
0123         return nn;
0124 
0125     nn->app = pf->app;
0126     nn->tx_bar = qc_bar + tx_base * NFP_QCP_QUEUE_ADDR_SZ;
0127     nn->rx_bar = qc_bar + rx_base * NFP_QCP_QUEUE_ADDR_SZ;
0128     nn->dp.is_vf = 0;
0129     nn->stride_rx = stride;
0130     nn->stride_tx = stride;
0131 
0132     if (needs_netdev) {
0133         err = nfp_app_vnic_alloc(pf->app, nn, id);
0134         if (err) {
0135             nfp_net_free(nn);
0136             return ERR_PTR(err);
0137         }
0138     }
0139 
0140     pf->num_vnics++;
0141     list_add_tail(&nn->vnic_list, &pf->vnics);
0142 
0143     return nn;
0144 }
0145 
0146 static int
0147 nfp_net_pf_init_vnic(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id)
0148 {
0149     int err;
0150 
0151     nn->id = id;
0152 
0153     if (nn->port) {
0154         err = nfp_devlink_port_register(pf->app, nn->port);
0155         if (err)
0156             return err;
0157     }
0158 
0159     err = nfp_net_init(nn);
0160     if (err)
0161         goto err_devlink_port_clean;
0162 
0163     nfp_net_debugfs_vnic_add(nn, pf->ddir);
0164 
0165     if (nn->port)
0166         nfp_devlink_port_type_eth_set(nn->port);
0167 
0168     nfp_net_info(nn);
0169 
0170     if (nfp_net_is_data_vnic(nn)) {
0171         err = nfp_app_vnic_init(pf->app, nn);
0172         if (err)
0173             goto err_devlink_port_type_clean;
0174     }
0175 
0176     return 0;
0177 
0178 err_devlink_port_type_clean:
0179     if (nn->port)
0180         nfp_devlink_port_type_clear(nn->port);
0181     nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
0182     nfp_net_clean(nn);
0183 err_devlink_port_clean:
0184     if (nn->port)
0185         nfp_devlink_port_unregister(nn->port);
0186     return err;
0187 }
0188 
0189 static int
0190 nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
0191                void __iomem *qc_bar, int stride)
0192 {
0193     struct nfp_net *nn;
0194     unsigned int i;
0195     int err;
0196 
0197     for (i = 0; i < pf->max_data_vnics; i++) {
0198         nn = nfp_net_pf_alloc_vnic(pf, true, ctrl_bar, qc_bar,
0199                        stride, i);
0200         if (IS_ERR(nn)) {
0201             err = PTR_ERR(nn);
0202             goto err_free_prev;
0203         }
0204 
0205         ctrl_bar += NFP_PF_CSR_SLICE_SIZE;
0206 
0207         /* Kill the vNIC if app init marked it as invalid */
0208         if (nn->port && nn->port->type == NFP_PORT_INVALID)
0209             nfp_net_pf_free_vnic(pf, nn);
0210     }
0211 
0212     if (list_empty(&pf->vnics))
0213         return -ENODEV;
0214 
0215     return 0;
0216 
0217 err_free_prev:
0218     nfp_net_pf_free_vnics(pf);
0219     return err;
0220 }
0221 
0222 static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn)
0223 {
0224     if (nfp_net_is_data_vnic(nn))
0225         nfp_app_vnic_clean(pf->app, nn);
0226     if (nn->port)
0227         nfp_devlink_port_type_clear(nn->port);
0228     nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
0229     nfp_net_clean(nn);
0230     if (nn->port)
0231         nfp_devlink_port_unregister(nn->port);
0232 }
0233 
0234 static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
0235 {
0236     unsigned int wanted_irqs, num_irqs, vnics_left, irqs_left;
0237     struct nfp_net *nn;
0238 
0239     /* Get MSI-X vectors */
0240     wanted_irqs = 0;
0241     list_for_each_entry(nn, &pf->vnics, vnic_list)
0242         wanted_irqs += NFP_NET_NON_Q_VECTORS + nn->dp.num_r_vecs;
0243     pf->irq_entries = kcalloc(wanted_irqs, sizeof(*pf->irq_entries),
0244                   GFP_KERNEL);
0245     if (!pf->irq_entries)
0246         return -ENOMEM;
0247 
0248     num_irqs = nfp_net_irqs_alloc(pf->pdev, pf->irq_entries,
0249                       NFP_NET_MIN_VNIC_IRQS * pf->num_vnics,
0250                       wanted_irqs);
0251     if (!num_irqs) {
0252         nfp_warn(pf->cpp, "Unable to allocate MSI-X vectors\n");
0253         kfree(pf->irq_entries);
0254         return -ENOMEM;
0255     }
0256 
0257     /* Distribute IRQs to vNICs */
0258     irqs_left = num_irqs;
0259     vnics_left = pf->num_vnics;
0260     list_for_each_entry(nn, &pf->vnics, vnic_list) {
0261         unsigned int n;
0262 
0263         n = min(NFP_NET_NON_Q_VECTORS + nn->dp.num_r_vecs,
0264             DIV_ROUND_UP(irqs_left, vnics_left));
0265         nfp_net_irqs_assign(nn, &pf->irq_entries[num_irqs - irqs_left],
0266                     n);
0267         irqs_left -= n;
0268         vnics_left--;
0269     }
0270 
0271     return 0;
0272 }
0273 
0274 static void nfp_net_pf_free_irqs(struct nfp_pf *pf)
0275 {
0276     nfp_net_irqs_disable(pf->pdev);
0277     kfree(pf->irq_entries);
0278 }
0279 
0280 static int nfp_net_pf_init_vnics(struct nfp_pf *pf)
0281 {
0282     struct nfp_net *nn;
0283     unsigned int id;
0284     int err;
0285 
0286     /* Finish vNIC init and register */
0287     id = 0;
0288     list_for_each_entry(nn, &pf->vnics, vnic_list) {
0289         if (!nfp_net_is_data_vnic(nn))
0290             continue;
0291         err = nfp_net_pf_init_vnic(pf, nn, id);
0292         if (err)
0293             goto err_prev_deinit;
0294 
0295         id++;
0296     }
0297 
0298     return 0;
0299 
0300 err_prev_deinit:
0301     list_for_each_entry_continue_reverse(nn, &pf->vnics, vnic_list)
0302         if (nfp_net_is_data_vnic(nn))
0303             nfp_net_pf_clean_vnic(pf, nn);
0304     return err;
0305 }
0306 
0307 static int
0308 nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
0309 {
0310     struct devlink *devlink = priv_to_devlink(pf);
0311     u8 __iomem *ctrl_bar;
0312     int err;
0313 
0314     pf->app = nfp_app_alloc(pf, nfp_net_pf_get_app_id(pf));
0315     if (IS_ERR(pf->app))
0316         return PTR_ERR(pf->app);
0317 
0318     devl_lock(devlink);
0319     err = nfp_app_init(pf->app);
0320     devl_unlock(devlink);
0321     if (err)
0322         goto err_free;
0323 
0324     if (!nfp_app_needs_ctrl_vnic(pf->app))
0325         return 0;
0326 
0327     ctrl_bar = nfp_pf_map_rtsym(pf, "net.ctrl", "_pf%u_net_ctrl_bar",
0328                     NFP_PF_CSR_SLICE_SIZE, &pf->ctrl_vnic_bar);
0329     if (IS_ERR(ctrl_bar)) {
0330         nfp_err(pf->cpp, "Failed to find ctrl vNIC memory symbol\n");
0331         err = PTR_ERR(ctrl_bar);
0332         goto err_app_clean;
0333     }
0334 
0335     pf->ctrl_vnic = nfp_net_pf_alloc_vnic(pf, false, ctrl_bar, qc_bar,
0336                           stride, 0);
0337     if (IS_ERR(pf->ctrl_vnic)) {
0338         err = PTR_ERR(pf->ctrl_vnic);
0339         goto err_unmap;
0340     }
0341 
0342     return 0;
0343 
0344 err_unmap:
0345     nfp_cpp_area_release_free(pf->ctrl_vnic_bar);
0346 err_app_clean:
0347     devl_lock(devlink);
0348     nfp_app_clean(pf->app);
0349     devl_unlock(devlink);
0350 err_free:
0351     nfp_app_free(pf->app);
0352     pf->app = NULL;
0353     return err;
0354 }
0355 
0356 static void nfp_net_pf_app_clean(struct nfp_pf *pf)
0357 {
0358     struct devlink *devlink = priv_to_devlink(pf);
0359 
0360     if (pf->ctrl_vnic) {
0361         nfp_net_pf_free_vnic(pf, pf->ctrl_vnic);
0362         nfp_cpp_area_release_free(pf->ctrl_vnic_bar);
0363     }
0364 
0365     devl_lock(devlink);
0366     nfp_app_clean(pf->app);
0367     devl_unlock(devlink);
0368 
0369     nfp_app_free(pf->app);
0370     pf->app = NULL;
0371 }
0372 
0373 static int nfp_net_pf_app_start_ctrl(struct nfp_pf *pf)
0374 {
0375     int err;
0376 
0377     if (!pf->ctrl_vnic)
0378         return 0;
0379     err = nfp_net_pf_init_vnic(pf, pf->ctrl_vnic, 0);
0380     if (err)
0381         return err;
0382 
0383     err = nfp_ctrl_open(pf->ctrl_vnic);
0384     if (err)
0385         goto err_clean_ctrl;
0386 
0387     return 0;
0388 
0389 err_clean_ctrl:
0390     nfp_net_pf_clean_vnic(pf, pf->ctrl_vnic);
0391     return err;
0392 }
0393 
0394 static void nfp_net_pf_app_stop_ctrl(struct nfp_pf *pf)
0395 {
0396     if (!pf->ctrl_vnic)
0397         return;
0398     nfp_ctrl_close(pf->ctrl_vnic);
0399     nfp_net_pf_clean_vnic(pf, pf->ctrl_vnic);
0400 }
0401 
0402 static int nfp_net_pf_app_start(struct nfp_pf *pf)
0403 {
0404     int err;
0405 
0406     err = nfp_net_pf_app_start_ctrl(pf);
0407     if (err)
0408         return err;
0409 
0410     err = nfp_app_start(pf->app, pf->ctrl_vnic);
0411     if (err)
0412         goto err_ctrl_stop;
0413 
0414     if (pf->num_vfs) {
0415         err = nfp_app_sriov_enable(pf->app, pf->num_vfs);
0416         if (err)
0417             goto err_app_stop;
0418     }
0419 
0420     return 0;
0421 
0422 err_app_stop:
0423     nfp_app_stop(pf->app);
0424 err_ctrl_stop:
0425     nfp_net_pf_app_stop_ctrl(pf);
0426     return err;
0427 }
0428 
0429 static void nfp_net_pf_app_stop(struct nfp_pf *pf)
0430 {
0431     if (pf->num_vfs)
0432         nfp_app_sriov_disable(pf->app);
0433     nfp_app_stop(pf->app);
0434     nfp_net_pf_app_stop_ctrl(pf);
0435 }
0436 
0437 static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)
0438 {
0439     if (pf->vfcfg_tbl2_area)
0440         nfp_cpp_area_release_free(pf->vfcfg_tbl2_area);
0441     if (pf->vf_cfg_bar)
0442         nfp_cpp_area_release_free(pf->vf_cfg_bar);
0443     if (pf->mac_stats_bar)
0444         nfp_cpp_area_release_free(pf->mac_stats_bar);
0445     nfp_cpp_area_release_free(pf->qc_area);
0446     nfp_cpp_area_release_free(pf->data_vnic_bar);
0447 }
0448 
0449 static int nfp_net_pci_map_mem(struct nfp_pf *pf)
0450 {
0451     u32 min_size, cpp_id;
0452     u8 __iomem *mem;
0453     int err;
0454 
0455     min_size = pf->max_data_vnics * NFP_PF_CSR_SLICE_SIZE;
0456     mem = nfp_pf_map_rtsym(pf, "net.bar0", "_pf%d_net_bar0",
0457                    min_size, &pf->data_vnic_bar);
0458     if (IS_ERR(mem)) {
0459         nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n");
0460         return PTR_ERR(mem);
0461     }
0462 
0463     if (pf->eth_tbl) {
0464         min_size =  NFP_MAC_STATS_SIZE * (pf->eth_tbl->max_index + 1);
0465         pf->mac_stats_mem = nfp_rtsym_map(pf->rtbl, "_mac_stats",
0466                           "net.macstats", min_size,
0467                           &pf->mac_stats_bar);
0468         if (IS_ERR(pf->mac_stats_mem)) {
0469             if (PTR_ERR(pf->mac_stats_mem) != -ENOENT) {
0470                 err = PTR_ERR(pf->mac_stats_mem);
0471                 goto err_unmap_ctrl;
0472             }
0473             pf->mac_stats_mem = NULL;
0474         }
0475     }
0476 
0477     pf->vf_cfg_mem = nfp_pf_map_rtsym(pf, "net.vfcfg", "_pf%d_net_vf_bar",
0478                       NFP_NET_CFG_BAR_SZ * pf->limit_vfs,
0479                       &pf->vf_cfg_bar);
0480     if (IS_ERR(pf->vf_cfg_mem)) {
0481         if (PTR_ERR(pf->vf_cfg_mem) != -ENOENT) {
0482             err = PTR_ERR(pf->vf_cfg_mem);
0483             goto err_unmap_mac_stats;
0484         }
0485         pf->vf_cfg_mem = NULL;
0486     }
0487 
0488     min_size = NFP_NET_VF_CFG_SZ * pf->limit_vfs + NFP_NET_VF_CFG_MB_SZ;
0489     pf->vfcfg_tbl2 = nfp_pf_map_rtsym(pf, "net.vfcfg_tbl2",
0490                       "_pf%d_net_vf_cfg2",
0491                       min_size, &pf->vfcfg_tbl2_area);
0492     if (IS_ERR(pf->vfcfg_tbl2)) {
0493         if (PTR_ERR(pf->vfcfg_tbl2) != -ENOENT) {
0494             err = PTR_ERR(pf->vfcfg_tbl2);
0495             goto err_unmap_vf_cfg;
0496         }
0497         pf->vfcfg_tbl2 = NULL;
0498     }
0499 
0500     cpp_id = NFP_CPP_ISLAND_ID(0, NFP_CPP_ACTION_RW, 0, 0);
0501     mem = nfp_cpp_map_area(pf->cpp, "net.qc", cpp_id,
0502                    nfp_qcp_queue_offset(pf->dev_info, 0),
0503                    pf->dev_info->qc_area_sz, &pf->qc_area);
0504     if (IS_ERR(mem)) {
0505         nfp_err(pf->cpp, "Failed to map Queue Controller area.\n");
0506         err = PTR_ERR(mem);
0507         goto err_unmap_vfcfg_tbl2;
0508     }
0509 
0510     return 0;
0511 
0512 err_unmap_vfcfg_tbl2:
0513     if (pf->vfcfg_tbl2_area)
0514         nfp_cpp_area_release_free(pf->vfcfg_tbl2_area);
0515 err_unmap_vf_cfg:
0516     if (pf->vf_cfg_bar)
0517         nfp_cpp_area_release_free(pf->vf_cfg_bar);
0518 err_unmap_mac_stats:
0519     if (pf->mac_stats_bar)
0520         nfp_cpp_area_release_free(pf->mac_stats_bar);
0521 err_unmap_ctrl:
0522     nfp_cpp_area_release_free(pf->data_vnic_bar);
0523     return err;
0524 }
0525 
0526 static int
0527 nfp_net_eth_port_update(struct nfp_cpp *cpp, struct nfp_port *port,
0528             struct nfp_eth_table *eth_table)
0529 {
0530     struct nfp_eth_table_port *eth_port;
0531 
0532     ASSERT_RTNL();
0533 
0534     eth_port = nfp_net_find_port(eth_table, port->eth_id);
0535     if (!eth_port) {
0536         set_bit(NFP_PORT_CHANGED, &port->flags);
0537         nfp_warn(cpp, "Warning: port #%d not present after reconfig\n",
0538              port->eth_id);
0539         return -EIO;
0540     }
0541     if (eth_port->override_changed) {
0542         nfp_warn(cpp, "Port #%d config changed, unregistering. Driver reload required before port will be operational again.\n", port->eth_id);
0543         port->type = NFP_PORT_INVALID;
0544     }
0545 
0546     memcpy(port->eth_port, eth_port, sizeof(*eth_port));
0547 
0548     return 0;
0549 }
0550 
0551 int nfp_net_refresh_port_table_sync(struct nfp_pf *pf)
0552 {
0553     struct devlink *devlink = priv_to_devlink(pf);
0554     struct nfp_eth_table *eth_table;
0555     struct nfp_net *nn, *next;
0556     struct nfp_port *port;
0557     int err;
0558 
0559     devl_assert_locked(devlink);
0560 
0561     /* Check for nfp_net_pci_remove() racing against us */
0562     if (list_empty(&pf->vnics))
0563         return 0;
0564 
0565     /* Update state of all ports */
0566     rtnl_lock();
0567     list_for_each_entry(port, &pf->ports, port_list)
0568         clear_bit(NFP_PORT_CHANGED, &port->flags);
0569 
0570     eth_table = nfp_eth_read_ports(pf->cpp);
0571     if (!eth_table) {
0572         list_for_each_entry(port, &pf->ports, port_list)
0573             if (__nfp_port_get_eth_port(port))
0574                 set_bit(NFP_PORT_CHANGED, &port->flags);
0575         rtnl_unlock();
0576         nfp_err(pf->cpp, "Error refreshing port config!\n");
0577         return -EIO;
0578     }
0579 
0580     list_for_each_entry(port, &pf->ports, port_list)
0581         if (__nfp_port_get_eth_port(port))
0582             nfp_net_eth_port_update(pf->cpp, port, eth_table);
0583     rtnl_unlock();
0584 
0585     kfree(eth_table);
0586 
0587     /* Resync repr state. This may cause reprs to be removed. */
0588     err = nfp_reprs_resync_phys_ports(pf->app);
0589     if (err)
0590         return err;
0591 
0592     /* Shoot off the ports which became invalid */
0593     list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
0594         if (!nn->port || nn->port->type != NFP_PORT_INVALID)
0595             continue;
0596 
0597         nfp_net_pf_clean_vnic(pf, nn);
0598         nfp_net_pf_free_vnic(pf, nn);
0599     }
0600 
0601     return 0;
0602 }
0603 
0604 static void nfp_net_refresh_vnics(struct work_struct *work)
0605 {
0606     struct nfp_pf *pf = container_of(work, struct nfp_pf,
0607                      port_refresh_work);
0608     struct devlink *devlink = priv_to_devlink(pf);
0609 
0610     devl_lock(devlink);
0611     nfp_net_refresh_port_table_sync(pf);
0612     devl_unlock(devlink);
0613 }
0614 
0615 void nfp_net_refresh_port_table(struct nfp_port *port)
0616 {
0617     struct nfp_pf *pf = port->app->pf;
0618 
0619     set_bit(NFP_PORT_CHANGED, &port->flags);
0620 
0621     queue_work(pf->wq, &pf->port_refresh_work);
0622 }
0623 
0624 int nfp_net_refresh_eth_port(struct nfp_port *port)
0625 {
0626     struct nfp_cpp *cpp = port->app->cpp;
0627     struct nfp_eth_table *eth_table;
0628     int ret;
0629 
0630     clear_bit(NFP_PORT_CHANGED, &port->flags);
0631 
0632     eth_table = nfp_eth_read_ports(cpp);
0633     if (!eth_table) {
0634         set_bit(NFP_PORT_CHANGED, &port->flags);
0635         nfp_err(cpp, "Error refreshing port state table!\n");
0636         return -EIO;
0637     }
0638 
0639     ret = nfp_net_eth_port_update(cpp, port, eth_table);
0640 
0641     kfree(eth_table);
0642 
0643     return ret;
0644 }
0645 
0646 /*
0647  * PCI device functions
0648  */
0649 int nfp_net_pci_probe(struct nfp_pf *pf)
0650 {
0651     struct devlink *devlink = priv_to_devlink(pf);
0652     struct nfp_net_fw_version fw_ver;
0653     u8 __iomem *ctrl_bar, *qc_bar;
0654     int stride;
0655     int err;
0656 
0657     INIT_WORK(&pf->port_refresh_work, nfp_net_refresh_vnics);
0658 
0659     if (!pf->rtbl) {
0660         nfp_err(pf->cpp, "No %s, giving up.\n",
0661             pf->fw_loaded ? "symbol table" : "firmware found");
0662         return -EINVAL;
0663     }
0664 
0665     pf->max_data_vnics = nfp_net_pf_get_num_ports(pf);
0666     if ((int)pf->max_data_vnics < 0)
0667         return pf->max_data_vnics;
0668 
0669     err = nfp_net_pci_map_mem(pf);
0670     if (err)
0671         return err;
0672 
0673     ctrl_bar = nfp_cpp_area_iomem(pf->data_vnic_bar);
0674     qc_bar = nfp_cpp_area_iomem(pf->qc_area);
0675     if (!ctrl_bar || !qc_bar) {
0676         err = -EIO;
0677         goto err_unmap;
0678     }
0679 
0680     nfp_net_get_fw_version(&fw_ver, ctrl_bar);
0681     if (fw_ver.extend & NFP_NET_CFG_VERSION_RESERVED_MASK ||
0682         fw_ver.class != NFP_NET_CFG_VERSION_CLASS_GENERIC) {
0683         nfp_err(pf->cpp, "Unknown Firmware ABI %d.%d.%d.%d\n",
0684             fw_ver.extend, fw_ver.class,
0685             fw_ver.major, fw_ver.minor);
0686         err = -EINVAL;
0687         goto err_unmap;
0688     }
0689 
0690     /* Determine stride */
0691     if (nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0, 1)) {
0692         stride = 2;
0693         nfp_warn(pf->cpp, "OBSOLETE Firmware detected - VF isolation not available\n");
0694     } else {
0695         switch (fw_ver.major) {
0696         case 1 ... 5:
0697             stride = 4;
0698             break;
0699         default:
0700             nfp_err(pf->cpp, "Unsupported Firmware ABI %d.%d.%d.%d\n",
0701                 fw_ver.extend, fw_ver.class,
0702                 fw_ver.major, fw_ver.minor);
0703             err = -EINVAL;
0704             goto err_unmap;
0705         }
0706     }
0707 
0708     err = nfp_net_pf_app_init(pf, qc_bar, stride);
0709     if (err)
0710         goto err_unmap;
0711 
0712     err = nfp_shared_buf_register(pf);
0713     if (err)
0714         goto err_devlink_unreg;
0715 
0716     err = nfp_devlink_params_register(pf);
0717     if (err)
0718         goto err_shared_buf_unreg;
0719 
0720     devl_lock(devlink);
0721     pf->ddir = nfp_net_debugfs_device_add(pf->pdev);
0722 
0723     /* Allocate the vnics and do basic init */
0724     err = nfp_net_pf_alloc_vnics(pf, ctrl_bar, qc_bar, stride);
0725     if (err)
0726         goto err_clean_ddir;
0727 
0728     err = nfp_net_pf_alloc_irqs(pf);
0729     if (err)
0730         goto err_free_vnics;
0731 
0732     err = nfp_net_pf_app_start(pf);
0733     if (err)
0734         goto err_free_irqs;
0735 
0736     err = nfp_net_pf_init_vnics(pf);
0737     if (err)
0738         goto err_stop_app;
0739 
0740     devl_unlock(devlink);
0741     devlink_register(devlink);
0742 
0743     return 0;
0744 
0745 err_stop_app:
0746     nfp_net_pf_app_stop(pf);
0747 err_free_irqs:
0748     nfp_net_pf_free_irqs(pf);
0749 err_free_vnics:
0750     nfp_net_pf_free_vnics(pf);
0751 err_clean_ddir:
0752     nfp_net_debugfs_dir_clean(&pf->ddir);
0753     devl_unlock(devlink);
0754     nfp_devlink_params_unregister(pf);
0755 err_shared_buf_unreg:
0756     nfp_shared_buf_unregister(pf);
0757 err_devlink_unreg:
0758     cancel_work_sync(&pf->port_refresh_work);
0759     nfp_net_pf_app_clean(pf);
0760 err_unmap:
0761     nfp_net_pci_unmap_mem(pf);
0762     return err;
0763 }
0764 
0765 void nfp_net_pci_remove(struct nfp_pf *pf)
0766 {
0767     struct devlink *devlink = priv_to_devlink(pf);
0768     struct nfp_net *nn, *next;
0769 
0770     devlink_unregister(priv_to_devlink(pf));
0771     devl_lock(devlink);
0772     list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
0773         if (!nfp_net_is_data_vnic(nn))
0774             continue;
0775         nfp_net_pf_clean_vnic(pf, nn);
0776         nfp_net_pf_free_vnic(pf, nn);
0777     }
0778 
0779     nfp_net_pf_app_stop(pf);
0780     /* stop app first, to avoid double free of ctrl vNIC's ddir */
0781     nfp_net_debugfs_dir_clean(&pf->ddir);
0782 
0783     devl_unlock(devlink);
0784 
0785     nfp_devlink_params_unregister(pf);
0786     nfp_shared_buf_unregister(pf);
0787 
0788     nfp_net_pf_free_irqs(pf);
0789     nfp_net_pf_app_clean(pf);
0790     nfp_net_pci_unmap_mem(pf);
0791 
0792     cancel_work_sync(&pf->port_refresh_work);
0793 }