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