1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
4 #include <cnxk_ethdev.h>
6 /* CNXK platform independent eth dev ops */
7 struct eth_dev_ops cnxk_eth_dev_ops;
10 cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
12 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
13 struct roc_nix *nix = &dev->nix;
14 struct rte_pci_device *pci_dev;
17 eth_dev->dev_ops = &cnxk_eth_dev_ops;
19 /* For secondary processes, the primary has done all the work */
20 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
23 pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
24 rte_eth_copy_pci_info(eth_dev, pci_dev);
26 /* Initialize base roc nix */
27 nix->pci_dev = pci_dev;
28 rc = roc_nix_dev_init(nix);
30 plt_err("Failed to initialize roc nix rc=%d", rc);
34 dev->eth_dev = eth_dev;
36 /* For vfs, returned max_entries will be 0. but to keep default mac
37 * address, one entry must be allocated. so setting up to 1.
39 if (roc_nix_is_vf_or_sdp(nix))
42 max_entries = roc_nix_mac_max_entries_get(nix);
44 if (max_entries <= 0) {
45 plt_err("Failed to get max entries for mac addr");
50 eth_dev->data->mac_addrs =
51 rte_zmalloc("mac_addr", max_entries * RTE_ETHER_ADDR_LEN, 0);
52 if (eth_dev->data->mac_addrs == NULL) {
53 plt_err("Failed to allocate memory for mac addr");
58 dev->max_mac_entries = max_entries;
61 rc = roc_nix_npc_mac_addr_get(nix, dev->mac_addr);
63 plt_err("Failed to get mac addr, rc=%d", rc);
67 /* Update the mac address */
68 memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
70 if (!roc_nix_is_vf_or_sdp(nix)) {
71 /* Sync same MAC address to CGX/RPM table */
72 rc = roc_nix_mac_addr_set(nix, dev->mac_addr);
74 plt_err("Failed to set mac addr, rc=%d", rc);
79 /* Initialize roc npc */
80 plt_nix_dbg("Port=%d pf=%d vf=%d ver=%s hwcap=0x%" PRIx64
81 " rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64,
82 eth_dev->data->port_id, roc_nix_get_pf(nix),
83 roc_nix_get_vf(nix), CNXK_ETH_DEV_PMD_VERSION, dev->hwcap,
84 dev->rx_offload_capa, dev->tx_offload_capa);
88 rte_free(eth_dev->data->mac_addrs);
90 roc_nix_dev_fini(nix);
92 plt_err("Failed to init nix eth_dev rc=%d", rc);
97 cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
99 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
100 const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
101 struct roc_nix *nix = &dev->nix;
104 /* Nothing to be done for secondary processes */
105 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
108 roc_nix_npc_rx_ena_dis(nix, false);
111 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
112 dev_ops->tx_queue_release(eth_dev->data->tx_queues[i]);
113 eth_dev->data->tx_queues[i] = NULL;
115 eth_dev->data->nb_tx_queues = 0;
117 /* Free up RQ's and CQ's */
118 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
119 dev_ops->rx_queue_release(eth_dev->data->rx_queues[i]);
120 eth_dev->data->rx_queues[i] = NULL;
122 eth_dev->data->nb_rx_queues = 0;
124 /* Free tm resources */
125 roc_nix_tm_fini(nix);
127 /* Unregister queue irqs */
128 roc_nix_unregister_queue_irqs(nix);
130 /* Unregister cq irqs */
131 if (eth_dev->data->dev_conf.intr_conf.rxq)
132 roc_nix_unregister_cq_irqs(nix);
134 /* Free nix lf resources */
135 rc = roc_nix_lf_free(nix);
137 plt_err("Failed to free nix lf, rc=%d", rc);
139 rte_free(eth_dev->data->mac_addrs);
140 eth_dev->data->mac_addrs = NULL;
142 /* Check if mbox close is needed */
146 rc = roc_nix_dev_fini(nix);
147 /* Can be freed later by PMD if NPA LF is in use */
149 eth_dev->data->dev_private = NULL;
152 plt_err("Failed in nix dev fini, rc=%d", rc);
159 cnxk_nix_remove(struct rte_pci_device *pci_dev)
161 struct rte_eth_dev *eth_dev;
165 eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
167 /* Cleanup eth dev */
168 rc = cnxk_eth_dev_uninit(eth_dev, true);
172 rte_eth_dev_release_port(eth_dev);
175 /* Nothing to be done for secondary processes */
176 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
179 /* Check if this device is hosting common resource */
180 nix = roc_idev_npa_nix_get();
181 if (nix->pci_dev != pci_dev)
184 /* Try nix fini now */
185 rc = roc_nix_dev_fini(nix);
187 plt_info("%s: common resource in use by other devices",
191 plt_err("Failed in nix dev fini, rc=%d", rc);
195 /* Free device pointer as rte_ethdev does not have it anymore */
202 cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
206 RTE_SET_USED(pci_drv);
208 rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),
211 /* On error on secondary, recheck if port exists in primary or
212 * in mid of detach state.
214 if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
215 if (!rte_eth_dev_allocated(pci_dev->device.name))