589b0da35b6aa1c76bbc641dbd55d1899526ead1
[dpdk.git] / drivers / net / cnxk / cnxk_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #include <cnxk_ethdev.h>
5
6 /* CNXK platform independent eth dev ops */
7 struct eth_dev_ops cnxk_eth_dev_ops;
8
9 static int
10 cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
11 {
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;
15         int rc, max_entries;
16
17         eth_dev->dev_ops = &cnxk_eth_dev_ops;
18
19         /* For secondary processes, the primary has done all the work */
20         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
21                 return 0;
22
23         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
24         rte_eth_copy_pci_info(eth_dev, pci_dev);
25
26         /* Initialize base roc nix */
27         nix->pci_dev = pci_dev;
28         rc = roc_nix_dev_init(nix);
29         if (rc) {
30                 plt_err("Failed to initialize roc nix rc=%d", rc);
31                 goto error;
32         }
33
34         dev->eth_dev = eth_dev;
35
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.
38          */
39         if (roc_nix_is_vf_or_sdp(nix))
40                 max_entries = 1;
41         else
42                 max_entries = roc_nix_mac_max_entries_get(nix);
43
44         if (max_entries <= 0) {
45                 plt_err("Failed to get max entries for mac addr");
46                 rc = -ENOTSUP;
47                 goto dev_fini;
48         }
49
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");
54                 rc = -ENOMEM;
55                 goto dev_fini;
56         }
57
58         dev->max_mac_entries = max_entries;
59
60         /* Get mac address */
61         rc = roc_nix_npc_mac_addr_get(nix, dev->mac_addr);
62         if (rc) {
63                 plt_err("Failed to get mac addr, rc=%d", rc);
64                 goto free_mac_addrs;
65         }
66
67         /* Update the mac address */
68         memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
69
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);
73                 if (rc) {
74                         plt_err("Failed to set mac addr, rc=%d", rc);
75                         goto free_mac_addrs;
76                 }
77         }
78
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);
85         return 0;
86
87 free_mac_addrs:
88         rte_free(eth_dev->data->mac_addrs);
89 dev_fini:
90         roc_nix_dev_fini(nix);
91 error:
92         plt_err("Failed to init nix eth_dev rc=%d", rc);
93         return rc;
94 }
95
96 static int
97 cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
98 {
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;
102         int rc, i;
103
104         /* Nothing to be done for secondary processes */
105         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
106                 return 0;
107
108         roc_nix_npc_rx_ena_dis(nix, false);
109
110         /* Free up SQs */
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;
114         }
115         eth_dev->data->nb_tx_queues = 0;
116
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;
121         }
122         eth_dev->data->nb_rx_queues = 0;
123
124         /* Free tm resources */
125         roc_nix_tm_fini(nix);
126
127         /* Unregister queue irqs */
128         roc_nix_unregister_queue_irqs(nix);
129
130         /* Unregister cq irqs */
131         if (eth_dev->data->dev_conf.intr_conf.rxq)
132                 roc_nix_unregister_cq_irqs(nix);
133
134         /* Free nix lf resources */
135         rc = roc_nix_lf_free(nix);
136         if (rc)
137                 plt_err("Failed to free nix lf, rc=%d", rc);
138
139         rte_free(eth_dev->data->mac_addrs);
140         eth_dev->data->mac_addrs = NULL;
141
142         /* Check if mbox close is needed */
143         if (!mbox_close)
144                 return 0;
145
146         rc = roc_nix_dev_fini(nix);
147         /* Can be freed later by PMD if NPA LF is in use */
148         if (rc == -EAGAIN) {
149                 eth_dev->data->dev_private = NULL;
150                 return 0;
151         } else if (rc) {
152                 plt_err("Failed in nix dev fini, rc=%d", rc);
153         }
154
155         return rc;
156 }
157
158 int
159 cnxk_nix_remove(struct rte_pci_device *pci_dev)
160 {
161         struct rte_eth_dev *eth_dev;
162         struct roc_nix *nix;
163         int rc = -EINVAL;
164
165         eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
166         if (eth_dev) {
167                 /* Cleanup eth dev */
168                 rc = cnxk_eth_dev_uninit(eth_dev, true);
169                 if (rc)
170                         return rc;
171
172                 rte_eth_dev_release_port(eth_dev);
173         }
174
175         /* Nothing to be done for secondary processes */
176         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
177                 return 0;
178
179         /* Check if this device is hosting common resource */
180         nix = roc_idev_npa_nix_get();
181         if (nix->pci_dev != pci_dev)
182                 return 0;
183
184         /* Try nix fini now */
185         rc = roc_nix_dev_fini(nix);
186         if (rc == -EAGAIN) {
187                 plt_info("%s: common resource in use by other devices",
188                          pci_dev->name);
189                 goto exit;
190         } else if (rc) {
191                 plt_err("Failed in nix dev fini, rc=%d", rc);
192                 goto exit;
193         }
194
195         /* Free device pointer as rte_ethdev does not have it anymore */
196         rte_free(nix);
197 exit:
198         return rc;
199 }
200
201 int
202 cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
203 {
204         int rc;
205
206         RTE_SET_USED(pci_drv);
207
208         rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),
209                                            cnxk_eth_dev_init);
210
211         /* On error on secondary, recheck if port exists in primary or
212          * in mid of detach state.
213          */
214         if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
215                 if (!rte_eth_dev_allocated(pci_dev->device.name))
216                         return 0;
217         return rc;
218 }