+/*
+ * When attaching to the NFP4000/6000 PF on a secondary process there
+ * is no need to initialize the PF again. Only minimal work is required
+ * here
+ */
+static int nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
+{
+ struct nfp_cpp *cpp;
+ struct nfp_rtsym_table *sym_tbl;
+ int total_ports;
+ int i;
+ int err;
+
+ if (!pci_dev)
+ return -ENODEV;
+
+ /*
+ * When device bound to UIO, the device could be used, by mistake,
+ * by two DPDK apps, and the UIO driver does not avoid it. This
+ * could lead to a serious problem when configuring the NFP CPP
+ * interface. Here we avoid this telling to the CPP init code to
+ * use a lock file if UIO is being used.
+ */
+ if (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)
+ cpp = nfp_cpp_from_device_name(pci_dev, 0);
+ else
+ cpp = nfp_cpp_from_device_name(pci_dev, 1);
+
+ if (!cpp) {
+ PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
+ return -EIO;
+ }
+
+ /*
+ * We don't have access to the PF created in the primary process
+ * here so we have to read the number of ports from firmware
+ */
+ sym_tbl = nfp_rtsym_table_read(cpp);
+ if (!sym_tbl) {
+ PMD_INIT_LOG(ERR, "Something is wrong with the firmware"
+ " symbol table");
+ return -EIO;
+ }
+
+ total_ports = nfp_rtsym_read_le(sym_tbl, "nfd_cfg_pf0_num_ports", &err);
+
+ for (i = 0; i < total_ports; i++) {
+ struct rte_eth_dev *eth_dev;
+ char port_name[RTE_ETH_NAME_MAX_LEN];
+
+ snprintf(port_name, sizeof(port_name), "%s_port%d",
+ pci_dev->device.name, i);
+
+ PMD_DRV_LOG(DEBUG, "Secondary attaching to port %s",
+ port_name);
+ eth_dev = rte_eth_dev_attach_secondary(port_name);
+ if (!eth_dev) {
+ RTE_LOG(ERR, EAL,
+ "secondary process attach failed, "
+ "ethdev doesn't exist");
+ return -ENODEV;
+ }
+ eth_dev->process_private = cpp;
+ eth_dev->dev_ops = &nfp_net_eth_dev_ops;
+ eth_dev->rx_queue_count = nfp_net_rx_queue_count;
+ eth_dev->rx_pkt_burst = &nfp_net_recv_pkts;
+ eth_dev->tx_pkt_burst = &nfp_net_xmit_pkts;
+ rte_eth_dev_probing_finish(eth_dev);
+ }
+
+ /* Register the CPP bridge service for the secondary too */
+ nfp_register_cpp_service(cpp);
+
+ return 0;
+}
+