+ /* For secondary processes, the primary has done all the work */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ /* Setup callbacks for secondary process */
+ otx2_eth_set_tx_function(eth_dev);
+ otx2_eth_set_rx_function(eth_dev);
+ return 0;
+ }
+
+ pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+
+ /* Zero out everything after OTX2_DEV to allow proper dev_reset() */
+ memset(&dev->otx2_eth_dev_data_start, 0, sizeof(*dev) -
+ offsetof(struct otx2_eth_dev, otx2_eth_dev_data_start));
+
+ if (!dev->mbox_active) {
+ /* Initialize the base otx2_dev object
+ * only if already present
+ */
+ rc = otx2_dev_init(pci_dev, dev);
+ if (rc) {
+ otx2_err("Failed to initialize otx2_dev rc=%d", rc);
+ goto error;
+ }
+ }
+
+ /* Grab the NPA LF if required */
+ rc = otx2_npa_lf_init(pci_dev, dev);
+ if (rc)
+ goto otx2_dev_uninit;
+
+ dev->configured = 0;
+ dev->drv_inited = true;
+ dev->base = dev->bar2 + (RVU_BLOCK_ADDR_NIX0 << 20);
+ dev->lmt_addr = dev->bar2 + (RVU_BLOCK_ADDR_LMT << 20);
+
+ /* Attach NIX LF */
+ rc = nix_lf_attach(dev);
+ if (rc)
+ goto otx2_npa_uninit;
+
+ /* Get NIX MSIX offset */
+ rc = nix_lf_get_msix_offset(dev);
+ if (rc)
+ goto otx2_npa_uninit;
+
+ /* Get maximum number of supported MAC entries */
+ max_entries = otx2_cgx_mac_max_entries_get(dev);
+ if (max_entries < 0) {
+ otx2_err("Failed to get max entries for mac addr");
+ rc = -ENOTSUP;
+ goto mbox_detach;
+ }
+
+ /* For VFs, returned max_entries will be 0. But to keep default MAC
+ * address, one entry must be allocated. So setting up to 1.
+ */
+ if (max_entries == 0)
+ max_entries = 1;
+
+ eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", max_entries *
+ RTE_ETHER_ADDR_LEN, 0);
+ if (eth_dev->data->mac_addrs == NULL) {
+ otx2_err("Failed to allocate memory for mac addr");
+ rc = -ENOMEM;
+ goto mbox_detach;
+ }
+
+ dev->max_mac_entries = max_entries;
+
+ rc = otx2_nix_mac_addr_get(eth_dev, dev->mac_addr);
+ if (rc)
+ goto free_mac_addrs;
+
+ /* Update the mac address */
+ memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
+
+ /* Also sync same MAC address to CGX table */
+ otx2_cgx_mac_addr_set(eth_dev, ð_dev->data->mac_addrs[0]);
+
+ dev->tx_offload_capa = nix_get_tx_offload_capa(dev);
+ dev->rx_offload_capa = nix_get_rx_offload_capa(dev);
+
+ if (otx2_dev_is_A0(dev)) {
+ dev->hwcap |= OTX2_FIXUP_F_MIN_4K_Q;
+ dev->hwcap |= OTX2_FIXUP_F_LIMIT_CQ_FULL;
+ }
+
+ otx2_nix_dbg("Port=%d pf=%d vf=%d ver=%s msix_off=%d hwcap=0x%" PRIx64
+ " rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64,
+ eth_dev->data->port_id, dev->pf, dev->vf,
+ OTX2_ETH_DEV_PMD_VERSION, dev->nix_msixoff, dev->hwcap,
+ dev->rx_offload_capa, dev->tx_offload_capa);
+ return 0;
+
+free_mac_addrs:
+ rte_free(eth_dev->data->mac_addrs);
+mbox_detach:
+ otx2_eth_dev_lf_detach(dev->mbox);
+otx2_npa_uninit:
+ otx2_npa_lf_fini();
+otx2_dev_uninit:
+ otx2_dev_fini(pci_dev, dev);
+error:
+ otx2_err("Failed to init nix eth_dev rc=%d", rc);
+ return rc;