+ struct nfp_net_hw *hw;
+ struct rte_eth_dev *eth_dev;
+ struct nfp_eth_table *nfp_eth_table = NULL;
+ int ret = 0;
+ int i;
+
+ nfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);
+ if (!nfp_eth_table) {
+ PMD_INIT_LOG(ERR, "Error reading NFP ethernet table");
+ ret = -EIO;
+ goto error;
+ }
+
+ /* Loop through all physical ports on PF */
+ for (i = 0; i < pf_dev->total_phyports; i++) {
+ const unsigned int numa_node = rte_socket_id();
+ char port_name[RTE_ETH_NAME_MAX_LEN];
+
+ snprintf(port_name, sizeof(port_name), "%s_port%d",
+ pf_dev->pci_dev->device.name, i);
+
+ /* Allocate a eth_dev for this phyport */
+ eth_dev = rte_eth_dev_allocate(port_name);
+ if (!eth_dev) {
+ ret = -ENODEV;
+ goto port_cleanup;
+ }
+
+ /* Allocate memory for this phyport */
+ eth_dev->data->dev_private =
+ rte_zmalloc_socket(port_name, sizeof(struct nfp_net_hw),
+ RTE_CACHE_LINE_SIZE, numa_node);
+ if (!eth_dev->data->dev_private) {
+ ret = -ENOMEM;
+ rte_eth_dev_release_port(eth_dev);
+ goto port_cleanup;
+ }
+
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+ /* Add this device to the PF's array of physical ports */
+ pf_dev->ports[i] = hw;
+
+ hw->pf_dev = pf_dev;
+ hw->cpp = pf_dev->cpp;
+ hw->eth_dev = eth_dev;
+ hw->idx = i;
+ hw->nfp_idx = nfp_eth_table->ports[i].index;
+ hw->is_phyport = true;
+
+ eth_dev->device = &pf_dev->pci_dev->device;
+
+ /* ctrl/tx/rx BAR mappings and remaining init happens in
+ * nfp_net_init
+ */
+ ret = nfp_net_init(eth_dev);
+
+ if (ret) {
+ ret = -ENODEV;
+ goto port_cleanup;
+ }
+
+ rte_eth_dev_probing_finish(eth_dev);
+
+ } /* End loop, all ports on this PF */
+ ret = 0;
+ goto eth_table_cleanup;
+
+port_cleanup:
+ for (i = 0; i < pf_dev->total_phyports; i++) {
+ if (pf_dev->ports[i] && pf_dev->ports[i]->eth_dev) {
+ struct rte_eth_dev *tmp_dev;
+ tmp_dev = pf_dev->ports[i]->eth_dev;
+ rte_eth_dev_release_port(tmp_dev);
+ pf_dev->ports[i] = NULL;
+ }
+ }
+eth_table_cleanup:
+ free(nfp_eth_table);
+error:
+ return ret;
+}
+
+static void nfp_register_cpp_service(struct nfp_cpp *cpp)
+{
+ uint32_t *cpp_service_id = NULL;
+ struct rte_service_spec service;
+
+ memset(&service, 0, sizeof(struct rte_service_spec));
+ snprintf(service.name, sizeof(service.name), "nfp_cpp_service");
+ service.callback = nfp_cpp_bridge_service_func;
+ service.callback_userdata = (void *)cpp;
+
+ if (rte_service_component_register(&service,
+ cpp_service_id))
+ RTE_LOG(WARNING, PMD, "NFP CPP bridge service register() failed");
+ else
+ RTE_LOG(DEBUG, PMD, "NFP CPP bridge service registered");
+}
+
+static int nfp_pf_init(struct rte_pci_device *pci_dev)
+{
+ struct nfp_pf_dev *pf_dev = NULL;