xref: /dpdk/drivers/net/ark/ark_ethdev.c (revision 3c4898ef762eeb2578b9ae3d7f6e3a0e5cbca8c8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2015-2018 Atomic Rules LLC
3  */
4 
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <dlfcn.h>
8 
9 #include <bus_pci_driver.h>
10 #include <ethdev_pci.h>
11 #include <rte_kvargs.h>
12 
13 #include "ark_global.h"
14 #include "ark_logs.h"
15 #include "ark_ethdev_tx.h"
16 #include "ark_ethdev_rx.h"
17 #include "ark_mpu.h"
18 #include "ark_ddm.h"
19 #include "ark_udm.h"
20 #include "ark_pktdir.h"
21 #include "ark_pktgen.h"
22 #include "ark_pktchkr.h"
23 
24 /*  Internal prototypes */
25 static int eth_ark_check_args(struct ark_adapter *ark, const char *params);
26 static int eth_ark_dev_init(struct rte_eth_dev *dev);
27 static int ark_config_device(struct rte_eth_dev *dev);
28 static int eth_ark_dev_uninit(struct rte_eth_dev *eth_dev);
29 static int eth_ark_dev_configure(struct rte_eth_dev *dev);
30 static int eth_ark_dev_start(struct rte_eth_dev *dev);
31 static int eth_ark_dev_stop(struct rte_eth_dev *dev);
32 static int eth_ark_dev_close(struct rte_eth_dev *dev);
33 static int eth_ark_dev_info_get(struct rte_eth_dev *dev,
34 				struct rte_eth_dev_info *dev_info);
35 static int eth_ark_dev_link_update(struct rte_eth_dev *dev,
36 				   int wait_to_complete);
37 static int eth_ark_dev_set_link_up(struct rte_eth_dev *dev);
38 static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
39 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
40 				  struct rte_eth_stats *stats);
41 static int eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
42 static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
43 					 struct rte_ether_addr *mac_addr);
44 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
45 			       struct rte_ether_addr *mac_addr,
46 			       uint32_t index,
47 			       uint32_t pool);
48 static void eth_ark_macaddr_remove(struct rte_eth_dev *dev,
49 				   uint32_t index);
50 static int  eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size);
51 
52 /*
53  * The packet generator is a functional block used to generate packet
54  * patterns for testing.  It is not intended for nominal use.
55  */
56 #define ARK_PKTGEN_ARG "Pkt_gen"
57 
58 /*
59  * The packet checker is a functional block used to verify packet
60  * patterns for testing.  It is not intended for nominal use.
61  */
62 #define ARK_PKTCHKR_ARG "Pkt_chkr"
63 
64 /*
65  * The packet director is used to select the internal ingress and
66  * egress packets paths during testing.  It is not intended for
67  * nominal use.
68  */
69 #define ARK_PKTDIR_ARG "Pkt_dir"
70 
71 /* Devinfo configurations */
72 #define ARK_RX_MAX_QUEUE (4096 * 4)
73 #define ARK_RX_MIN_QUEUE (512)
74 #define ARK_RX_MAX_PKT_LEN ((16 * 1024) - 128)
75 #define ARK_RX_MIN_BUFSIZE (1024)
76 
77 #define ARK_TX_MAX_QUEUE (4096 * 4)
78 #define ARK_TX_MIN_QUEUE (256)
79 
80 static const char * const valid_arguments[] = {
81 	ARK_PKTGEN_ARG,
82 	ARK_PKTCHKR_ARG,
83 	ARK_PKTDIR_ARG,
84 	NULL
85 };
86 
87 #define AR_VENDOR_ID 0x1d6c
88 static const struct rte_pci_id pci_id_ark_map[] = {
89 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100d)},
90 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100e)},
91 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100f)},
92 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1010)},
93 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1017)},
94 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1018)},
95 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1019)},
96 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101a)},
97 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101b)},
98 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101c)},
99 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101e)},
100 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101f)},
101 	{RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1022)},
102 	{.vendor_id = 0, /* sentinel */ },
103 };
104 
105 /*
106  * This structure is used to statically define the capabilities
107  * of supported devices.
108  * Capabilities:
109  *    isvf -- defined for function id that are virtual
110  */
111 struct ark_caps {
112 	bool isvf;
113 };
114 struct ark_dev_caps {
115 	uint32_t  device_id;
116 	struct ark_caps  caps;
117 };
118 #define SET_DEV_CAPS(id, vf)			\
119 	{id, {.isvf = vf} }
120 
121 static const struct ark_dev_caps
122 ark_device_caps[] = {
123 		     SET_DEV_CAPS(0x100d, false),
124 		     SET_DEV_CAPS(0x100e, false),
125 		     SET_DEV_CAPS(0x100f, false),
126 		     SET_DEV_CAPS(0x1010, false),
127 		     SET_DEV_CAPS(0x1017, false),
128 		     SET_DEV_CAPS(0x1018, false),
129 		     SET_DEV_CAPS(0x1019, false),
130 		     SET_DEV_CAPS(0x101a, false),
131 		     SET_DEV_CAPS(0x101b, false),
132 		     SET_DEV_CAPS(0x101c, true),
133 		     SET_DEV_CAPS(0x101e, false),
134 		     SET_DEV_CAPS(0x101f, false),
135 		     {.device_id = 0,}
136 };
137 
138 static int
139 eth_ark_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
140 		struct rte_pci_device *pci_dev)
141 {
142 	struct rte_eth_dev *eth_dev;
143 	int ret;
144 
145 	eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct ark_adapter));
146 
147 	if (eth_dev == NULL)
148 		return -ENOMEM;
149 
150 	ret = eth_ark_dev_init(eth_dev);
151 	if (ret)
152 		rte_eth_dev_release_port(eth_dev);
153 
154 	return ret;
155 }
156 
157 static int
158 eth_ark_pci_remove(struct rte_pci_device *pci_dev)
159 {
160 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_ark_dev_uninit);
161 }
162 
163 static struct rte_pci_driver rte_ark_pmd = {
164 	.id_table = pci_id_ark_map,
165 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
166 	.probe = eth_ark_pci_probe,
167 	.remove = eth_ark_pci_remove,
168 };
169 
170 static const struct eth_dev_ops ark_eth_dev_ops = {
171 	.dev_configure = eth_ark_dev_configure,
172 	.dev_start = eth_ark_dev_start,
173 	.dev_stop = eth_ark_dev_stop,
174 	.dev_close = eth_ark_dev_close,
175 
176 	.dev_infos_get = eth_ark_dev_info_get,
177 
178 	.rx_queue_setup = eth_ark_dev_rx_queue_setup,
179 	.tx_queue_setup = eth_ark_tx_queue_setup,
180 
181 	.link_update = eth_ark_dev_link_update,
182 	.dev_set_link_up = eth_ark_dev_set_link_up,
183 	.dev_set_link_down = eth_ark_dev_set_link_down,
184 
185 	.rx_queue_start = eth_ark_rx_start_queue,
186 	.rx_queue_stop = eth_ark_rx_stop_queue,
187 
188 	.tx_queue_start = eth_ark_tx_queue_start,
189 	.tx_queue_stop = eth_ark_tx_queue_stop,
190 
191 	.stats_get = eth_ark_dev_stats_get,
192 	.stats_reset = eth_ark_dev_stats_reset,
193 
194 	.mac_addr_add = eth_ark_macaddr_add,
195 	.mac_addr_remove = eth_ark_macaddr_remove,
196 	.mac_addr_set = eth_ark_set_default_mac_addr,
197 
198 	.mtu_set = eth_ark_set_mtu,
199 };
200 
201 static int
202 check_for_ext(struct ark_adapter *ark)
203 {
204 	int found = 0;
205 
206 	/* Get the env */
207 	const char *dllpath = getenv("ARK_EXT_PATH");
208 
209 	if (dllpath == NULL) {
210 		ARK_PMD_LOG(DEBUG, "EXT NO dll path specified\n");
211 		return 0;
212 	}
213 	ARK_PMD_LOG(NOTICE, "EXT found dll path at %s\n", dllpath);
214 
215 	/* Open and load the .so */
216 	ark->d_handle = dlopen(dllpath, RTLD_LOCAL | RTLD_LAZY);
217 	if (ark->d_handle == NULL) {
218 		ARK_PMD_LOG(ERR, "Could not load user extension %s\n",
219 			    dllpath);
220 		return -1;
221 	}
222 	ARK_PMD_LOG(DEBUG, "SUCCESS: loaded user extension %s\n",
223 			    dllpath);
224 
225 	/* Get the entry points */
226 	ark->user_ext.dev_init =
227 		(void *(*)(struct rte_eth_dev *, void *, int))
228 		dlsym(ark->d_handle, "rte_pmd_ark_dev_init");
229 	ARK_PMD_LOG(DEBUG, "device ext init pointer = %p\n",
230 		      ark->user_ext.dev_init);
231 	ark->user_ext.dev_get_port_count =
232 		(int (*)(struct rte_eth_dev *, void *))
233 		dlsym(ark->d_handle, "rte_pmd_ark_dev_get_port_count");
234 	ark->user_ext.dev_uninit =
235 		(void (*)(struct rte_eth_dev *, void *))
236 		dlsym(ark->d_handle, "rte_pmd_ark_dev_uninit");
237 	ark->user_ext.dev_configure =
238 		(int (*)(struct rte_eth_dev *, void *))
239 		dlsym(ark->d_handle, "rte_pmd_ark_dev_configure");
240 	ark->user_ext.dev_start =
241 		(int (*)(struct rte_eth_dev *, void *))
242 		dlsym(ark->d_handle, "rte_pmd_ark_dev_start");
243 	ark->user_ext.dev_stop =
244 		(void (*)(struct rte_eth_dev *, void *))
245 		dlsym(ark->d_handle, "rte_pmd_ark_dev_stop");
246 	ark->user_ext.dev_close =
247 		(void (*)(struct rte_eth_dev *, void *))
248 		dlsym(ark->d_handle, "rte_pmd_ark_dev_close");
249 	ark->user_ext.link_update =
250 		(int (*)(struct rte_eth_dev *, int, void *))
251 		dlsym(ark->d_handle, "rte_pmd_ark_link_update");
252 	ark->user_ext.dev_set_link_up =
253 		(int (*)(struct rte_eth_dev *, void *))
254 		dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_up");
255 	ark->user_ext.dev_set_link_down =
256 		(int (*)(struct rte_eth_dev *, void *))
257 		dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_down");
258 	ark->user_ext.stats_get =
259 		(int (*)(struct rte_eth_dev *, struct rte_eth_stats *,
260 			  void *))
261 		dlsym(ark->d_handle, "rte_pmd_ark_stats_get");
262 	ark->user_ext.stats_reset =
263 		(void (*)(struct rte_eth_dev *, void *))
264 		dlsym(ark->d_handle, "rte_pmd_ark_stats_reset");
265 	ark->user_ext.mac_addr_add =
266 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
267 			uint32_t, uint32_t, void *))
268 		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_add");
269 	ark->user_ext.mac_addr_remove =
270 		(void (*)(struct rte_eth_dev *, uint32_t, void *))
271 		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_remove");
272 	ark->user_ext.mac_addr_set =
273 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
274 			  void *))
275 		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_set");
276 	ark->user_ext.set_mtu =
277 		(int (*)(struct rte_eth_dev *, uint16_t,
278 			  void *))
279 		dlsym(ark->d_handle, "rte_pmd_ark_set_mtu");
280 	ark->user_ext.rx_user_meta_hook =
281 		(rx_user_meta_hook_fn)dlsym(ark->d_handle,
282 					    "rte_pmd_ark_rx_user_meta_hook");
283 	ark->user_ext.tx_user_meta_hook =
284 		(tx_user_meta_hook_fn)dlsym(ark->d_handle,
285 					    "rte_pmd_ark_tx_user_meta_hook");
286 
287 	return found;
288 }
289 
290 static int
291 eth_ark_dev_init(struct rte_eth_dev *dev)
292 {
293 	struct ark_adapter *ark = dev->data->dev_private;
294 	struct rte_pci_device *pci_dev;
295 	int ret;
296 	int port_count = 1;
297 	int p;
298 	uint16_t num_queues;
299 
300 	ark->eth_dev = dev;
301 
302 	ARK_PMD_LOG(DEBUG, "\n");
303 
304 	/* Check to see if there is an extension that we need to load */
305 	ret = check_for_ext(ark);
306 	if (ret)
307 		return ret;
308 
309 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
310 	rte_eth_copy_pci_info(dev, pci_dev);
311 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
312 
313 	p = 0;
314 	while (ark_device_caps[p].device_id != 0) {
315 		if (pci_dev->id.device_id == ark_device_caps[p].device_id) {
316 			ark->isvf = ark_device_caps[p].caps.isvf;
317 			break;
318 		}
319 		p++;
320 	}
321 
322 	/* Use dummy function until setup */
323 	dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
324 	dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
325 
326 	ark->bar0 = (uint8_t *)pci_dev->mem_resource[0].addr;
327 	ark->a_bar = (uint8_t *)pci_dev->mem_resource[2].addr;
328 
329 	ark->sysctrl.v  = (void *)&ark->bar0[ARK_SYSCTRL_BASE];
330 	ark->mpurx.v  = (void *)&ark->bar0[ARK_MPU_RX_BASE];
331 	ark->udm.v  = (void *)&ark->bar0[ARK_UDM_BASE];
332 	ark->mputx.v  = (void *)&ark->bar0[ARK_MPU_TX_BASE];
333 	ark->ddm.v  = (void *)&ark->bar0[ARK_DDM_BASE];
334 	ark->cmac.v  = (void *)&ark->bar0[ARK_CMAC_BASE];
335 	ark->external.v  = (void *)&ark->bar0[ARK_EXTERNAL_BASE];
336 	ark->pktdir.v  = (void *)&ark->bar0[ARK_PKTDIR_BASE];
337 	ark->pktgen.v  = (void *)&ark->bar0[ARK_PKTGEN_BASE];
338 	ark->pktchkr.v  = (void *)&ark->bar0[ARK_PKTCHKR_BASE];
339 
340 	ark->started = 0;
341 	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
342 
343 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
344 		      ark->sysctrl.t32[4],
345 		      rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4]));
346 	ARK_PMD_LOG(NOTICE, "Arkville HW Commit_ID: %08x\n",
347 		    rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4]));
348 
349 	/* If HW sanity test fails, return an error */
350 	if (ark->sysctrl.t32[4] != 0xcafef00d) {
351 		ARK_PMD_LOG(ERR,
352 			    "HW Sanity test has failed, expected constant"
353 			    " 0x%x, read 0x%x (%s)\n",
354 			    0xcafef00d,
355 			    ark->sysctrl.t32[4], __func__);
356 		return -1;
357 	}
358 
359 	ARK_PMD_LOG(DEBUG,
360 		    "HW Sanity test has PASSED, expected constant"
361 		    " 0x%x, read 0x%x (%s)\n",
362 		    0xcafef00d, ark->sysctrl.t32[4], __func__);
363 
364 	/* We are a single function multi-port device. */
365 	ret = ark_config_device(dev);
366 	if (ret)
367 		return -1;
368 
369 	dev->dev_ops = &ark_eth_dev_ops;
370 	dev->rx_queue_count = eth_ark_dev_rx_queue_count;
371 
372 	dev->data->mac_addrs = rte_zmalloc("ark", RTE_ETHER_ADDR_LEN, 0);
373 	if (!dev->data->mac_addrs) {
374 		ARK_PMD_LOG(ERR,
375 			    "Failed to allocated memory for storing mac address"
376 			    );
377 	}
378 
379 	if (ark->user_ext.dev_init) {
380 		ark->user_data[dev->data->port_id] =
381 			ark->user_ext.dev_init(dev, ark->a_bar, 0);
382 		if (!ark->user_data[dev->data->port_id]) {
383 			ARK_PMD_LOG(WARNING,
384 				    "Failed to initialize PMD extension!"
385 				    " continuing without it\n");
386 			memset(&ark->user_ext, 0, sizeof(struct ark_user_ext));
387 			dlclose(ark->d_handle);
388 		}
389 	}
390 
391 	if (pci_dev->device.devargs)
392 		ret = eth_ark_check_args(ark, pci_dev->device.devargs->args);
393 	else
394 		ARK_PMD_LOG(INFO, "No Device args found\n");
395 
396 	if (ret)
397 		goto error;
398 	/*
399 	 * We will create additional devices based on the number of requested
400 	 * ports
401 	 */
402 	if (ark->user_ext.dev_get_port_count)
403 		port_count =
404 			ark->user_ext.dev_get_port_count(dev,
405 				 ark->user_data[dev->data->port_id]);
406 	ark->num_ports = port_count;
407 	num_queues = ark_api_num_queues_per_port(ark->mpurx.v, port_count);
408 
409 	for (p = 0; p < port_count; p++) {
410 		struct rte_eth_dev *eth_dev;
411 		char name[RTE_ETH_NAME_MAX_LEN];
412 
413 		snprintf(name, sizeof(name), "arketh%d",
414 			 dev->data->port_id + p);
415 
416 		if (p == 0) {
417 			/* First port is already allocated by DPDK */
418 			eth_dev = ark->eth_dev;
419 			rte_eth_dev_probing_finish(eth_dev);
420 			continue;
421 		}
422 
423 		/* reserve an ethdev entry */
424 		eth_dev = rte_eth_dev_allocate(name);
425 		if (!eth_dev) {
426 			ARK_PMD_LOG(ERR,
427 				    "Could not allocate eth_dev for port %d\n",
428 				    p);
429 			goto error;
430 		}
431 
432 		eth_dev->device = &pci_dev->device;
433 		/* Device requires new dev_private data */
434 		eth_dev->data->dev_private =
435 			rte_zmalloc_socket(name,
436 					   sizeof(struct ark_adapter),
437 					   RTE_CACHE_LINE_SIZE,
438 					   rte_socket_id());
439 
440 		memcpy(eth_dev->data->dev_private, ark,
441 		       sizeof(struct ark_adapter));
442 		ark = eth_dev->data->dev_private;
443 		ark->qbase = p * num_queues;
444 
445 		eth_dev->dev_ops = ark->eth_dev->dev_ops;
446 		eth_dev->tx_pkt_burst = ark->eth_dev->tx_pkt_burst;
447 		eth_dev->rx_pkt_burst = ark->eth_dev->rx_pkt_burst;
448 
449 		rte_eth_copy_pci_info(eth_dev, pci_dev);
450 		eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
451 
452 		eth_dev->data->mac_addrs = rte_zmalloc(name,
453 						RTE_ETHER_ADDR_LEN, 0);
454 		if (!eth_dev->data->mac_addrs) {
455 			ARK_PMD_LOG(ERR,
456 				    "Memory allocation for MAC failed!"
457 				    " Exiting.\n");
458 			goto error;
459 		}
460 
461 		if (ark->user_ext.dev_init) {
462 			ark->user_data[eth_dev->data->port_id] =
463 				ark->user_ext.dev_init(dev, ark->a_bar, p);
464 		}
465 
466 		rte_eth_dev_probing_finish(eth_dev);
467 	}
468 
469 	return ret;
470 
471 error:
472 	rte_free(dev->data->mac_addrs);
473 	dev->data->mac_addrs = NULL;
474 	return -1;
475 }
476 
477 /*
478  *Initial device configuration when device is opened
479  * setup the DDM, and UDM
480  * Called once per PCIE device
481  */
482 static int
483 ark_config_device(struct rte_eth_dev *dev)
484 {
485 	struct ark_adapter *ark = dev->data->dev_private;
486 	uint16_t num_q, i;
487 	struct ark_mpu_t *mpu;
488 
489 	/*
490 	 * Make sure that the packet director, generator and checker are in a
491 	 * known state
492 	 */
493 	if (!ark->isvf) {
494 		ark->start_pg = 0;
495 		ark->pg_running = 0;
496 		ark->pg = ark_pktgen_init(ark->pktgen.v, 0, 1);
497 		if (ark->pg == NULL)
498 			return -1;
499 		ark_pktgen_reset(ark->pg);
500 		ark->pc = ark_pktchkr_init(ark->pktchkr.v, 0, 1);
501 		if (ark->pc == NULL)
502 			return -1;
503 		ark_pktchkr_stop(ark->pc);
504 		ark->pd = ark_pktdir_init(ark->pktdir.v);
505 		if (ark->pd == NULL)
506 			return -1;
507 	}
508 	/* Verify HW */
509 	if (ark_udm_verify(ark->udm.v))
510 		return -1;
511 	if (ark_ddm_verify(ark->ddm.v))
512 		return -1;
513 
514 	/* MPU reset */
515 	mpu = ark->mpurx.v;
516 	num_q = ark_api_num_queues(mpu);
517 	ark->rx_queues = num_q;
518 	for (i = 0; i < num_q; i++) {
519 		mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
520 	}
521 
522 	mpu = ark->mputx.v;
523 	num_q = ark_api_num_queues(mpu);
524 	ark->tx_queues = num_q;
525 	for (i = 0; i < num_q; i++) {
526 		mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
527 	}
528 
529 	return 0;
530 }
531 
532 static int
533 eth_ark_dev_uninit(struct rte_eth_dev *dev)
534 {
535 	struct ark_adapter *ark = dev->data->dev_private;
536 
537 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
538 		return 0;
539 
540 	if (ark->user_ext.dev_uninit)
541 		ark->user_ext.dev_uninit(dev,
542 			 ark->user_data[dev->data->port_id]);
543 
544 	if (!ark->isvf) {
545 		ark_pktgen_uninit(ark->pg);
546 		ark_pktchkr_uninit(ark->pc);
547 	}
548 
549 	return 0;
550 }
551 
552 static int
553 eth_ark_dev_configure(struct rte_eth_dev *dev)
554 {
555 	struct ark_adapter *ark = dev->data->dev_private;
556 
557 	eth_ark_dev_set_link_up(dev);
558 	if (ark->user_ext.dev_configure)
559 		return ark->user_ext.dev_configure(dev,
560 			   ark->user_data[dev->data->port_id]);
561 	return 0;
562 }
563 
564 static int
565 eth_ark_dev_start(struct rte_eth_dev *dev)
566 {
567 	struct ark_adapter *ark = dev->data->dev_private;
568 	int i;
569 
570 	/* RX Side */
571 	for (i = 0; i < dev->data->nb_rx_queues; i++)
572 		eth_ark_rx_start_queue(dev, i);
573 
574 	/* TX Side */
575 	for (i = 0; i < dev->data->nb_tx_queues; i++)
576 		eth_ark_tx_queue_start(dev, i);
577 
578 	ark->started = 1;
579 	/* set xmit and receive function */
580 	dev->rx_pkt_burst = &eth_ark_recv_pkts;
581 	dev->tx_pkt_burst = &eth_ark_xmit_pkts;
582 
583 	if (!ark->isvf && ark->start_pg)
584 		ark_pktchkr_run(ark->pc);
585 
586 	if (!ark->isvf && ark->start_pg && !ark->pg_running) {
587 		rte_thread_t thread;
588 
589 		/* Delay packet generator start allow the hardware to be ready
590 		 * This is only used for sanity checking with internal generator
591 		 */
592 		char tname[RTE_THREAD_INTERNAL_NAME_SIZE];
593 		snprintf(tname, sizeof(tname), "ark-pg%d", dev->data->port_id);
594 
595 		if (rte_thread_create_internal_control(&thread, tname,
596 					ark_pktgen_delay_start, ark->pg)) {
597 			ARK_PMD_LOG(ERR, "Could not create pktgen "
598 				    "starter thread\n");
599 			return -1;
600 		}
601 		ark->pg_running = 1;
602 	}
603 
604 	if (ark->user_ext.dev_start)
605 		ark->user_ext.dev_start(dev,
606 			ark->user_data[dev->data->port_id]);
607 
608 	return 0;
609 }
610 
611 static int
612 eth_ark_dev_stop(struct rte_eth_dev *dev)
613 {
614 	uint16_t i;
615 	int status;
616 	struct ark_adapter *ark = dev->data->dev_private;
617 
618 	if (ark->started == 0)
619 		return 0;
620 	ark->started = 0;
621 	dev->data->dev_started = 0;
622 
623 	/* Stop the extension first */
624 	if (ark->user_ext.dev_stop)
625 		ark->user_ext.dev_stop(dev,
626 		       ark->user_data[dev->data->port_id]);
627 
628 	/* Stop the packet generator */
629 	if (!ark->isvf && ark->start_pg && ark->pg_running) {
630 		ark_pktgen_pause(ark->pg);
631 		ark->pg_running = 0;
632 	}
633 
634 	dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
635 	dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
636 
637 	/* Stop RX Side */
638 	for (i = 0; i < dev->data->nb_rx_queues; i++)
639 		eth_ark_rx_stop_queue(dev, i);
640 
641 	/* STOP TX Side */
642 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
643 		status = eth_ark_tx_queue_stop(dev, i);
644 		if (status != 0) {
645 			uint16_t port = dev->data->port_id;
646 			ARK_PMD_LOG(ERR,
647 				    "tx_queue stop anomaly"
648 				    " port %u, queue %u\n",
649 				    port, i);
650 		}
651 	}
652 
653 	ark_udm_dump_stats(ark->udm.v, "Post stop");
654 
655 	for (i = 0; i < dev->data->nb_rx_queues; i++)
656 		eth_ark_rx_dump_queue(dev, i, __func__);
657 
658 	/* Stop the packet checker if it is running */
659 	if (!ark->isvf && ark->start_pg) {
660 		ark_pktchkr_dump_stats(ark->pc);
661 		ark_pktchkr_stop(ark->pc);
662 	}
663 
664 	return 0;
665 }
666 
667 static int
668 eth_ark_dev_close(struct rte_eth_dev *dev)
669 {
670 	struct ark_adapter *ark = dev->data->dev_private;
671 	uint16_t i;
672 
673 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
674 		return 0;
675 
676 	if (ark->user_ext.dev_close)
677 		ark->user_ext.dev_close(dev,
678 		 ark->user_data[dev->data->port_id]);
679 
680 	eth_ark_dev_stop(dev);
681 
682 	/*
683 	 * This should only be called once for the device during shutdown
684 	 */
685 	/* return to power-on state */
686 	if (ark->pd)
687 		ark_pktdir_setup(ark->pd, ARK_PKT_DIR_INIT_VAL);
688 
689 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
690 		eth_ark_tx_queue_release(dev->data->tx_queues[i]);
691 		dev->data->tx_queues[i] = 0;
692 	}
693 
694 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
695 		eth_ark_dev_rx_queue_release(dev->data->rx_queues[i]);
696 		dev->data->rx_queues[i] = 0;
697 	}
698 
699 	return 0;
700 }
701 
702 static int
703 eth_ark_dev_info_get(struct rte_eth_dev *dev,
704 		     struct rte_eth_dev_info *dev_info)
705 {
706 	struct ark_adapter *ark = dev->data->dev_private;
707 	struct ark_mpu_t *tx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_TX_BASE);
708 	struct ark_mpu_t *rx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_RX_BASE);
709 	uint16_t ports = ark->num_ports;
710 
711 	dev_info->max_rx_pktlen = ARK_RX_MAX_PKT_LEN;
712 	dev_info->min_rx_bufsize = ARK_RX_MIN_BUFSIZE;
713 
714 	dev_info->max_rx_queues = ark_api_num_queues_per_port(rx_mpu, ports);
715 	dev_info->max_tx_queues = ark_api_num_queues_per_port(tx_mpu, ports);
716 
717 	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
718 		.nb_max = ARK_RX_MAX_QUEUE,
719 		.nb_min = ARK_RX_MIN_QUEUE,
720 		.nb_align = ARK_RX_MIN_QUEUE}; /* power of 2 */
721 
722 	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
723 		.nb_max = ARK_TX_MAX_QUEUE,
724 		.nb_min = ARK_TX_MIN_QUEUE,
725 		.nb_align = ARK_TX_MIN_QUEUE}; /* power of 2 */
726 
727 	/* ARK PMD supports all line rates, how do we indicate that here ?? */
728 	dev_info->speed_capa = (RTE_ETH_LINK_SPEED_1G |
729 				RTE_ETH_LINK_SPEED_10G |
730 				RTE_ETH_LINK_SPEED_25G |
731 				RTE_ETH_LINK_SPEED_40G |
732 				RTE_ETH_LINK_SPEED_50G |
733 				RTE_ETH_LINK_SPEED_100G);
734 
735 	dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_TIMESTAMP;
736 
737 	return 0;
738 }
739 
740 static int
741 eth_ark_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
742 {
743 	ARK_PMD_LOG(DEBUG, "link status = %d\n",
744 			dev->data->dev_link.link_status);
745 	struct ark_adapter *ark = dev->data->dev_private;
746 
747 	if (ark->user_ext.link_update) {
748 		return ark->user_ext.link_update
749 			(dev, wait_to_complete,
750 			 ark->user_data[dev->data->port_id]);
751 	}
752 	return 0;
753 }
754 
755 static int
756 eth_ark_dev_set_link_up(struct rte_eth_dev *dev)
757 {
758 	dev->data->dev_link.link_status = 1;
759 	struct ark_adapter *ark = dev->data->dev_private;
760 
761 	if (ark->user_ext.dev_set_link_up)
762 		return ark->user_ext.dev_set_link_up(dev,
763 			     ark->user_data[dev->data->port_id]);
764 	return 0;
765 }
766 
767 static int
768 eth_ark_dev_set_link_down(struct rte_eth_dev *dev)
769 {
770 	dev->data->dev_link.link_status = 0;
771 	struct ark_adapter *ark = dev->data->dev_private;
772 
773 	if (ark->user_ext.dev_set_link_down)
774 		return ark->user_ext.dev_set_link_down(dev,
775 		       ark->user_data[dev->data->port_id]);
776 	return 0;
777 }
778 
779 static int
780 eth_ark_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
781 {
782 	uint16_t i;
783 	struct ark_adapter *ark = dev->data->dev_private;
784 
785 	stats->ipackets = 0;
786 	stats->ibytes = 0;
787 	stats->opackets = 0;
788 	stats->obytes = 0;
789 	stats->imissed = 0;
790 	stats->oerrors = 0;
791 
792 	for (i = 0; i < dev->data->nb_tx_queues; i++)
793 		eth_tx_queue_stats_get(dev->data->tx_queues[i], stats);
794 	for (i = 0; i < dev->data->nb_rx_queues; i++)
795 		eth_rx_queue_stats_get(dev->data->rx_queues[i], stats);
796 	if (ark->user_ext.stats_get)
797 		return ark->user_ext.stats_get(dev, stats,
798 			ark->user_data[dev->data->port_id]);
799 	return 0;
800 }
801 
802 static int
803 eth_ark_dev_stats_reset(struct rte_eth_dev *dev)
804 {
805 	uint16_t i;
806 	struct ark_adapter *ark = dev->data->dev_private;
807 
808 	for (i = 0; i < dev->data->nb_tx_queues; i++)
809 		eth_tx_queue_stats_reset(dev->data->tx_queues[i]);
810 	for (i = 0; i < dev->data->nb_rx_queues; i++)
811 		eth_rx_queue_stats_reset(dev->data->rx_queues[i]);
812 	if (ark->user_ext.stats_reset)
813 		ark->user_ext.stats_reset(dev,
814 			  ark->user_data[dev->data->port_id]);
815 
816 	return 0;
817 }
818 
819 static int
820 eth_ark_macaddr_add(struct rte_eth_dev *dev,
821 		    struct rte_ether_addr *mac_addr,
822 		    uint32_t index,
823 		    uint32_t pool)
824 {
825 	struct ark_adapter *ark = dev->data->dev_private;
826 
827 	if (ark->user_ext.mac_addr_add) {
828 		ark->user_ext.mac_addr_add(dev,
829 					   mac_addr,
830 					   index,
831 					   pool,
832 			   ark->user_data[dev->data->port_id]);
833 		return 0;
834 	}
835 	return -ENOTSUP;
836 }
837 
838 static void
839 eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
840 {
841 	struct ark_adapter *ark = dev->data->dev_private;
842 
843 	if (ark->user_ext.mac_addr_remove)
844 		ark->user_ext.mac_addr_remove(dev, index,
845 			      ark->user_data[dev->data->port_id]);
846 }
847 
848 static int
849 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
850 			     struct rte_ether_addr *mac_addr)
851 {
852 	struct ark_adapter *ark = dev->data->dev_private;
853 
854 	if (ark->user_ext.mac_addr_set) {
855 		ark->user_ext.mac_addr_set(dev, mac_addr,
856 			   ark->user_data[dev->data->port_id]);
857 		return 0;
858 	}
859 	return -ENOTSUP;
860 }
861 
862 static int
863 eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t  size)
864 {
865 	struct ark_adapter *ark = dev->data->dev_private;
866 
867 	if (ark->user_ext.set_mtu)
868 		return ark->user_ext.set_mtu(dev, size,
869 			     ark->user_data[dev->data->port_id]);
870 
871 	return -ENOTSUP;
872 }
873 
874 static inline int
875 process_pktdir_arg(const char *key, const char *value,
876 		   void *extra_args)
877 {
878 	ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n",
879 		    key, value);
880 	struct ark_adapter *ark =
881 		(struct ark_adapter *)extra_args;
882 
883 	ark->pkt_dir_v = strtol(value, NULL, 16);
884 	ARK_PMD_LOG(DEBUG, "pkt_dir_v = 0x%x\n", ark->pkt_dir_v);
885 	return 0;
886 }
887 
888 static inline int
889 process_file_args(const char *key, const char *value, void *extra_args)
890 {
891 	ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n",
892 		    key, value);
893 	char *args = (char *)extra_args;
894 
895 	/* Open the configuration file */
896 	FILE *file = fopen(value, "r");
897 	char line[ARK_MAX_ARG_LEN];
898 	int  size = 0;
899 	int first = 1;
900 
901 	if (file == NULL) {
902 		ARK_PMD_LOG(ERR, "Unable to open "
903 			    "config file %s\n", value);
904 		return -1;
905 	}
906 
907 	while (fgets(line, sizeof(line), file)) {
908 		size += strlen(line);
909 		if (size >= ARK_MAX_ARG_LEN) {
910 			ARK_PMD_LOG(ERR, "Unable to parse file %s args, "
911 				    "parameter list is too long\n", value);
912 			fclose(file);
913 			return -1;
914 		}
915 		if (first) {
916 			strncpy(args, line, ARK_MAX_ARG_LEN);
917 			first = 0;
918 		} else {
919 			strncat(args, line, ARK_MAX_ARG_LEN);
920 		}
921 	}
922 	ARK_PMD_LOG(DEBUG, "file = %s\n", args);
923 	fclose(file);
924 	return 0;
925 }
926 
927 static int
928 eth_ark_check_args(struct ark_adapter *ark, const char *params)
929 {
930 	struct rte_kvargs *kvlist;
931 	unsigned int k_idx;
932 	struct rte_kvargs_pair *pair = NULL;
933 	int ret = -1;
934 
935 	kvlist = rte_kvargs_parse(params, valid_arguments);
936 	if (kvlist == NULL)
937 		return 0;
938 
939 	ark->pkt_gen_args[0] = 0;
940 	ark->pkt_chkr_args[0] = 0;
941 
942 	for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
943 		pair = &kvlist->pairs[k_idx];
944 		ARK_PMD_LOG(DEBUG, "**** Arg passed to PMD = %s:%s\n",
945 			     pair->key,
946 			     pair->value);
947 	}
948 
949 	if (rte_kvargs_process(kvlist,
950 			       ARK_PKTDIR_ARG,
951 			       &process_pktdir_arg,
952 			       ark) != 0) {
953 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTDIR_ARG);
954 		goto free_kvlist;
955 	}
956 
957 	if (rte_kvargs_process(kvlist,
958 			       ARK_PKTGEN_ARG,
959 			       &process_file_args,
960 			       ark->pkt_gen_args) != 0) {
961 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTGEN_ARG);
962 		goto free_kvlist;
963 	}
964 
965 	if (rte_kvargs_process(kvlist,
966 			       ARK_PKTCHKR_ARG,
967 			       &process_file_args,
968 			       ark->pkt_chkr_args) != 0) {
969 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTCHKR_ARG);
970 		goto free_kvlist;
971 	}
972 
973 	if (ark->isvf) {
974 		ret = 0;
975 		goto free_kvlist;
976 	}
977 	ARK_PMD_LOG(INFO, "packet director set to 0x%x\n", ark->pkt_dir_v);
978 	/* Setup the packet director */
979 	ark_pktdir_setup(ark->pd, ark->pkt_dir_v);
980 
981 	/* Setup the packet generator */
982 	if (ark->pkt_gen_args[0]) {
983 		ARK_PMD_LOG(DEBUG, "Setting up the packet generator\n");
984 		ark_pktgen_parse(ark->pkt_gen_args);
985 		ark_pktgen_reset(ark->pg);
986 		ark_pktgen_setup(ark->pg);
987 		ark->start_pg = 1;
988 	}
989 
990 	/* Setup the packet checker */
991 	if (ark->pkt_chkr_args[0]) {
992 		ark_pktchkr_parse(ark->pkt_chkr_args);
993 		ark_pktchkr_setup(ark->pc);
994 	}
995 
996 	ret = 0;
997 
998 free_kvlist:
999 	rte_kvargs_free(kvlist);
1000 
1001 	return ret;
1002 }
1003 
1004 RTE_PMD_REGISTER_PCI(net_ark, rte_ark_pmd);
1005 RTE_PMD_REGISTER_KMOD_DEP(net_ark, "* igb_uio | uio_pci_generic ");
1006 RTE_PMD_REGISTER_PCI_TABLE(net_ark, pci_id_ark_map);
1007 RTE_PMD_REGISTER_PARAM_STRING(net_ark,
1008 			      ARK_PKTGEN_ARG "=<filename> "
1009 			      ARK_PKTCHKR_ARG "=<filename> "
1010 			      ARK_PKTDIR_ARG "=<bitmap>");
1011 RTE_LOG_REGISTER_DEFAULT(ark_logtype, NOTICE);
1012