xref: /dpdk/drivers/net/sfc/sfc_ethdev.c (revision ce35b05c635ea358242983b3d353e24c5edf3264)
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);
388