0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0040
0041
0042
0043
0044
0045
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 ð_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
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
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
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
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
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
0562 if (list_empty(&pf->vnics))
0563 return 0;
0564
0565
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
0588 err = nfp_reprs_resync_phys_ports(pf->app);
0589 if (err)
0590 return err;
0591
0592
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
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
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
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
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 }