066e01ca8979d39b39866065eb69cae6938c3f30
[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 static inline uint64_t
7 nix_get_rx_offload_capa(struct cnxk_eth_dev *dev)
8 {
9         uint64_t capa = CNXK_NIX_RX_OFFLOAD_CAPA;
10
11         if (roc_nix_is_vf_or_sdp(&dev->nix))
12                 capa &= ~DEV_RX_OFFLOAD_TIMESTAMP;
13
14         return capa;
15 }
16
17 static inline uint64_t
18 nix_get_tx_offload_capa(struct cnxk_eth_dev *dev)
19 {
20         RTE_SET_USED(dev);
21         return CNXK_NIX_TX_OFFLOAD_CAPA;
22 }
23
24 static inline uint32_t
25 nix_get_speed_capa(struct cnxk_eth_dev *dev)
26 {
27         uint32_t speed_capa;
28
29         /* Auto negotiation disabled */
30         speed_capa = ETH_LINK_SPEED_FIXED;
31         if (!roc_nix_is_vf_or_sdp(&dev->nix) && !roc_nix_is_lbk(&dev->nix)) {
32                 speed_capa |= ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
33                               ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
34                               ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
35         }
36
37         return speed_capa;
38 }
39
40 /* CNXK platform independent eth dev ops */
41 struct eth_dev_ops cnxk_eth_dev_ops = {
42         .dev_infos_get = cnxk_nix_info_get,
43 };
44
45 static int
46 cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
47 {
48         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
49         struct roc_nix *nix = &dev->nix;
50         struct rte_pci_device *pci_dev;
51         int rc, max_entries;
52
53         eth_dev->dev_ops = &cnxk_eth_dev_ops;
54
55         /* For secondary processes, the primary has done all the work */
56         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
57                 return 0;
58
59         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
60         rte_eth_copy_pci_info(eth_dev, pci_dev);
61
62         /* Parse devargs string */
63         rc = cnxk_ethdev_parse_devargs(eth_dev->device->devargs, dev);
64         if (rc) {
65                 plt_err("Failed to parse devargs rc=%d", rc);
66                 goto error;
67         }
68
69         /* Initialize base roc nix */
70         nix->pci_dev = pci_dev;
71         rc = roc_nix_dev_init(nix);
72         if (rc) {
73                 plt_err("Failed to initialize roc nix rc=%d", rc);
74                 goto error;
75         }
76
77         dev->eth_dev = eth_dev;
78
79         /* For vfs, returned max_entries will be 0. but to keep default mac
80          * address, one entry must be allocated. so setting up to 1.
81          */
82         if (roc_nix_is_vf_or_sdp(nix))
83                 max_entries = 1;
84         else
85                 max_entries = roc_nix_mac_max_entries_get(nix);
86
87         if (max_entries <= 0) {
88                 plt_err("Failed to get max entries for mac addr");
89                 rc = -ENOTSUP;
90                 goto dev_fini;
91         }
92
93         eth_dev->data->mac_addrs =
94                 rte_zmalloc("mac_addr", max_entries * RTE_ETHER_ADDR_LEN, 0);
95         if (eth_dev->data->mac_addrs == NULL) {
96                 plt_err("Failed to allocate memory for mac addr");
97                 rc = -ENOMEM;
98                 goto dev_fini;
99         }
100
101         dev->max_mac_entries = max_entries;
102
103         /* Get mac address */
104         rc = roc_nix_npc_mac_addr_get(nix, dev->mac_addr);
105         if (rc) {
106                 plt_err("Failed to get mac addr, rc=%d", rc);
107                 goto free_mac_addrs;
108         }
109
110         /* Update the mac address */
111         memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
112
113         if (!roc_nix_is_vf_or_sdp(nix)) {
114                 /* Sync same MAC address to CGX/RPM table */
115                 rc = roc_nix_mac_addr_set(nix, dev->mac_addr);
116                 if (rc) {
117                         plt_err("Failed to set mac addr, rc=%d", rc);
118                         goto free_mac_addrs;
119                 }
120         }
121
122         /* Union of all capabilities supported by CNXK.
123          * Platform specific capabilities will be
124          * updated later.
125          */
126         dev->rx_offload_capa = nix_get_rx_offload_capa(dev);
127         dev->tx_offload_capa = nix_get_tx_offload_capa(dev);
128         dev->speed_capa = nix_get_speed_capa(dev);
129
130         /* Initialize roc npc */
131         plt_nix_dbg("Port=%d pf=%d vf=%d ver=%s hwcap=0x%" PRIx64
132                     " rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64,
133                     eth_dev->data->port_id, roc_nix_get_pf(nix),
134                     roc_nix_get_vf(nix), CNXK_ETH_DEV_PMD_VERSION, dev->hwcap,
135                     dev->rx_offload_capa, dev->tx_offload_capa);
136         return 0;
137
138 free_mac_addrs:
139         rte_free(eth_dev->data->mac_addrs);
140 dev_fini:
141         roc_nix_dev_fini(nix);
142 error:
143         plt_err("Failed to init nix eth_dev rc=%d", rc);
144         return rc;
145 }
146
147 static int
148 cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
149 {
150         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
151         const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
152         struct roc_nix *nix = &dev->nix;
153         int rc, i;
154
155         /* Nothing to be done for secondary processes */
156         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
157                 return 0;
158
159         roc_nix_npc_rx_ena_dis(nix, false);
160
161         /* Free up SQs */
162         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
163                 dev_ops->tx_queue_release(eth_dev->data->tx_queues[i]);
164                 eth_dev->data->tx_queues[i] = NULL;
165         }
166         eth_dev->data->nb_tx_queues = 0;
167
168         /* Free up RQ's and CQ's */
169         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
170                 dev_ops->rx_queue_release(eth_dev->data->rx_queues[i]);
171                 eth_dev->data->rx_queues[i] = NULL;
172         }
173         eth_dev->data->nb_rx_queues = 0;
174
175         /* Free tm resources */
176         roc_nix_tm_fini(nix);
177
178         /* Unregister queue irqs */
179         roc_nix_unregister_queue_irqs(nix);
180
181         /* Unregister cq irqs */
182         if (eth_dev->data->dev_conf.intr_conf.rxq)
183                 roc_nix_unregister_cq_irqs(nix);
184
185         /* Free nix lf resources */
186         rc = roc_nix_lf_free(nix);
187         if (rc)
188                 plt_err("Failed to free nix lf, rc=%d", rc);
189
190         rte_free(eth_dev->data->mac_addrs);
191         eth_dev->data->mac_addrs = NULL;
192
193         /* Check if mbox close is needed */
194         if (!mbox_close)
195                 return 0;
196
197         rc = roc_nix_dev_fini(nix);
198         /* Can be freed later by PMD if NPA LF is in use */
199         if (rc == -EAGAIN) {
200                 eth_dev->data->dev_private = NULL;
201                 return 0;
202         } else if (rc) {
203                 plt_err("Failed in nix dev fini, rc=%d", rc);
204         }
205
206         return rc;
207 }
208
209 int
210 cnxk_nix_remove(struct rte_pci_device *pci_dev)
211 {
212         struct rte_eth_dev *eth_dev;
213         struct roc_nix *nix;
214         int rc = -EINVAL;
215
216         eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
217         if (eth_dev) {
218                 /* Cleanup eth dev */
219                 rc = cnxk_eth_dev_uninit(eth_dev, true);
220                 if (rc)
221                         return rc;
222
223                 rte_eth_dev_release_port(eth_dev);
224         }
225
226         /* Nothing to be done for secondary processes */
227         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
228                 return 0;
229
230         /* Check if this device is hosting common resource */
231         nix = roc_idev_npa_nix_get();
232         if (nix->pci_dev != pci_dev)
233                 return 0;
234
235         /* Try nix fini now */
236         rc = roc_nix_dev_fini(nix);
237         if (rc == -EAGAIN) {
238                 plt_info("%s: common resource in use by other devices",
239                          pci_dev->name);
240                 goto exit;
241         } else if (rc) {
242                 plt_err("Failed in nix dev fini, rc=%d", rc);
243                 goto exit;
244         }
245
246         /* Free device pointer as rte_ethdev does not have it anymore */
247         rte_free(nix);
248 exit:
249         return rc;
250 }
251
252 int
253 cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
254 {
255         int rc;
256
257         RTE_SET_USED(pci_drv);
258
259         rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),
260                                            cnxk_eth_dev_init);
261
262         /* On error on secondary, recheck if port exists in primary or
263          * in mid of detach state.
264          */
265         if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
266                 if (!rte_eth_dev_allocated(pci_dev->device.name))
267                         return 0;
268         return rc;
269 }