fe6beb31af26f05a02837088dea7a447d177772c
[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
42
43 static void
44 sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
45 {
46         struct sfc_adapter *sa = dev->data->dev_private;
47
48         sfc_log_init(sa, "entry");
49
50         dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
51         dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
52
53         /* By default packets are dropped if no descriptors are available */
54         dev_info->default_rxconf.rx_drop_en = 1;
55
56         dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
57         dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
58         /* The RXQ hardware requires that the descriptor count is a power
59          * of 2, but rx_desc_lim cannot properly describe that constraint.
60          */
61         dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
62 }
63
64 static int
65 sfc_dev_configure(struct rte_eth_dev *dev)
66 {
67         struct rte_eth_dev_data *dev_data = dev->data;
68         struct sfc_adapter *sa = dev_data->dev_private;
69         int rc;
70
71         sfc_log_init(sa, "entry n_rxq=%u n_txq=%u",
72                      dev_data->nb_rx_queues, dev_data->nb_tx_queues);
73
74         sfc_adapter_lock(sa);
75         switch (sa->state) {
76         case SFC_ADAPTER_CONFIGURED:
77                 sfc_close(sa);
78                 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
79                 /* FALLTHROUGH */
80         case SFC_ADAPTER_INITIALIZED:
81                 rc = sfc_configure(sa);
82                 break;
83         default:
84                 sfc_err(sa, "unexpected adapter state %u to configure",
85                         sa->state);
86                 rc = EINVAL;
87                 break;
88         }
89         sfc_adapter_unlock(sa);
90
91         sfc_log_init(sa, "done %d", rc);
92         SFC_ASSERT(rc >= 0);
93         return -rc;
94 }
95
96 static int
97 sfc_dev_start(struct rte_eth_dev *dev)
98 {
99         struct sfc_adapter *sa = dev->data->dev_private;
100         int rc;
101
102         sfc_log_init(sa, "entry");
103
104         sfc_adapter_lock(sa);
105         rc = sfc_start(sa);
106         sfc_adapter_unlock(sa);
107
108         sfc_log_init(sa, "done %d", rc);
109         SFC_ASSERT(rc >= 0);
110         return -rc;
111 }
112
113 static int
114 sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
115 {
116         struct sfc_adapter *sa = dev->data->dev_private;
117         struct rte_eth_link *dev_link = &dev->data->dev_link;
118         struct rte_eth_link old_link;
119         struct rte_eth_link current_link;
120
121         sfc_log_init(sa, "entry");
122
123         if (sa->state != SFC_ADAPTER_STARTED)
124                 return 0;
125
126 retry:
127         EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
128         *(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
129
130         if (wait_to_complete) {
131                 efx_link_mode_t link_mode;
132
133                 efx_port_poll(sa->nic, &link_mode);
134                 sfc_port_link_mode_to_info(link_mode, &current_link);
135
136                 if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
137                                          *(uint64_t *)&old_link,
138                                          *(uint64_t *)&current_link))
139                         goto retry;
140         } else {
141                 sfc_ev_mgmt_qpoll(sa);
142                 *(int64_t *)&current_link =
143                         rte_atomic64_read((rte_atomic64_t *)dev_link);
144         }
145
146         if (old_link.link_status != current_link.link_status)
147                 sfc_info(sa, "Link status is %s",
148                          current_link.link_status ? "UP" : "DOWN");
149
150         return old_link.link_status == current_link.link_status ? 0 : -1;
151 }
152
153 static void
154 sfc_dev_stop(struct rte_eth_dev *dev)
155 {
156         struct sfc_adapter *sa = dev->data->dev_private;
157
158         sfc_log_init(sa, "entry");
159
160         sfc_adapter_lock(sa);
161         sfc_stop(sa);
162         sfc_adapter_unlock(sa);
163
164         sfc_log_init(sa, "done");
165 }
166
167 static void
168 sfc_dev_close(struct rte_eth_dev *dev)
169 {
170         struct sfc_adapter *sa = dev->data->dev_private;
171
172         sfc_log_init(sa, "entry");
173
174         sfc_adapter_lock(sa);
175         switch (sa->state) {
176         case SFC_ADAPTER_STARTED:
177                 sfc_stop(sa);
178                 SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
179                 /* FALLTHROUGH */
180         case SFC_ADAPTER_CONFIGURED:
181                 sfc_close(sa);
182                 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
183                 /* FALLTHROUGH */
184         case SFC_ADAPTER_INITIALIZED:
185                 break;
186         default:
187                 sfc_err(sa, "unexpected adapter state %u on close", sa->state);
188                 break;
189         }
190         sfc_adapter_unlock(sa);
191
192         sfc_log_init(sa, "done");
193 }
194
195 static const struct eth_dev_ops sfc_eth_dev_ops = {
196         .dev_configure                  = sfc_dev_configure,
197         .dev_start                      = sfc_dev_start,
198         .dev_stop                       = sfc_dev_stop,
199         .dev_close                      = sfc_dev_close,
200         .link_update                    = sfc_dev_link_update,
201         .dev_infos_get                  = sfc_dev_infos_get,
202 };
203
204 static int
205 sfc_eth_dev_init(struct rte_eth_dev *dev)
206 {
207         struct sfc_adapter *sa = dev->data->dev_private;
208         struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(dev);
209         int rc;
210         const efx_nic_cfg_t *encp;
211         const struct ether_addr *from;
212
213         /* Required for logging */
214         sa->eth_dev = dev;
215
216         /* Copy PCI device info to the dev->data */
217         rte_eth_copy_pci_info(dev, pci_dev);
218
219         rc = sfc_kvargs_parse(sa);
220         if (rc != 0)
221                 goto fail_kvargs_parse;
222
223         rc = sfc_kvargs_process(sa, SFC_KVARG_DEBUG_INIT,
224                                 sfc_kvarg_bool_handler, &sa->debug_init);
225         if (rc != 0)
226                 goto fail_kvarg_debug_init;
227
228         sfc_log_init(sa, "entry");
229
230         dev->data->mac_addrs = rte_zmalloc("sfc", ETHER_ADDR_LEN, 0);
231         if (dev->data->mac_addrs == NULL) {
232                 rc = ENOMEM;
233                 goto fail_mac_addrs;
234         }
235
236         sfc_adapter_lock_init(sa);
237         sfc_adapter_lock(sa);
238
239         sfc_log_init(sa, "attaching");
240         rc = sfc_attach(sa);
241         if (rc != 0)
242                 goto fail_attach;
243
244         encp = efx_nic_cfg_get(sa->nic);
245
246         /*
247          * The arguments are really reverse order in comparison to
248          * Linux kernel. Copy from NIC config to Ethernet device data.
249          */
250         from = (const struct ether_addr *)(encp->enc_mac_addr);
251         ether_addr_copy(from, &dev->data->mac_addrs[0]);
252
253         dev->dev_ops = &sfc_eth_dev_ops;
254
255         sfc_adapter_unlock(sa);
256
257         sfc_log_init(sa, "done");
258         return 0;
259
260 fail_attach:
261         sfc_adapter_unlock(sa);
262         sfc_adapter_lock_fini(sa);
263         rte_free(dev->data->mac_addrs);
264         dev->data->mac_addrs = NULL;
265
266 fail_mac_addrs:
267 fail_kvarg_debug_init:
268         sfc_kvargs_cleanup(sa);
269
270 fail_kvargs_parse:
271         sfc_log_init(sa, "failed %d", rc);
272         SFC_ASSERT(rc > 0);
273         return -rc;
274 }
275
276 static int
277 sfc_eth_dev_uninit(struct rte_eth_dev *dev)
278 {
279         struct sfc_adapter *sa = dev->data->dev_private;
280
281         sfc_log_init(sa, "entry");
282
283         sfc_adapter_lock(sa);
284
285         sfc_detach(sa);
286
287         rte_free(dev->data->mac_addrs);
288         dev->data->mac_addrs = NULL;
289
290         dev->dev_ops = NULL;
291
292         sfc_kvargs_cleanup(sa);
293
294         sfc_adapter_unlock(sa);
295         sfc_adapter_lock_fini(sa);
296
297         sfc_log_init(sa, "done");
298
299         /* Required for logging, so cleanup last */
300         sa->eth_dev = NULL;
301         return 0;
302 }
303
304 static const struct rte_pci_id pci_id_sfc_efx_map[] = {
305         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_FARMINGDALE) },
306         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_GREENPORT) },
307         { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD) },
308         { .vendor_id = 0 /* sentinel */ }
309 };
310
311 static struct eth_driver sfc_efx_pmd = {
312         .pci_drv = {
313                 .id_table = pci_id_sfc_efx_map,
314                 .drv_flags =
315                         RTE_PCI_DRV_NEED_MAPPING,
316                 .probe = rte_eth_dev_pci_probe,
317                 .remove = rte_eth_dev_pci_remove,
318         },
319         .eth_dev_init = sfc_eth_dev_init,
320         .eth_dev_uninit = sfc_eth_dev_uninit,
321         .dev_private_size = sizeof(struct sfc_adapter),
322 };
323
324 RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
325 RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
326 RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
327         SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);