net/sfc: implement Rx queue setup release operations
[dpdk.git] / drivers / net / sfc / sfc_ethdev.c
1 /*-
2  * Copyright (c) 2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * This software was jointly developed between OKTET Labs (under contract
6  * for Solarflare) and Solarflare Communications, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <rte_dev.h>
31 #include <rte_ethdev.h>
32 #include <rte_pci.h>
33
34 #include "efx.h"
35
36 #include "sfc.h"
37 #include "sfc_debug.h"
38 #include "sfc_log.h"
39 #include "sfc_kvargs.h"
40 #include "sfc_ev.h"
41 #include "sfc_rx.h"
42
43
44 static void
45 sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
46 {
47         struct sfc_adapter *sa = dev->data->dev_private;
48
49         sfc_log_init(sa, "entry");
50
51         dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
52         dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
53
54         dev_info->max_rx_queues = sa->rxq_max;
55
56         /* By default packets are dropped if no descriptors are available */
57         dev_info->default_rxconf.rx_drop_en = 1;
58
59         dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
60         dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
61         /* The RXQ hardware requires that the descriptor count is a power
62          * of 2, but rx_desc_lim cannot properly describe that constraint.
63          */
64         dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
65 }
66
67 static int
68 sfc_dev_configure(struct rte_eth_dev *dev)
69 {
70         struct rte_eth_dev_data *dev_data = dev->data;
71         struct sfc_adapter *sa = dev_data->dev_private;
72         int rc;
73
74         sfc_log_init(sa, "entry n_rxq=%u n_txq=%u",
75                      dev_data->nb_rx_queues, dev_data->nb_tx_queues);
76
77         sfc_adapter_lock(sa);
78         switch (sa->state) {
79         case SFC_ADAPTER_CONFIGURED:
80                 sfc_close(sa);
81                 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
82                 /* FALLTHROUGH */
83         case SFC_ADAPTER_INITIALIZED:
84                 rc = sfc_configure(sa);
85                 break;
86         default:
87                 sfc_err(sa, "unexpected adapter state %u to configure",
88                         sa->state);
89                 rc = EINVAL;
90                 break;
91         }
92         sfc_adapter_unlock(sa);
93
94         sfc_log_init(sa, "done %d", rc);
95         SFC_ASSERT(rc >= 0);
96         return -rc;
97 }
98
99 static int
100 sfc_dev_start(struct rte_eth_dev *dev)
101 {
102         struct sfc_adapter *sa = dev->data->dev_private;
103         int rc;
104
105         sfc_log_init(sa, "entry");
106
107         sfc_adapter_lock(sa);
108         rc = sfc_start(sa);
109         sfc_adapter_unlock(sa);
110
111         sfc_log_init(sa, "done %d", rc);
112         SFC_ASSERT(rc >= 0);
113         return -rc;
114 }
115
116 static int
117 sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
118 {
119         struct sfc_adapter *sa = dev->data->dev_private;
120         struct rte_eth_link *dev_link = &dev->data->dev_link;
121         struct rte_eth_link old_link;
122         struct rte_eth_link current_link;
123
124         sfc_log_init(sa, "entry");
125
126         if (sa->state != SFC_ADAPTER_STARTED)
127                 return 0;
128
129 retry:
130         EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
131         *(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
132
133         if (wait_to_complete) {
134                 efx_link_mode_t link_mode;
135
136                 efx_port_poll(sa->nic, &link_mode);
137                 sfc_port_link_mode_to_info(link_mode, &current_link);
138
139                 if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
140                                          *(uint64_t *)&old_link,
141                                          *(uint64_t *)&current_link))
142                         goto retry;
143         } else {
144                 sfc_ev_mgmt_qpoll(sa);
145                 *(int64_t *)&current_link =
146                         rte_atomic64_read((rte_atomic64_t *)dev_link);
147         }
148
149         if (old_link.link_status != current_link.link_status)
150                 sfc_info(sa, "Link status is %s",
151                          current_link.link_status ? "UP" : "DOWN");
152
153         return old_link.link_status == current_link.link_status ? 0 : -1;
154 }
155
156 static void
157 sfc_dev_stop(struct rte_eth_dev *dev)
158 {
159         struct sfc_adapter *sa = dev->data->dev_private;
160
161         sfc_log_init(sa, "entry");
162
163         sfc_adapter_lock(sa);
164         sfc_stop(sa);
165         sfc_adapter_unlock(sa);
166
167         sfc_log_init(sa, "done");
168 }
169
170 static void
171 sfc_dev_close(struct rte_eth_dev *dev)
172 {
173         struct sfc_adapter *sa = dev->data->dev_private;
174
175         sfc_log_init(sa, "entry");
176
177         sfc_adapter_lock(sa);
178         switch (sa->state) {
179         case SFC_ADAPTER_STARTED:
180                 sfc_stop(sa);
181                 SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
182                 /* FALLTHROUGH */
183         case SFC_ADAPTER_CONFIGURED:
184                 sfc_close(sa);
185                 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
186                 /* FALLTHROUGH */
187         case SFC_ADAPTER_INITIALIZED:
188                 break;
189         default:
190                 sfc_err(sa, "unexpected adapter state %u on close", sa->state);
191                 break;
192         }
193         sfc_adapter_unlock(sa);
194
195         sfc_log_init(sa, "done");
196 }
197
198 static int
199 sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
200                    uint16_t nb_rx_desc, unsigned int socket_id,
201                    const struct rte_eth_rxconf *rx_conf,
202                    struct rte_mempool *mb_pool)
203 {
204         struct sfc_adapter *sa = dev->data->dev_private;
205         int rc;
206
207         sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
208                      rx_queue_id, nb_rx_desc, socket_id);
209
210         sfc_adapter_lock(sa);
211
212         rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
213                           rx_conf, mb_pool);
214         if (rc != 0)
215                 goto fail_rx_qinit;
216
217         dev->data->rx_queues[rx_queue_id] = sa->rxq_info[rx_queue_id].rxq;
218
219         sfc_adapter_unlock(sa);
220
221         return 0;
222
223 fail_rx_qinit:
224         sfc_adapter_unlock(sa);
225         SFC_ASSERT(rc > 0);
226         return -rc;
227 }
228
229 static void
230 sfc_rx_queue_release(void *queue)
231 {
232         struct sfc_rxq *rxq = queue;
233         struct sfc_adapter *sa;
234         unsigned int sw_index;
235
236         if (rxq == NULL)
237                 return;
238
239         sa = rxq->evq->sa;
240         sfc_adapter_lock(sa);
241
242         sw_index = sfc_rxq_sw_index(rxq);
243
244         sfc_log_init(sa, "RxQ=%u", sw_index);
245
246         sa->eth_dev->data->rx_queues[sw_index] = NULL;
247
248         sfc_rx_qfini(sa, sw_index);
249
250         sfc_adapter_unlock(sa);
251 }
252
253 static const struct eth_dev_ops sfc_eth_dev_ops = {
254         .dev_configure                  = sfc_dev_configure,
255         .dev_start                      = sfc_dev_start,
256         .dev_stop                       = sfc_dev_stop,
257         .dev_close                      = sfc_dev_close,
258         .link_update                    = sfc_dev_link_update,
259         .dev_infos_get                  = sfc_dev_infos_get,
260         .rx_queue_setup                 = sfc_rx_queue_setup,
261         .rx_queue_release               = sfc_rx_queue_release,
262 };
263
264 static int
265 sfc_eth_dev_init(struct rte_eth_dev *dev)
266 {
267         struct sfc_adapter *sa = dev->data->dev_private;
268         struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(dev);
269         int rc;
270         const efx_nic_cfg_t *encp;
271         const struct ether_addr *from;
272
273         /* Required for logging */
274         sa->eth_dev = dev;
275
276         /* Copy PCI device info to the dev->data */
277         rte_eth_copy_pci_info(dev, pci_dev);
278
279         rc = sfc_kvargs_parse(sa);
280         if (rc != 0)
281                 goto fail_kvargs_parse;
282
283         rc = sfc_kvargs_process(sa, SFC_KVARG_DEBUG_INIT,
284                                 sfc_kvarg_bool_handler, &sa->debug_init);
285         if (rc != 0)
286                 goto fail_kvarg_debug_init;
287
288         sfc_log_init(sa, "entry");
289
290         dev->data->mac_addrs = rte_zmalloc("sfc", ETHER_ADDR_LEN, 0);
291         if (dev->data->mac_addrs == NULL) {
292                 rc = ENOMEM;
293                 goto fail_mac_addrs;
294         }
295
296         sfc_adapter_lock_init(sa);
297         sfc_adapter_lock(sa);
298
299         sfc_log_init(sa, "attaching");
300         rc = sfc_attach(sa);
301         if (rc != 0)
302                 goto fail_attach;
303
304         encp = efx_nic_cfg_get(sa->nic);
305
306         /*
307          * The arguments are really reverse order in comparison to
308          * Linux kernel. Copy from NIC config to Ethernet device data.
309          */
310         from = (const struct ether_addr *)(encp->enc_mac_addr);
311         ether_addr_copy(from, &dev->data->mac_addrs[0]);
312
313         dev->dev_ops = &sfc_eth_dev_ops;
314
315         sfc_adapter_unlock(sa);
316
317         sfc_log_init(sa, "done");
318         return 0;
319
320 fail_attach:
321         sfc_adapter_unlock(sa);
322         sfc_adapter_lock_fini(sa);
323         rte_free(dev->data->mac_addrs);
324         dev->data->mac_addrs = NULL;
325
326 fail_mac_addrs:
327 fail_kvarg_debug_init:
328         sfc_kvargs_cleanup(sa);
329
330 fail_kvargs_parse:
331         sfc_log_init(sa, "failed %d", rc);
332         SFC_ASSERT(rc > 0);
333         return -rc;
334 }
335
336 static int
337 sfc_eth_dev_uninit(struct rte_eth_dev *dev)
338 {
339         struct sfc_adapter *sa = dev->data->dev_private;
340
341         sfc_log_init(sa, "entry");
342
343         sfc_adapter_lock(sa);
344
345         sfc_detach(sa);
346
347         rte_free(dev->data->mac_addrs);
348         dev->data->mac_addrs = NULL;
349
350         dev->dev_ops = NULL;
351
352         sfc_kvargs_cleanup(sa);
353
354         sfc_adapter_unlock(sa);
355         sfc_adapter_lock_fini(sa);
356
357         sfc_log_init(sa, "done");
358
359         /* Required for logging, so cleanup last */
360         sa->eth_dev = NULL;
361         return 0;
362 }
363
364 static const struct rte_pci_id pci_id_sfc_efx_map[] = {
365         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_FARMINGDALE) },
366         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_GREENPORT) },
367         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD) },
368         { .vendor_id = 0 /* sentinel */ }
369 };
370
371 static struct eth_driver sfc_efx_pmd = {
372         .pci_drv = {
373                 .id_table = pci_id_sfc_efx_map,
374                 .drv_flags =
375                         RTE_PCI_DRV_NEED_MAPPING,
376                 .probe = rte_eth_dev_pci_probe,
377                 .remove = rte_eth_dev_pci_remove,
378         },
379         .eth_dev_init = sfc_eth_dev_init,
380         .eth_dev_uninit = sfc_eth_dev_uninit,
381         .dev_private_size = sizeof(struct sfc_adapter),
382 };
383
384 RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
385 RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
386 RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
387         SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);