xref: /f-stack/dpdk/drivers/net/ark/ark_ethdev.c (revision 2d9fd380)
1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright (c) 2015-2018 Atomic Rules LLC
32bfe3f2eSlogwang  */
42bfe3f2eSlogwang 
52bfe3f2eSlogwang #include <unistd.h>
62bfe3f2eSlogwang #include <sys/stat.h>
72bfe3f2eSlogwang #include <dlfcn.h>
82bfe3f2eSlogwang 
92bfe3f2eSlogwang #include <rte_bus_pci.h>
102bfe3f2eSlogwang #include <rte_ethdev_pci.h>
112bfe3f2eSlogwang #include <rte_kvargs.h>
122bfe3f2eSlogwang 
13*2d9fd380Sjfb8856606 #include "rte_pmd_ark.h"
142bfe3f2eSlogwang #include "ark_global.h"
152bfe3f2eSlogwang #include "ark_logs.h"
162bfe3f2eSlogwang #include "ark_ethdev_tx.h"
172bfe3f2eSlogwang #include "ark_ethdev_rx.h"
182bfe3f2eSlogwang #include "ark_mpu.h"
192bfe3f2eSlogwang #include "ark_ddm.h"
202bfe3f2eSlogwang #include "ark_udm.h"
212bfe3f2eSlogwang #include "ark_rqp.h"
222bfe3f2eSlogwang #include "ark_pktdir.h"
232bfe3f2eSlogwang #include "ark_pktgen.h"
242bfe3f2eSlogwang #include "ark_pktchkr.h"
252bfe3f2eSlogwang 
262bfe3f2eSlogwang /*  Internal prototypes */
272bfe3f2eSlogwang static int eth_ark_check_args(struct ark_adapter *ark, const char *params);
282bfe3f2eSlogwang static int eth_ark_dev_init(struct rte_eth_dev *dev);
292bfe3f2eSlogwang static int ark_config_device(struct rte_eth_dev *dev);
302bfe3f2eSlogwang static int eth_ark_dev_uninit(struct rte_eth_dev *eth_dev);
312bfe3f2eSlogwang static int eth_ark_dev_configure(struct rte_eth_dev *dev);
322bfe3f2eSlogwang static int eth_ark_dev_start(struct rte_eth_dev *dev);
33*2d9fd380Sjfb8856606 static int eth_ark_dev_stop(struct rte_eth_dev *dev);
34*2d9fd380Sjfb8856606 static int eth_ark_dev_close(struct rte_eth_dev *dev);
354418919fSjohnjiang static int eth_ark_dev_info_get(struct rte_eth_dev *dev,
362bfe3f2eSlogwang 				struct rte_eth_dev_info *dev_info);
372bfe3f2eSlogwang static int eth_ark_dev_link_update(struct rte_eth_dev *dev,
382bfe3f2eSlogwang 				   int wait_to_complete);
392bfe3f2eSlogwang static int eth_ark_dev_set_link_up(struct rte_eth_dev *dev);
402bfe3f2eSlogwang static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
412bfe3f2eSlogwang static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
422bfe3f2eSlogwang 				  struct rte_eth_stats *stats);
434418919fSjohnjiang static int eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
44d30ea906Sjfb8856606 static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
454418919fSjohnjiang 					 struct rte_ether_addr *mac_addr);
462bfe3f2eSlogwang static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
474418919fSjohnjiang 			       struct rte_ether_addr *mac_addr,
482bfe3f2eSlogwang 			       uint32_t index,
492bfe3f2eSlogwang 			       uint32_t pool);
502bfe3f2eSlogwang static void eth_ark_macaddr_remove(struct rte_eth_dev *dev,
512bfe3f2eSlogwang 				   uint32_t index);
522bfe3f2eSlogwang static int  eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size);
532bfe3f2eSlogwang 
542bfe3f2eSlogwang /*
552bfe3f2eSlogwang  * The packet generator is a functional block used to generate packet
562bfe3f2eSlogwang  * patterns for testing.  It is not intended for nominal use.
572bfe3f2eSlogwang  */
582bfe3f2eSlogwang #define ARK_PKTGEN_ARG "Pkt_gen"
592bfe3f2eSlogwang 
602bfe3f2eSlogwang /*
612bfe3f2eSlogwang  * The packet checker is a functional block used to verify packet
622bfe3f2eSlogwang  * patterns for testing.  It is not intended for nominal use.
632bfe3f2eSlogwang  */
642bfe3f2eSlogwang #define ARK_PKTCHKR_ARG "Pkt_chkr"
652bfe3f2eSlogwang 
662bfe3f2eSlogwang /*
672bfe3f2eSlogwang  * The packet director is used to select the internal ingress and
682bfe3f2eSlogwang  * egress packets paths during testing.  It is not intended for
692bfe3f2eSlogwang  * nominal use.
702bfe3f2eSlogwang  */
712bfe3f2eSlogwang #define ARK_PKTDIR_ARG "Pkt_dir"
722bfe3f2eSlogwang 
732bfe3f2eSlogwang /* Devinfo configurations */
742bfe3f2eSlogwang #define ARK_RX_MAX_QUEUE (4096 * 4)
752bfe3f2eSlogwang #define ARK_RX_MIN_QUEUE (512)
762bfe3f2eSlogwang #define ARK_RX_MAX_PKT_LEN ((16 * 1024) - 128)
772bfe3f2eSlogwang #define ARK_RX_MIN_BUFSIZE (1024)
782bfe3f2eSlogwang 
792bfe3f2eSlogwang #define ARK_TX_MAX_QUEUE (4096 * 4)
802bfe3f2eSlogwang #define ARK_TX_MIN_QUEUE (256)
812bfe3f2eSlogwang 
82*2d9fd380Sjfb8856606 uint64_t ark_timestamp_rx_dynflag;
83*2d9fd380Sjfb8856606 int ark_timestamp_dynfield_offset = -1;
84*2d9fd380Sjfb8856606 
85*2d9fd380Sjfb8856606 int rte_pmd_ark_rx_userdata_dynfield_offset = -1;
86*2d9fd380Sjfb8856606 int rte_pmd_ark_tx_userdata_dynfield_offset = -1;
874418919fSjohnjiang 
882bfe3f2eSlogwang static const char * const valid_arguments[] = {
892bfe3f2eSlogwang 	ARK_PKTGEN_ARG,
902bfe3f2eSlogwang 	ARK_PKTCHKR_ARG,
912bfe3f2eSlogwang 	ARK_PKTDIR_ARG,
922bfe3f2eSlogwang 	NULL
932bfe3f2eSlogwang };
942bfe3f2eSlogwang 
952bfe3f2eSlogwang static const struct rte_pci_id pci_id_ark_map[] = {
962bfe3f2eSlogwang 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
972bfe3f2eSlogwang 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
982bfe3f2eSlogwang 	{.vendor_id = 0, /* sentinel */ },
992bfe3f2eSlogwang };
1002bfe3f2eSlogwang 
1012bfe3f2eSlogwang static int
eth_ark_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)1022bfe3f2eSlogwang eth_ark_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1032bfe3f2eSlogwang 		struct rte_pci_device *pci_dev)
1042bfe3f2eSlogwang {
1052bfe3f2eSlogwang 	struct rte_eth_dev *eth_dev;
1062bfe3f2eSlogwang 	int ret;
1072bfe3f2eSlogwang 
1082bfe3f2eSlogwang 	eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct ark_adapter));
1092bfe3f2eSlogwang 
1102bfe3f2eSlogwang 	if (eth_dev == NULL)
1112bfe3f2eSlogwang 		return -ENOMEM;
1122bfe3f2eSlogwang 
1132bfe3f2eSlogwang 	ret = eth_ark_dev_init(eth_dev);
1142bfe3f2eSlogwang 	if (ret)
115*2d9fd380Sjfb8856606 		rte_eth_dev_release_port(eth_dev);
1162bfe3f2eSlogwang 
1172bfe3f2eSlogwang 	return ret;
1182bfe3f2eSlogwang }
1192bfe3f2eSlogwang 
1202bfe3f2eSlogwang static int
eth_ark_pci_remove(struct rte_pci_device * pci_dev)1212bfe3f2eSlogwang eth_ark_pci_remove(struct rte_pci_device *pci_dev)
1222bfe3f2eSlogwang {
1232bfe3f2eSlogwang 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_ark_dev_uninit);
1242bfe3f2eSlogwang }
1252bfe3f2eSlogwang 
1262bfe3f2eSlogwang static struct rte_pci_driver rte_ark_pmd = {
1272bfe3f2eSlogwang 	.id_table = pci_id_ark_map,
1282bfe3f2eSlogwang 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
1292bfe3f2eSlogwang 	.probe = eth_ark_pci_probe,
1302bfe3f2eSlogwang 	.remove = eth_ark_pci_remove,
1312bfe3f2eSlogwang };
1322bfe3f2eSlogwang 
1332bfe3f2eSlogwang static const struct eth_dev_ops ark_eth_dev_ops = {
1342bfe3f2eSlogwang 	.dev_configure = eth_ark_dev_configure,
1352bfe3f2eSlogwang 	.dev_start = eth_ark_dev_start,
1362bfe3f2eSlogwang 	.dev_stop = eth_ark_dev_stop,
1372bfe3f2eSlogwang 	.dev_close = eth_ark_dev_close,
1382bfe3f2eSlogwang 
1392bfe3f2eSlogwang 	.dev_infos_get = eth_ark_dev_info_get,
1402bfe3f2eSlogwang 
1412bfe3f2eSlogwang 	.rx_queue_setup = eth_ark_dev_rx_queue_setup,
1422bfe3f2eSlogwang 	.tx_queue_setup = eth_ark_tx_queue_setup,
1432bfe3f2eSlogwang 
1442bfe3f2eSlogwang 	.link_update = eth_ark_dev_link_update,
1452bfe3f2eSlogwang 	.dev_set_link_up = eth_ark_dev_set_link_up,
1462bfe3f2eSlogwang 	.dev_set_link_down = eth_ark_dev_set_link_down,
1472bfe3f2eSlogwang 
1482bfe3f2eSlogwang 	.rx_queue_start = eth_ark_rx_start_queue,
1492bfe3f2eSlogwang 	.rx_queue_stop = eth_ark_rx_stop_queue,
1502bfe3f2eSlogwang 
1512bfe3f2eSlogwang 	.tx_queue_start = eth_ark_tx_queue_start,
1522bfe3f2eSlogwang 	.tx_queue_stop = eth_ark_tx_queue_stop,
1532bfe3f2eSlogwang 
1542bfe3f2eSlogwang 	.stats_get = eth_ark_dev_stats_get,
1552bfe3f2eSlogwang 	.stats_reset = eth_ark_dev_stats_reset,
1562bfe3f2eSlogwang 
1572bfe3f2eSlogwang 	.mac_addr_add = eth_ark_macaddr_add,
1582bfe3f2eSlogwang 	.mac_addr_remove = eth_ark_macaddr_remove,
1592bfe3f2eSlogwang 	.mac_addr_set = eth_ark_set_default_mac_addr,
1602bfe3f2eSlogwang 
1612bfe3f2eSlogwang 	.mtu_set = eth_ark_set_mtu,
1622bfe3f2eSlogwang };
1632bfe3f2eSlogwang 
1642bfe3f2eSlogwang static int
check_for_ext(struct ark_adapter * ark)1652bfe3f2eSlogwang check_for_ext(struct ark_adapter *ark)
1662bfe3f2eSlogwang {
1672bfe3f2eSlogwang 	int found = 0;
1682bfe3f2eSlogwang 
1692bfe3f2eSlogwang 	/* Get the env */
1702bfe3f2eSlogwang 	const char *dllpath = getenv("ARK_EXT_PATH");
1712bfe3f2eSlogwang 
1722bfe3f2eSlogwang 	if (dllpath == NULL) {
173*2d9fd380Sjfb8856606 		ARK_PMD_LOG(DEBUG, "EXT NO dll path specified\n");
1742bfe3f2eSlogwang 		return 0;
1752bfe3f2eSlogwang 	}
176*2d9fd380Sjfb8856606 	ARK_PMD_LOG(NOTICE, "EXT found dll path at %s\n", dllpath);
1772bfe3f2eSlogwang 
1782bfe3f2eSlogwang 	/* Open and load the .so */
1792bfe3f2eSlogwang 	ark->d_handle = dlopen(dllpath, RTLD_LOCAL | RTLD_LAZY);
1802bfe3f2eSlogwang 	if (ark->d_handle == NULL) {
181*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Could not load user extension %s\n",
1822bfe3f2eSlogwang 			    dllpath);
1832bfe3f2eSlogwang 		return -1;
1842bfe3f2eSlogwang 	}
185*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "SUCCESS: loaded user extension %s\n",
1862bfe3f2eSlogwang 			    dllpath);
1872bfe3f2eSlogwang 
1882bfe3f2eSlogwang 	/* Get the entry points */
1892bfe3f2eSlogwang 	ark->user_ext.dev_init =
1902bfe3f2eSlogwang 		(void *(*)(struct rte_eth_dev *, void *, int))
1912bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_init");
192*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "device ext init pointer = %p\n",
1932bfe3f2eSlogwang 		      ark->user_ext.dev_init);
1942bfe3f2eSlogwang 	ark->user_ext.dev_get_port_count =
1952bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, void *))
1962bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_get_port_count");
1972bfe3f2eSlogwang 	ark->user_ext.dev_uninit =
1982bfe3f2eSlogwang 		(void (*)(struct rte_eth_dev *, void *))
1992bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_uninit");
2002bfe3f2eSlogwang 	ark->user_ext.dev_configure =
2012bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, void *))
2022bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_configure");
2032bfe3f2eSlogwang 	ark->user_ext.dev_start =
2042bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, void *))
2052bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_start");
2062bfe3f2eSlogwang 	ark->user_ext.dev_stop =
2072bfe3f2eSlogwang 		(void (*)(struct rte_eth_dev *, void *))
2082bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_stop");
2092bfe3f2eSlogwang 	ark->user_ext.dev_close =
2102bfe3f2eSlogwang 		(void (*)(struct rte_eth_dev *, void *))
2112bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_close");
2122bfe3f2eSlogwang 	ark->user_ext.link_update =
2132bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, int, void *))
2142bfe3f2eSlogwang 		dlsym(ark->d_handle, "link_update");
2152bfe3f2eSlogwang 	ark->user_ext.dev_set_link_up =
2162bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, void *))
2172bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_set_link_up");
2182bfe3f2eSlogwang 	ark->user_ext.dev_set_link_down =
2192bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, void *))
2202bfe3f2eSlogwang 		dlsym(ark->d_handle, "dev_set_link_down");
2212bfe3f2eSlogwang 	ark->user_ext.stats_get =
2222bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, struct rte_eth_stats *,
2232bfe3f2eSlogwang 			  void *))
2242bfe3f2eSlogwang 		dlsym(ark->d_handle, "stats_get");
2252bfe3f2eSlogwang 	ark->user_ext.stats_reset =
2262bfe3f2eSlogwang 		(void (*)(struct rte_eth_dev *, void *))
2272bfe3f2eSlogwang 		dlsym(ark->d_handle, "stats_reset");
2282bfe3f2eSlogwang 	ark->user_ext.mac_addr_add =
2294418919fSjohnjiang 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
2304418919fSjohnjiang 			uint32_t, uint32_t, void *))
2312bfe3f2eSlogwang 		dlsym(ark->d_handle, "mac_addr_add");
2322bfe3f2eSlogwang 	ark->user_ext.mac_addr_remove =
2332bfe3f2eSlogwang 		(void (*)(struct rte_eth_dev *, uint32_t, void *))
2342bfe3f2eSlogwang 		dlsym(ark->d_handle, "mac_addr_remove");
2352bfe3f2eSlogwang 	ark->user_ext.mac_addr_set =
2364418919fSjohnjiang 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
2372bfe3f2eSlogwang 			  void *))
2382bfe3f2eSlogwang 		dlsym(ark->d_handle, "mac_addr_set");
2392bfe3f2eSlogwang 	ark->user_ext.set_mtu =
2402bfe3f2eSlogwang 		(int (*)(struct rte_eth_dev *, uint16_t,
2412bfe3f2eSlogwang 			  void *))
2422bfe3f2eSlogwang 		dlsym(ark->d_handle, "set_mtu");
2432bfe3f2eSlogwang 
2442bfe3f2eSlogwang 	return found;
2452bfe3f2eSlogwang }
2462bfe3f2eSlogwang 
2472bfe3f2eSlogwang static int
eth_ark_dev_init(struct rte_eth_dev * dev)2482bfe3f2eSlogwang eth_ark_dev_init(struct rte_eth_dev *dev)
2492bfe3f2eSlogwang {
2504b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
2512bfe3f2eSlogwang 	struct rte_pci_device *pci_dev;
2522bfe3f2eSlogwang 	int ret;
2532bfe3f2eSlogwang 	int port_count = 1;
2542bfe3f2eSlogwang 	int p;
255*2d9fd380Sjfb8856606 	static const struct rte_mbuf_dynfield ark_tx_userdata_dynfield_desc = {
256*2d9fd380Sjfb8856606 		.name = RTE_PMD_ARK_TX_USERDATA_DYNFIELD_NAME,
257*2d9fd380Sjfb8856606 		.size = sizeof(rte_pmd_ark_tx_userdata_t),
258*2d9fd380Sjfb8856606 		.align = __alignof__(rte_pmd_ark_tx_userdata_t),
259*2d9fd380Sjfb8856606 	};
260*2d9fd380Sjfb8856606 	static const struct rte_mbuf_dynfield ark_rx_userdata_dynfield_desc = {
261*2d9fd380Sjfb8856606 		.name = RTE_PMD_ARK_RX_USERDATA_DYNFIELD_NAME,
262*2d9fd380Sjfb8856606 		.size = sizeof(rte_pmd_ark_rx_userdata_t),
263*2d9fd380Sjfb8856606 		.align = __alignof__(rte_pmd_ark_rx_userdata_t),
264*2d9fd380Sjfb8856606 	};
2652bfe3f2eSlogwang 
2662bfe3f2eSlogwang 	ark->eth_dev = dev;
2672bfe3f2eSlogwang 
268*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "\n");
2692bfe3f2eSlogwang 
2702bfe3f2eSlogwang 	/* Check to see if there is an extension that we need to load */
2712bfe3f2eSlogwang 	ret = check_for_ext(ark);
2722bfe3f2eSlogwang 	if (ret)
2732bfe3f2eSlogwang 		return ret;
274*2d9fd380Sjfb8856606 
275*2d9fd380Sjfb8856606 	/* Extra mbuf fields for user data */
276*2d9fd380Sjfb8856606 	if (RTE_PMD_ARK_TX_USERDATA_ENABLE) {
277*2d9fd380Sjfb8856606 		rte_pmd_ark_tx_userdata_dynfield_offset =
278*2d9fd380Sjfb8856606 		    rte_mbuf_dynfield_register(&ark_tx_userdata_dynfield_desc);
279*2d9fd380Sjfb8856606 		if (rte_pmd_ark_tx_userdata_dynfield_offset < 0) {
280*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
281*2d9fd380Sjfb8856606 				    "Failed to register mbuf field for tx userdata\n");
282*2d9fd380Sjfb8856606 			return -rte_errno;
283*2d9fd380Sjfb8856606 		}
284*2d9fd380Sjfb8856606 		ARK_PMD_LOG(INFO, "Registered TX-meta dynamic field at %d\n",
285*2d9fd380Sjfb8856606 			    rte_pmd_ark_tx_userdata_dynfield_offset);
286*2d9fd380Sjfb8856606 	}
287*2d9fd380Sjfb8856606 	if (RTE_PMD_ARK_RX_USERDATA_ENABLE) {
288*2d9fd380Sjfb8856606 		rte_pmd_ark_rx_userdata_dynfield_offset =
289*2d9fd380Sjfb8856606 		    rte_mbuf_dynfield_register(&ark_rx_userdata_dynfield_desc);
290*2d9fd380Sjfb8856606 		if (rte_pmd_ark_rx_userdata_dynfield_offset < 0) {
291*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
292*2d9fd380Sjfb8856606 				    "Failed to register mbuf field for rx userdata\n");
293*2d9fd380Sjfb8856606 			return -rte_errno;
294*2d9fd380Sjfb8856606 		}
295*2d9fd380Sjfb8856606 		ARK_PMD_LOG(INFO, "Registered RX-meta dynamic field at %d\n",
296*2d9fd380Sjfb8856606 			    rte_pmd_ark_rx_userdata_dynfield_offset);
297*2d9fd380Sjfb8856606 	}
298*2d9fd380Sjfb8856606 
2992bfe3f2eSlogwang 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
3002bfe3f2eSlogwang 	rte_eth_copy_pci_info(dev, pci_dev);
301*2d9fd380Sjfb8856606 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
3022bfe3f2eSlogwang 
3032bfe3f2eSlogwang 	/* Use dummy function until setup */
3042bfe3f2eSlogwang 	dev->rx_pkt_burst = &eth_ark_recv_pkts_noop;
3052bfe3f2eSlogwang 	dev->tx_pkt_burst = &eth_ark_xmit_pkts_noop;
3062bfe3f2eSlogwang 
3072bfe3f2eSlogwang 	ark->bar0 = (uint8_t *)pci_dev->mem_resource[0].addr;
3082bfe3f2eSlogwang 	ark->a_bar = (uint8_t *)pci_dev->mem_resource[2].addr;
3092bfe3f2eSlogwang 
3102bfe3f2eSlogwang 	ark->sysctrl.v  = (void *)&ark->bar0[ARK_SYSCTRL_BASE];
3112bfe3f2eSlogwang 	ark->mpurx.v  = (void *)&ark->bar0[ARK_MPU_RX_BASE];
3122bfe3f2eSlogwang 	ark->udm.v  = (void *)&ark->bar0[ARK_UDM_BASE];
3132bfe3f2eSlogwang 	ark->mputx.v  = (void *)&ark->bar0[ARK_MPU_TX_BASE];
3142bfe3f2eSlogwang 	ark->ddm.v  = (void *)&ark->bar0[ARK_DDM_BASE];
3152bfe3f2eSlogwang 	ark->cmac.v  = (void *)&ark->bar0[ARK_CMAC_BASE];
3162bfe3f2eSlogwang 	ark->external.v  = (void *)&ark->bar0[ARK_EXTERNAL_BASE];
3172bfe3f2eSlogwang 	ark->pktdir.v  = (void *)&ark->bar0[ARK_PKTDIR_BASE];
3182bfe3f2eSlogwang 	ark->pktgen.v  = (void *)&ark->bar0[ARK_PKTGEN_BASE];
3192bfe3f2eSlogwang 	ark->pktchkr.v  = (void *)&ark->bar0[ARK_PKTCHKR_BASE];
3202bfe3f2eSlogwang 
3212bfe3f2eSlogwang 	ark->rqpacing =
3222bfe3f2eSlogwang 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
3232bfe3f2eSlogwang 	ark->started = 0;
3242bfe3f2eSlogwang 
325*2d9fd380Sjfb8856606 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
3262bfe3f2eSlogwang 		      ark->sysctrl.t32[4],
3272bfe3f2eSlogwang 		      rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4]));
328*2d9fd380Sjfb8856606 	ARK_PMD_LOG(NOTICE, "Arkville HW Commit_ID: %08x\n",
3292bfe3f2eSlogwang 		    rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4]));
3302bfe3f2eSlogwang 
3312bfe3f2eSlogwang 	/* If HW sanity test fails, return an error */
3322bfe3f2eSlogwang 	if (ark->sysctrl.t32[4] != 0xcafef00d) {
333*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR,
3342bfe3f2eSlogwang 			    "HW Sanity test has failed, expected constant"
3352bfe3f2eSlogwang 			    " 0x%x, read 0x%x (%s)\n",
3362bfe3f2eSlogwang 			    0xcafef00d,
3372bfe3f2eSlogwang 			    ark->sysctrl.t32[4], __func__);
3382bfe3f2eSlogwang 		return -1;
3392bfe3f2eSlogwang 	}
3402bfe3f2eSlogwang 	if (ark->sysctrl.t32[3] != 0) {
3412bfe3f2eSlogwang 		if (ark_rqp_lasped(ark->rqpacing)) {
342*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR, "Arkville Evaluation System - "
3432bfe3f2eSlogwang 				    "Timer has Expired\n");
3442bfe3f2eSlogwang 			return -1;
3452bfe3f2eSlogwang 		}
346*2d9fd380Sjfb8856606 		ARK_PMD_LOG(WARNING, "Arkville Evaluation System - "
3472bfe3f2eSlogwang 			    "Timer is Running\n");
3482bfe3f2eSlogwang 	}
3492bfe3f2eSlogwang 
350*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG,
3512bfe3f2eSlogwang 		    "HW Sanity test has PASSED, expected constant"
3522bfe3f2eSlogwang 		    " 0x%x, read 0x%x (%s)\n",
3532bfe3f2eSlogwang 		    0xcafef00d, ark->sysctrl.t32[4], __func__);
3542bfe3f2eSlogwang 
3552bfe3f2eSlogwang 	/* We are a single function multi-port device. */
3562bfe3f2eSlogwang 	ret = ark_config_device(dev);
357d30ea906Sjfb8856606 	if (ret)
358d30ea906Sjfb8856606 		return -1;
359d30ea906Sjfb8856606 
3602bfe3f2eSlogwang 	dev->dev_ops = &ark_eth_dev_ops;
361*2d9fd380Sjfb8856606 	dev->rx_queue_count = eth_ark_dev_rx_queue_count;
3622bfe3f2eSlogwang 
3634418919fSjohnjiang 	dev->data->mac_addrs = rte_zmalloc("ark", RTE_ETHER_ADDR_LEN, 0);
3642bfe3f2eSlogwang 	if (!dev->data->mac_addrs) {
365*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR,
3662bfe3f2eSlogwang 			    "Failed to allocated memory for storing mac address"
3672bfe3f2eSlogwang 			    );
3682bfe3f2eSlogwang 	}
3692bfe3f2eSlogwang 
3702bfe3f2eSlogwang 	if (ark->user_ext.dev_init) {
3712bfe3f2eSlogwang 		ark->user_data[dev->data->port_id] =
3722bfe3f2eSlogwang 			ark->user_ext.dev_init(dev, ark->a_bar, 0);
3732bfe3f2eSlogwang 		if (!ark->user_data[dev->data->port_id]) {
374*2d9fd380Sjfb8856606 			ARK_PMD_LOG(WARNING,
3752bfe3f2eSlogwang 				    "Failed to initialize PMD extension!"
3762bfe3f2eSlogwang 				    " continuing without it\n");
3772bfe3f2eSlogwang 			memset(&ark->user_ext, 0, sizeof(struct ark_user_ext));
3782bfe3f2eSlogwang 			dlclose(ark->d_handle);
3792bfe3f2eSlogwang 		}
3802bfe3f2eSlogwang 	}
3812bfe3f2eSlogwang 
3822bfe3f2eSlogwang 	if (pci_dev->device.devargs)
3832bfe3f2eSlogwang 		ret = eth_ark_check_args(ark, pci_dev->device.devargs->args);
3842bfe3f2eSlogwang 	else
385*2d9fd380Sjfb8856606 		ARK_PMD_LOG(INFO, "No Device args found\n");
3862bfe3f2eSlogwang 
3872bfe3f2eSlogwang 	if (ret)
3882bfe3f2eSlogwang 		goto error;
3892bfe3f2eSlogwang 	/*
3902bfe3f2eSlogwang 	 * We will create additional devices based on the number of requested
3912bfe3f2eSlogwang 	 * ports
3922bfe3f2eSlogwang 	 */
3932bfe3f2eSlogwang 	if (ark->user_ext.dev_get_port_count)
3942bfe3f2eSlogwang 		port_count =
3952bfe3f2eSlogwang 			ark->user_ext.dev_get_port_count(dev,
3962bfe3f2eSlogwang 				 ark->user_data[dev->data->port_id]);
3972bfe3f2eSlogwang 	ark->num_ports = port_count;
3982bfe3f2eSlogwang 
3992bfe3f2eSlogwang 	for (p = 0; p < port_count; p++) {
4002bfe3f2eSlogwang 		struct rte_eth_dev *eth_dev;
4012bfe3f2eSlogwang 		char name[RTE_ETH_NAME_MAX_LEN];
4022bfe3f2eSlogwang 
4032bfe3f2eSlogwang 		snprintf(name, sizeof(name), "arketh%d",
4042bfe3f2eSlogwang 			 dev->data->port_id + p);
4052bfe3f2eSlogwang 
4062bfe3f2eSlogwang 		if (p == 0) {
4072bfe3f2eSlogwang 			/* First port is already allocated by DPDK */
4082bfe3f2eSlogwang 			eth_dev = ark->eth_dev;
409d30ea906Sjfb8856606 			rte_eth_dev_probing_finish(eth_dev);
4102bfe3f2eSlogwang 			continue;
4112bfe3f2eSlogwang 		}
4122bfe3f2eSlogwang 
4132bfe3f2eSlogwang 		/* reserve an ethdev entry */
4142bfe3f2eSlogwang 		eth_dev = rte_eth_dev_allocate(name);
4152bfe3f2eSlogwang 		if (!eth_dev) {
416*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
4172bfe3f2eSlogwang 				    "Could not allocate eth_dev for port %d\n",
4182bfe3f2eSlogwang 				    p);
4192bfe3f2eSlogwang 			goto error;
4202bfe3f2eSlogwang 		}
4212bfe3f2eSlogwang 
4222bfe3f2eSlogwang 		eth_dev->device = &pci_dev->device;
4232bfe3f2eSlogwang 		eth_dev->data->dev_private = ark;
4242bfe3f2eSlogwang 		eth_dev->dev_ops = ark->eth_dev->dev_ops;
4252bfe3f2eSlogwang 		eth_dev->tx_pkt_burst = ark->eth_dev->tx_pkt_burst;
4262bfe3f2eSlogwang 		eth_dev->rx_pkt_burst = ark->eth_dev->rx_pkt_burst;
4272bfe3f2eSlogwang 
4282bfe3f2eSlogwang 		rte_eth_copy_pci_info(eth_dev, pci_dev);
429*2d9fd380Sjfb8856606 		eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
4302bfe3f2eSlogwang 
4314418919fSjohnjiang 		eth_dev->data->mac_addrs = rte_zmalloc(name,
4324418919fSjohnjiang 						RTE_ETHER_ADDR_LEN, 0);
4332bfe3f2eSlogwang 		if (!eth_dev->data->mac_addrs) {
434*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
4352bfe3f2eSlogwang 				    "Memory allocation for MAC failed!"
4362bfe3f2eSlogwang 				    " Exiting.\n");
4372bfe3f2eSlogwang 			goto error;
4382bfe3f2eSlogwang 		}
4392bfe3f2eSlogwang 
4402bfe3f2eSlogwang 		if (ark->user_ext.dev_init) {
4412bfe3f2eSlogwang 			ark->user_data[eth_dev->data->port_id] =
4422bfe3f2eSlogwang 				ark->user_ext.dev_init(dev, ark->a_bar, p);
4432bfe3f2eSlogwang 		}
444d30ea906Sjfb8856606 
445d30ea906Sjfb8856606 		rte_eth_dev_probing_finish(eth_dev);
4462bfe3f2eSlogwang 	}
4472bfe3f2eSlogwang 
4482bfe3f2eSlogwang 	return ret;
4492bfe3f2eSlogwang 
4502bfe3f2eSlogwang error:
4512bfe3f2eSlogwang 	rte_free(dev->data->mac_addrs);
4524b05018fSfengbojiang 	dev->data->mac_addrs = NULL;
4532bfe3f2eSlogwang 	return -1;
4542bfe3f2eSlogwang }
4552bfe3f2eSlogwang 
4562bfe3f2eSlogwang /*
4572bfe3f2eSlogwang  *Initial device configuration when device is opened
4582bfe3f2eSlogwang  * setup the DDM, and UDM
4592bfe3f2eSlogwang  * Called once per PCIE device
4602bfe3f2eSlogwang  */
4612bfe3f2eSlogwang static int
ark_config_device(struct rte_eth_dev * dev)4622bfe3f2eSlogwang ark_config_device(struct rte_eth_dev *dev)
4632bfe3f2eSlogwang {
4644b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
4652bfe3f2eSlogwang 	uint16_t num_q, i;
4662bfe3f2eSlogwang 	struct ark_mpu_t *mpu;
4672bfe3f2eSlogwang 
4682bfe3f2eSlogwang 	/*
4692bfe3f2eSlogwang 	 * Make sure that the packet director, generator and checker are in a
4702bfe3f2eSlogwang 	 * known state
4712bfe3f2eSlogwang 	 */
4722bfe3f2eSlogwang 	ark->start_pg = 0;
4732bfe3f2eSlogwang 	ark->pg = ark_pktgen_init(ark->pktgen.v, 0, 1);
4742bfe3f2eSlogwang 	if (ark->pg == NULL)
4752bfe3f2eSlogwang 		return -1;
4762bfe3f2eSlogwang 	ark_pktgen_reset(ark->pg);
4772bfe3f2eSlogwang 	ark->pc = ark_pktchkr_init(ark->pktchkr.v, 0, 1);
4782bfe3f2eSlogwang 	if (ark->pc == NULL)
4792bfe3f2eSlogwang 		return -1;
4802bfe3f2eSlogwang 	ark_pktchkr_stop(ark->pc);
4812bfe3f2eSlogwang 	ark->pd = ark_pktdir_init(ark->pktdir.v);
4822bfe3f2eSlogwang 	if (ark->pd == NULL)
4832bfe3f2eSlogwang 		return -1;
4842bfe3f2eSlogwang 
4852bfe3f2eSlogwang 	/* Verify HW */
4862bfe3f2eSlogwang 	if (ark_udm_verify(ark->udm.v))
4872bfe3f2eSlogwang 		return -1;
4882bfe3f2eSlogwang 	if (ark_ddm_verify(ark->ddm.v))
4892bfe3f2eSlogwang 		return -1;
4902bfe3f2eSlogwang 
4912bfe3f2eSlogwang 	/* UDM */
4922bfe3f2eSlogwang 	if (ark_udm_reset(ark->udm.v)) {
493*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to stop and reset UDM\n");
4942bfe3f2eSlogwang 		return -1;
4952bfe3f2eSlogwang 	}
4962bfe3f2eSlogwang 	/* Keep in reset until the MPU are cleared */
4972bfe3f2eSlogwang 
4982bfe3f2eSlogwang 	/* MPU reset */
4992bfe3f2eSlogwang 	mpu = ark->mpurx.v;
5002bfe3f2eSlogwang 	num_q = ark_api_num_queues(mpu);
5012bfe3f2eSlogwang 	ark->rx_queues = num_q;
5022bfe3f2eSlogwang 	for (i = 0; i < num_q; i++) {
5032bfe3f2eSlogwang 		ark_mpu_reset(mpu);
5042bfe3f2eSlogwang 		mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
5052bfe3f2eSlogwang 	}
5062bfe3f2eSlogwang 
5072bfe3f2eSlogwang 	ark_udm_stop(ark->udm.v, 0);
5082bfe3f2eSlogwang 	ark_udm_configure(ark->udm.v,
5092bfe3f2eSlogwang 			  RTE_PKTMBUF_HEADROOM,
5102bfe3f2eSlogwang 			  RTE_MBUF_DEFAULT_DATAROOM,
5112bfe3f2eSlogwang 			  ARK_RX_WRITE_TIME_NS);
5122bfe3f2eSlogwang 	ark_udm_stats_reset(ark->udm.v);
5132bfe3f2eSlogwang 	ark_udm_stop(ark->udm.v, 0);
5142bfe3f2eSlogwang 
5152bfe3f2eSlogwang 	/* TX -- DDM */
5162bfe3f2eSlogwang 	if (ark_ddm_stop(ark->ddm.v, 1))
517*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to stop DDM\n");
5182bfe3f2eSlogwang 
5192bfe3f2eSlogwang 	mpu = ark->mputx.v;
5202bfe3f2eSlogwang 	num_q = ark_api_num_queues(mpu);
5212bfe3f2eSlogwang 	ark->tx_queues = num_q;
5222bfe3f2eSlogwang 	for (i = 0; i < num_q; i++) {
5232bfe3f2eSlogwang 		ark_mpu_reset(mpu);
5242bfe3f2eSlogwang 		mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
5252bfe3f2eSlogwang 	}
5262bfe3f2eSlogwang 
5272bfe3f2eSlogwang 	ark_ddm_reset(ark->ddm.v);
5282bfe3f2eSlogwang 	ark_ddm_stats_reset(ark->ddm.v);
5292bfe3f2eSlogwang 
5302bfe3f2eSlogwang 	ark_ddm_stop(ark->ddm.v, 0);
5312bfe3f2eSlogwang 	ark_rqp_stats_reset(ark->rqpacing);
5322bfe3f2eSlogwang 
5332bfe3f2eSlogwang 	return 0;
5342bfe3f2eSlogwang }
5352bfe3f2eSlogwang 
5362bfe3f2eSlogwang static int
eth_ark_dev_uninit(struct rte_eth_dev * dev)5372bfe3f2eSlogwang eth_ark_dev_uninit(struct rte_eth_dev *dev)
5382bfe3f2eSlogwang {
5394b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
5402bfe3f2eSlogwang 
5412bfe3f2eSlogwang 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
5422bfe3f2eSlogwang 		return 0;
5432bfe3f2eSlogwang 
5442bfe3f2eSlogwang 	if (ark->user_ext.dev_uninit)
5452bfe3f2eSlogwang 		ark->user_ext.dev_uninit(dev,
5462bfe3f2eSlogwang 			 ark->user_data[dev->data->port_id]);
5472bfe3f2eSlogwang 
5482bfe3f2eSlogwang 	ark_pktgen_uninit(ark->pg);
5492bfe3f2eSlogwang 	ark_pktchkr_uninit(ark->pc);
5502bfe3f2eSlogwang 
5512bfe3f2eSlogwang 	return 0;
5522bfe3f2eSlogwang }
5532bfe3f2eSlogwang 
5542bfe3f2eSlogwang static int
eth_ark_dev_configure(struct rte_eth_dev * dev)5552bfe3f2eSlogwang eth_ark_dev_configure(struct rte_eth_dev *dev)
5562bfe3f2eSlogwang {
5574b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
558*2d9fd380Sjfb8856606 	int ret;
559*2d9fd380Sjfb8856606 
560*2d9fd380Sjfb8856606 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
561*2d9fd380Sjfb8856606 		ret = rte_mbuf_dyn_rx_timestamp_register(
562*2d9fd380Sjfb8856606 				&ark_timestamp_dynfield_offset,
563*2d9fd380Sjfb8856606 				&ark_timestamp_rx_dynflag);
564*2d9fd380Sjfb8856606 		if (ret != 0) {
565*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
566*2d9fd380Sjfb8856606 				"Failed to register Rx timestamp field/flag\n");
567*2d9fd380Sjfb8856606 			return -rte_errno;
568*2d9fd380Sjfb8856606 		}
569*2d9fd380Sjfb8856606 	}
5702bfe3f2eSlogwang 
5712bfe3f2eSlogwang 	eth_ark_dev_set_link_up(dev);
5722bfe3f2eSlogwang 	if (ark->user_ext.dev_configure)
5732bfe3f2eSlogwang 		return ark->user_ext.dev_configure(dev,
5742bfe3f2eSlogwang 			   ark->user_data[dev->data->port_id]);
5752bfe3f2eSlogwang 	return 0;
5762bfe3f2eSlogwang }
5772bfe3f2eSlogwang 
5782bfe3f2eSlogwang static void *
delay_pg_start(void * arg)5792bfe3f2eSlogwang delay_pg_start(void *arg)
5802bfe3f2eSlogwang {
5812bfe3f2eSlogwang 	struct ark_adapter *ark = (struct ark_adapter *)arg;
5822bfe3f2eSlogwang 
5832bfe3f2eSlogwang 	/* This function is used exclusively for regression testing, We
5842bfe3f2eSlogwang 	 * perform a blind sleep here to ensure that the external test
5852bfe3f2eSlogwang 	 * application has time to setup the test before we generate packets
5862bfe3f2eSlogwang 	 */
5872bfe3f2eSlogwang 	usleep(100000);
5882bfe3f2eSlogwang 	ark_pktgen_run(ark->pg);
5892bfe3f2eSlogwang 	return NULL;
5902bfe3f2eSlogwang }
5912bfe3f2eSlogwang 
5922bfe3f2eSlogwang static int
eth_ark_dev_start(struct rte_eth_dev * dev)5932bfe3f2eSlogwang eth_ark_dev_start(struct rte_eth_dev *dev)
5942bfe3f2eSlogwang {
5954b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
5962bfe3f2eSlogwang 	int i;
5972bfe3f2eSlogwang 
5982bfe3f2eSlogwang 	/* RX Side */
5992bfe3f2eSlogwang 	/* start UDM */
6002bfe3f2eSlogwang 	ark_udm_start(ark->udm.v);
6012bfe3f2eSlogwang 
6022bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_rx_queues; i++)
6032bfe3f2eSlogwang 		eth_ark_rx_start_queue(dev, i);
6042bfe3f2eSlogwang 
6052bfe3f2eSlogwang 	/* TX Side */
6062bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_tx_queues; i++)
6072bfe3f2eSlogwang 		eth_ark_tx_queue_start(dev, i);
6082bfe3f2eSlogwang 
6092bfe3f2eSlogwang 	/* start DDM */
6102bfe3f2eSlogwang 	ark_ddm_start(ark->ddm.v);
6112bfe3f2eSlogwang 
6122bfe3f2eSlogwang 	ark->started = 1;
6132bfe3f2eSlogwang 	/* set xmit and receive function */
6142bfe3f2eSlogwang 	dev->rx_pkt_burst = &eth_ark_recv_pkts;
6152bfe3f2eSlogwang 	dev->tx_pkt_burst = &eth_ark_xmit_pkts;
6162bfe3f2eSlogwang 
6172bfe3f2eSlogwang 	if (ark->start_pg)
6182bfe3f2eSlogwang 		ark_pktchkr_run(ark->pc);
6192bfe3f2eSlogwang 
6202bfe3f2eSlogwang 	if (ark->start_pg && (dev->data->port_id == 0)) {
6212bfe3f2eSlogwang 		pthread_t thread;
6222bfe3f2eSlogwang 
6232bfe3f2eSlogwang 		/* Delay packet generatpr start allow the hardware to be ready
6242bfe3f2eSlogwang 		 * This is only used for sanity checking with internal generator
6252bfe3f2eSlogwang 		 */
6262bfe3f2eSlogwang 		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
627*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR, "Could not create pktgen "
6282bfe3f2eSlogwang 				    "starter thread\n");
6292bfe3f2eSlogwang 			return -1;
6302bfe3f2eSlogwang 		}
6312bfe3f2eSlogwang 	}
6322bfe3f2eSlogwang 
6332bfe3f2eSlogwang 	if (ark->user_ext.dev_start)
6342bfe3f2eSlogwang 		ark->user_ext.dev_start(dev,
6352bfe3f2eSlogwang 			ark->user_data[dev->data->port_id]);
6362bfe3f2eSlogwang 
6372bfe3f2eSlogwang 	return 0;
6382bfe3f2eSlogwang }
6392bfe3f2eSlogwang 
640*2d9fd380Sjfb8856606 static int
eth_ark_dev_stop(struct rte_eth_dev * dev)6412bfe3f2eSlogwang eth_ark_dev_stop(struct rte_eth_dev *dev)
6422bfe3f2eSlogwang {
6432bfe3f2eSlogwang 	uint16_t i;
6442bfe3f2eSlogwang 	int status;
6454b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
6462bfe3f2eSlogwang 	struct ark_mpu_t *mpu;
6472bfe3f2eSlogwang 
6482bfe3f2eSlogwang 	if (ark->started == 0)
649*2d9fd380Sjfb8856606 		return 0;
6502bfe3f2eSlogwang 	ark->started = 0;
651*2d9fd380Sjfb8856606 	dev->data->dev_started = 0;
6522bfe3f2eSlogwang 
6532bfe3f2eSlogwang 	/* Stop the extension first */
6542bfe3f2eSlogwang 	if (ark->user_ext.dev_stop)
6552bfe3f2eSlogwang 		ark->user_ext.dev_stop(dev,
6562bfe3f2eSlogwang 		       ark->user_data[dev->data->port_id]);
6572bfe3f2eSlogwang 
6582bfe3f2eSlogwang 	/* Stop the packet generator */
6592bfe3f2eSlogwang 	if (ark->start_pg)
6602bfe3f2eSlogwang 		ark_pktgen_pause(ark->pg);
6612bfe3f2eSlogwang 
6622bfe3f2eSlogwang 	dev->rx_pkt_burst = &eth_ark_recv_pkts_noop;
6632bfe3f2eSlogwang 	dev->tx_pkt_burst = &eth_ark_xmit_pkts_noop;
6642bfe3f2eSlogwang 
6652bfe3f2eSlogwang 	/* STOP TX Side */
6662bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
6672bfe3f2eSlogwang 		status = eth_ark_tx_queue_stop(dev, i);
6682bfe3f2eSlogwang 		if (status != 0) {
6692bfe3f2eSlogwang 			uint16_t port = dev->data->port_id;
670*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR,
6712bfe3f2eSlogwang 				    "tx_queue stop anomaly"
6722bfe3f2eSlogwang 				    " port %u, queue %u\n",
6732bfe3f2eSlogwang 				    port, i);
6742bfe3f2eSlogwang 		}
6752bfe3f2eSlogwang 	}
6762bfe3f2eSlogwang 
6772bfe3f2eSlogwang 	/* Stop DDM */
6782bfe3f2eSlogwang 	/* Wait up to 0.1 second.  each stop is up to 1000 * 10 useconds */
6792bfe3f2eSlogwang 	for (i = 0; i < 10; i++) {
6802bfe3f2eSlogwang 		status = ark_ddm_stop(ark->ddm.v, 1);
6812bfe3f2eSlogwang 		if (status == 0)
6822bfe3f2eSlogwang 			break;
6832bfe3f2eSlogwang 	}
6842bfe3f2eSlogwang 	if (status || i != 0) {
685*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "DDM stop anomaly. status:"
6862bfe3f2eSlogwang 			    " %d iter: %u. (%s)\n",
6872bfe3f2eSlogwang 			    status,
6882bfe3f2eSlogwang 			    i,
6892bfe3f2eSlogwang 			    __func__);
6902bfe3f2eSlogwang 		ark_ddm_dump(ark->ddm.v, "Stop anomaly");
6912bfe3f2eSlogwang 
6922bfe3f2eSlogwang 		mpu = ark->mputx.v;
6932bfe3f2eSlogwang 		for (i = 0; i < ark->tx_queues; i++) {
6942bfe3f2eSlogwang 			ark_mpu_dump(mpu, "DDM failure dump", i);
6952bfe3f2eSlogwang 			mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
6962bfe3f2eSlogwang 		}
6972bfe3f2eSlogwang 	}
6982bfe3f2eSlogwang 
6992bfe3f2eSlogwang 	/* STOP RX Side */
7002bfe3f2eSlogwang 	/* Stop UDM  multiple tries attempted */
7012bfe3f2eSlogwang 	for (i = 0; i < 10; i++) {
7022bfe3f2eSlogwang 		status = ark_udm_stop(ark->udm.v, 1);
7032bfe3f2eSlogwang 		if (status == 0)
7042bfe3f2eSlogwang 			break;
7052bfe3f2eSlogwang 	}
7062bfe3f2eSlogwang 	if (status || i != 0) {
707*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "UDM stop anomaly. status %d iter: %u. (%s)\n",
7082bfe3f2eSlogwang 			    status, i, __func__);
7092bfe3f2eSlogwang 		ark_udm_dump(ark->udm.v, "Stop anomaly");
7102bfe3f2eSlogwang 
7112bfe3f2eSlogwang 		mpu = ark->mpurx.v;
7122bfe3f2eSlogwang 		for (i = 0; i < ark->rx_queues; i++) {
7132bfe3f2eSlogwang 			ark_mpu_dump(mpu, "UDM Stop anomaly", i);
7142bfe3f2eSlogwang 			mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET);
7152bfe3f2eSlogwang 		}
7162bfe3f2eSlogwang 	}
7172bfe3f2eSlogwang 
7182bfe3f2eSlogwang 	ark_udm_dump_stats(ark->udm.v, "Post stop");
7192bfe3f2eSlogwang 	ark_udm_dump_perf(ark->udm.v, "Post stop");
7202bfe3f2eSlogwang 
7212bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_rx_queues; i++)
7222bfe3f2eSlogwang 		eth_ark_rx_dump_queue(dev, i, __func__);
7232bfe3f2eSlogwang 
7242bfe3f2eSlogwang 	/* Stop the packet checker if it is running */
7252bfe3f2eSlogwang 	if (ark->start_pg) {
7262bfe3f2eSlogwang 		ark_pktchkr_dump_stats(ark->pc);
7272bfe3f2eSlogwang 		ark_pktchkr_stop(ark->pc);
7282bfe3f2eSlogwang 	}
729*2d9fd380Sjfb8856606 
730*2d9fd380Sjfb8856606 	return 0;
7312bfe3f2eSlogwang }
7322bfe3f2eSlogwang 
733*2d9fd380Sjfb8856606 static int
eth_ark_dev_close(struct rte_eth_dev * dev)7342bfe3f2eSlogwang eth_ark_dev_close(struct rte_eth_dev *dev)
7352bfe3f2eSlogwang {
7364b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
7372bfe3f2eSlogwang 	uint16_t i;
7382bfe3f2eSlogwang 
739*2d9fd380Sjfb8856606 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
740*2d9fd380Sjfb8856606 		return 0;
741*2d9fd380Sjfb8856606 
7422bfe3f2eSlogwang 	if (ark->user_ext.dev_close)
7432bfe3f2eSlogwang 		ark->user_ext.dev_close(dev,
7442bfe3f2eSlogwang 		 ark->user_data[dev->data->port_id]);
7452bfe3f2eSlogwang 
7462bfe3f2eSlogwang 	eth_ark_dev_stop(dev);
7472bfe3f2eSlogwang 	eth_ark_udm_force_close(dev);
7482bfe3f2eSlogwang 
7492bfe3f2eSlogwang 	/*
7502bfe3f2eSlogwang 	 * TODO This should only be called once for the device during shutdown
7512bfe3f2eSlogwang 	 */
7522bfe3f2eSlogwang 	ark_rqp_dump(ark->rqpacing);
7532bfe3f2eSlogwang 
7542bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
7552bfe3f2eSlogwang 		eth_ark_tx_queue_release(dev->data->tx_queues[i]);
7562bfe3f2eSlogwang 		dev->data->tx_queues[i] = 0;
7572bfe3f2eSlogwang 	}
7582bfe3f2eSlogwang 
7592bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
7602bfe3f2eSlogwang 		eth_ark_dev_rx_queue_release(dev->data->rx_queues[i]);
7612bfe3f2eSlogwang 		dev->data->rx_queues[i] = 0;
7622bfe3f2eSlogwang 	}
7634418919fSjohnjiang 
764*2d9fd380Sjfb8856606 	return 0;
7652bfe3f2eSlogwang }
7662bfe3f2eSlogwang 
7674418919fSjohnjiang static int
eth_ark_dev_info_get(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)7682bfe3f2eSlogwang eth_ark_dev_info_get(struct rte_eth_dev *dev,
7692bfe3f2eSlogwang 		     struct rte_eth_dev_info *dev_info)
7702bfe3f2eSlogwang {
7714b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
7722bfe3f2eSlogwang 	struct ark_mpu_t *tx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_TX_BASE);
7732bfe3f2eSlogwang 	struct ark_mpu_t *rx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_RX_BASE);
7742bfe3f2eSlogwang 	uint16_t ports = ark->num_ports;
7752bfe3f2eSlogwang 
7762bfe3f2eSlogwang 	dev_info->max_rx_pktlen = ARK_RX_MAX_PKT_LEN;
7772bfe3f2eSlogwang 	dev_info->min_rx_bufsize = ARK_RX_MIN_BUFSIZE;
7782bfe3f2eSlogwang 
7792bfe3f2eSlogwang 	dev_info->max_rx_queues = ark_api_num_queues_per_port(rx_mpu, ports);
7802bfe3f2eSlogwang 	dev_info->max_tx_queues = ark_api_num_queues_per_port(tx_mpu, ports);
7812bfe3f2eSlogwang 
7822bfe3f2eSlogwang 	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
7832bfe3f2eSlogwang 		.nb_max = ARK_RX_MAX_QUEUE,
7842bfe3f2eSlogwang 		.nb_min = ARK_RX_MIN_QUEUE,
7852bfe3f2eSlogwang 		.nb_align = ARK_RX_MIN_QUEUE}; /* power of 2 */
7862bfe3f2eSlogwang 
7872bfe3f2eSlogwang 	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
7882bfe3f2eSlogwang 		.nb_max = ARK_TX_MAX_QUEUE,
7892bfe3f2eSlogwang 		.nb_min = ARK_TX_MIN_QUEUE,
7902bfe3f2eSlogwang 		.nb_align = ARK_TX_MIN_QUEUE}; /* power of 2 */
7912bfe3f2eSlogwang 
7922bfe3f2eSlogwang 	/* ARK PMD supports all line rates, how do we indicate that here ?? */
7932bfe3f2eSlogwang 	dev_info->speed_capa = (ETH_LINK_SPEED_1G |
7942bfe3f2eSlogwang 				ETH_LINK_SPEED_10G |
7952bfe3f2eSlogwang 				ETH_LINK_SPEED_25G |
7962bfe3f2eSlogwang 				ETH_LINK_SPEED_40G |
7972bfe3f2eSlogwang 				ETH_LINK_SPEED_50G |
7982bfe3f2eSlogwang 				ETH_LINK_SPEED_100G);
7994418919fSjohnjiang 
800*2d9fd380Sjfb8856606 	dev_info->rx_offload_capa = DEV_RX_OFFLOAD_TIMESTAMP;
801*2d9fd380Sjfb8856606 
8024418919fSjohnjiang 	return 0;
8032bfe3f2eSlogwang }
8042bfe3f2eSlogwang 
8052bfe3f2eSlogwang static int
eth_ark_dev_link_update(struct rte_eth_dev * dev,int wait_to_complete)8062bfe3f2eSlogwang eth_ark_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
8072bfe3f2eSlogwang {
808*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "link status = %d\n",
8092bfe3f2eSlogwang 			dev->data->dev_link.link_status);
8104b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8112bfe3f2eSlogwang 
8122bfe3f2eSlogwang 	if (ark->user_ext.link_update) {
8132bfe3f2eSlogwang 		return ark->user_ext.link_update
8142bfe3f2eSlogwang 			(dev, wait_to_complete,
8152bfe3f2eSlogwang 			 ark->user_data[dev->data->port_id]);
8162bfe3f2eSlogwang 	}
8172bfe3f2eSlogwang 	return 0;
8182bfe3f2eSlogwang }
8192bfe3f2eSlogwang 
8202bfe3f2eSlogwang static int
eth_ark_dev_set_link_up(struct rte_eth_dev * dev)8212bfe3f2eSlogwang eth_ark_dev_set_link_up(struct rte_eth_dev *dev)
8222bfe3f2eSlogwang {
8232bfe3f2eSlogwang 	dev->data->dev_link.link_status = 1;
8244b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8252bfe3f2eSlogwang 
8262bfe3f2eSlogwang 	if (ark->user_ext.dev_set_link_up)
8272bfe3f2eSlogwang 		return ark->user_ext.dev_set_link_up(dev,
8282bfe3f2eSlogwang 			     ark->user_data[dev->data->port_id]);
8292bfe3f2eSlogwang 	return 0;
8302bfe3f2eSlogwang }
8312bfe3f2eSlogwang 
8322bfe3f2eSlogwang static int
eth_ark_dev_set_link_down(struct rte_eth_dev * dev)8332bfe3f2eSlogwang eth_ark_dev_set_link_down(struct rte_eth_dev *dev)
8342bfe3f2eSlogwang {
8352bfe3f2eSlogwang 	dev->data->dev_link.link_status = 0;
8364b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8372bfe3f2eSlogwang 
8382bfe3f2eSlogwang 	if (ark->user_ext.dev_set_link_down)
8392bfe3f2eSlogwang 		return ark->user_ext.dev_set_link_down(dev,
8402bfe3f2eSlogwang 		       ark->user_data[dev->data->port_id]);
8412bfe3f2eSlogwang 	return 0;
8422bfe3f2eSlogwang }
8432bfe3f2eSlogwang 
8442bfe3f2eSlogwang static int
eth_ark_dev_stats_get(struct rte_eth_dev * dev,struct rte_eth_stats * stats)8452bfe3f2eSlogwang eth_ark_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
8462bfe3f2eSlogwang {
8472bfe3f2eSlogwang 	uint16_t i;
8484b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8492bfe3f2eSlogwang 
8502bfe3f2eSlogwang 	stats->ipackets = 0;
8512bfe3f2eSlogwang 	stats->ibytes = 0;
8522bfe3f2eSlogwang 	stats->opackets = 0;
8532bfe3f2eSlogwang 	stats->obytes = 0;
8542bfe3f2eSlogwang 	stats->imissed = 0;
8552bfe3f2eSlogwang 	stats->oerrors = 0;
8562bfe3f2eSlogwang 
8572bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_tx_queues; i++)
8582bfe3f2eSlogwang 		eth_tx_queue_stats_get(dev->data->tx_queues[i], stats);
8592bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_rx_queues; i++)
8602bfe3f2eSlogwang 		eth_rx_queue_stats_get(dev->data->rx_queues[i], stats);
8612bfe3f2eSlogwang 	if (ark->user_ext.stats_get)
8622bfe3f2eSlogwang 		return ark->user_ext.stats_get(dev, stats,
8632bfe3f2eSlogwang 			ark->user_data[dev->data->port_id]);
8642bfe3f2eSlogwang 	return 0;
8652bfe3f2eSlogwang }
8662bfe3f2eSlogwang 
8674418919fSjohnjiang static int
eth_ark_dev_stats_reset(struct rte_eth_dev * dev)8682bfe3f2eSlogwang eth_ark_dev_stats_reset(struct rte_eth_dev *dev)
8692bfe3f2eSlogwang {
8702bfe3f2eSlogwang 	uint16_t i;
8714b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8722bfe3f2eSlogwang 
8732bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_tx_queues; i++)
8742bfe3f2eSlogwang 		eth_tx_queue_stats_reset(dev->data->tx_queues[i]);
8752bfe3f2eSlogwang 	for (i = 0; i < dev->data->nb_rx_queues; i++)
8762bfe3f2eSlogwang 		eth_rx_queue_stats_reset(dev->data->rx_queues[i]);
8772bfe3f2eSlogwang 	if (ark->user_ext.stats_reset)
8782bfe3f2eSlogwang 		ark->user_ext.stats_reset(dev,
8792bfe3f2eSlogwang 			  ark->user_data[dev->data->port_id]);
8804418919fSjohnjiang 
8814418919fSjohnjiang 	return 0;
8822bfe3f2eSlogwang }
8832bfe3f2eSlogwang 
8842bfe3f2eSlogwang static int
eth_ark_macaddr_add(struct rte_eth_dev * dev,struct rte_ether_addr * mac_addr,uint32_t index,uint32_t pool)8852bfe3f2eSlogwang eth_ark_macaddr_add(struct rte_eth_dev *dev,
8864418919fSjohnjiang 		    struct rte_ether_addr *mac_addr,
8872bfe3f2eSlogwang 		    uint32_t index,
8882bfe3f2eSlogwang 		    uint32_t pool)
8892bfe3f2eSlogwang {
8904b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
8912bfe3f2eSlogwang 
8922bfe3f2eSlogwang 	if (ark->user_ext.mac_addr_add) {
8932bfe3f2eSlogwang 		ark->user_ext.mac_addr_add(dev,
8942bfe3f2eSlogwang 					   mac_addr,
8952bfe3f2eSlogwang 					   index,
8962bfe3f2eSlogwang 					   pool,
8972bfe3f2eSlogwang 			   ark->user_data[dev->data->port_id]);
8982bfe3f2eSlogwang 		return 0;
8992bfe3f2eSlogwang 	}
9002bfe3f2eSlogwang 	return -ENOTSUP;
9012bfe3f2eSlogwang }
9022bfe3f2eSlogwang 
9032bfe3f2eSlogwang static void
eth_ark_macaddr_remove(struct rte_eth_dev * dev,uint32_t index)9042bfe3f2eSlogwang eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
9052bfe3f2eSlogwang {
9064b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
9072bfe3f2eSlogwang 
9082bfe3f2eSlogwang 	if (ark->user_ext.mac_addr_remove)
9092bfe3f2eSlogwang 		ark->user_ext.mac_addr_remove(dev, index,
9102bfe3f2eSlogwang 			      ark->user_data[dev->data->port_id]);
9112bfe3f2eSlogwang }
9122bfe3f2eSlogwang 
913d30ea906Sjfb8856606 static int
eth_ark_set_default_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * mac_addr)9142bfe3f2eSlogwang eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
9154418919fSjohnjiang 			     struct rte_ether_addr *mac_addr)
9162bfe3f2eSlogwang {
9174b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
9182bfe3f2eSlogwang 
919d30ea906Sjfb8856606 	if (ark->user_ext.mac_addr_set) {
9202bfe3f2eSlogwang 		ark->user_ext.mac_addr_set(dev, mac_addr,
9212bfe3f2eSlogwang 			   ark->user_data[dev->data->port_id]);
922d30ea906Sjfb8856606 		return 0;
923d30ea906Sjfb8856606 	}
924d30ea906Sjfb8856606 	return -ENOTSUP;
9252bfe3f2eSlogwang }
9262bfe3f2eSlogwang 
9272bfe3f2eSlogwang static int
eth_ark_set_mtu(struct rte_eth_dev * dev,uint16_t size)9282bfe3f2eSlogwang eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t  size)
9292bfe3f2eSlogwang {
9304b05018fSfengbojiang 	struct ark_adapter *ark = dev->data->dev_private;
9312bfe3f2eSlogwang 
9322bfe3f2eSlogwang 	if (ark->user_ext.set_mtu)
9332bfe3f2eSlogwang 		return ark->user_ext.set_mtu(dev, size,
9342bfe3f2eSlogwang 			     ark->user_data[dev->data->port_id]);
9352bfe3f2eSlogwang 
9362bfe3f2eSlogwang 	return -ENOTSUP;
9372bfe3f2eSlogwang }
9382bfe3f2eSlogwang 
9392bfe3f2eSlogwang static inline int
process_pktdir_arg(const char * key,const char * value,void * extra_args)9402bfe3f2eSlogwang process_pktdir_arg(const char *key, const char *value,
9412bfe3f2eSlogwang 		   void *extra_args)
9422bfe3f2eSlogwang {
943*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n",
9442bfe3f2eSlogwang 		    key, value);
9452bfe3f2eSlogwang 	struct ark_adapter *ark =
9462bfe3f2eSlogwang 		(struct ark_adapter *)extra_args;
9472bfe3f2eSlogwang 
9482bfe3f2eSlogwang 	ark->pkt_dir_v = strtol(value, NULL, 16);
949*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "pkt_dir_v = 0x%x\n", ark->pkt_dir_v);
9502bfe3f2eSlogwang 	return 0;
9512bfe3f2eSlogwang }
9522bfe3f2eSlogwang 
9532bfe3f2eSlogwang static inline int
process_file_args(const char * key,const char * value,void * extra_args)9542bfe3f2eSlogwang process_file_args(const char *key, const char *value, void *extra_args)
9552bfe3f2eSlogwang {
956*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n",
9572bfe3f2eSlogwang 		    key, value);
9582bfe3f2eSlogwang 	char *args = (char *)extra_args;
9592bfe3f2eSlogwang 
9602bfe3f2eSlogwang 	/* Open the configuration file */
9612bfe3f2eSlogwang 	FILE *file = fopen(value, "r");
9622bfe3f2eSlogwang 	char line[ARK_MAX_ARG_LEN];
9632bfe3f2eSlogwang 	int  size = 0;
9642bfe3f2eSlogwang 	int first = 1;
9652bfe3f2eSlogwang 
9662bfe3f2eSlogwang 	if (file == NULL) {
967*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to open "
9682bfe3f2eSlogwang 			    "config file %s\n", value);
9692bfe3f2eSlogwang 		return -1;
9702bfe3f2eSlogwang 	}
9712bfe3f2eSlogwang 
9722bfe3f2eSlogwang 	while (fgets(line, sizeof(line), file)) {
9732bfe3f2eSlogwang 		size += strlen(line);
9742bfe3f2eSlogwang 		if (size >= ARK_MAX_ARG_LEN) {
975*2d9fd380Sjfb8856606 			ARK_PMD_LOG(ERR, "Unable to parse file %s args, "
9762bfe3f2eSlogwang 				    "parameter list is too long\n", value);
9772bfe3f2eSlogwang 			fclose(file);
9782bfe3f2eSlogwang 			return -1;
9792bfe3f2eSlogwang 		}
9802bfe3f2eSlogwang 		if (first) {
9812bfe3f2eSlogwang 			strncpy(args, line, ARK_MAX_ARG_LEN);
9822bfe3f2eSlogwang 			first = 0;
9832bfe3f2eSlogwang 		} else {
9842bfe3f2eSlogwang 			strncat(args, line, ARK_MAX_ARG_LEN);
9852bfe3f2eSlogwang 		}
9862bfe3f2eSlogwang 	}
987*2d9fd380Sjfb8856606 	ARK_PMD_LOG(DEBUG, "file = %s\n", args);
9882bfe3f2eSlogwang 	fclose(file);
9892bfe3f2eSlogwang 	return 0;
9902bfe3f2eSlogwang }
9912bfe3f2eSlogwang 
9922bfe3f2eSlogwang static int
eth_ark_check_args(struct ark_adapter * ark,const char * params)9932bfe3f2eSlogwang eth_ark_check_args(struct ark_adapter *ark, const char *params)
9942bfe3f2eSlogwang {
9952bfe3f2eSlogwang 	struct rte_kvargs *kvlist;
9962bfe3f2eSlogwang 	unsigned int k_idx;
9972bfe3f2eSlogwang 	struct rte_kvargs_pair *pair = NULL;
9982bfe3f2eSlogwang 	int ret = -1;
9992bfe3f2eSlogwang 
10002bfe3f2eSlogwang 	kvlist = rte_kvargs_parse(params, valid_arguments);
10012bfe3f2eSlogwang 	if (kvlist == NULL)
10022bfe3f2eSlogwang 		return 0;
10032bfe3f2eSlogwang 
10042bfe3f2eSlogwang 	ark->pkt_gen_args[0] = 0;
10052bfe3f2eSlogwang 	ark->pkt_chkr_args[0] = 0;
10062bfe3f2eSlogwang 
10072bfe3f2eSlogwang 	for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
10082bfe3f2eSlogwang 		pair = &kvlist->pairs[k_idx];
1009*2d9fd380Sjfb8856606 		ARK_PMD_LOG(DEBUG, "**** Arg passed to PMD = %s:%s\n",
10102bfe3f2eSlogwang 			     pair->key,
10112bfe3f2eSlogwang 			     pair->value);
10122bfe3f2eSlogwang 	}
10132bfe3f2eSlogwang 
10142bfe3f2eSlogwang 	if (rte_kvargs_process(kvlist,
10152bfe3f2eSlogwang 			       ARK_PKTDIR_ARG,
10162bfe3f2eSlogwang 			       &process_pktdir_arg,
10172bfe3f2eSlogwang 			       ark) != 0) {
1018*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTDIR_ARG);
10192bfe3f2eSlogwang 		goto free_kvlist;
10202bfe3f2eSlogwang 	}
10212bfe3f2eSlogwang 
10222bfe3f2eSlogwang 	if (rte_kvargs_process(kvlist,
10232bfe3f2eSlogwang 			       ARK_PKTGEN_ARG,
10242bfe3f2eSlogwang 			       &process_file_args,
10252bfe3f2eSlogwang 			       ark->pkt_gen_args) != 0) {
1026*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTGEN_ARG);
10272bfe3f2eSlogwang 		goto free_kvlist;
10282bfe3f2eSlogwang 	}
10292bfe3f2eSlogwang 
10302bfe3f2eSlogwang 	if (rte_kvargs_process(kvlist,
10312bfe3f2eSlogwang 			       ARK_PKTCHKR_ARG,
10322bfe3f2eSlogwang 			       &process_file_args,
10332bfe3f2eSlogwang 			       ark->pkt_chkr_args) != 0) {
1034*2d9fd380Sjfb8856606 		ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTCHKR_ARG);
10352bfe3f2eSlogwang 		goto free_kvlist;
10362bfe3f2eSlogwang 	}
10372bfe3f2eSlogwang 
1038*2d9fd380Sjfb8856606 	ARK_PMD_LOG(INFO, "packet director set to 0x%x\n", ark->pkt_dir_v);
10392bfe3f2eSlogwang 	/* Setup the packet director */
10402bfe3f2eSlogwang 	ark_pktdir_setup(ark->pd, ark->pkt_dir_v);
10412bfe3f2eSlogwang 
10422bfe3f2eSlogwang 	/* Setup the packet generator */
10432bfe3f2eSlogwang 	if (ark->pkt_gen_args[0]) {
1044*2d9fd380Sjfb8856606 		ARK_PMD_LOG(DEBUG, "Setting up the packet generator\n");
10452bfe3f2eSlogwang 		ark_pktgen_parse(ark->pkt_gen_args);
10462bfe3f2eSlogwang 		ark_pktgen_reset(ark->pg);
10472bfe3f2eSlogwang 		ark_pktgen_setup(ark->pg);
10482bfe3f2eSlogwang 		ark->start_pg = 1;
10492bfe3f2eSlogwang 	}
10502bfe3f2eSlogwang 
10512bfe3f2eSlogwang 	/* Setup the packet checker */
10522bfe3f2eSlogwang 	if (ark->pkt_chkr_args[0]) {
10532bfe3f2eSlogwang 		ark_pktchkr_parse(ark->pkt_chkr_args);
10542bfe3f2eSlogwang 		ark_pktchkr_setup(ark->pc);
10552bfe3f2eSlogwang 	}
10562bfe3f2eSlogwang 
10572bfe3f2eSlogwang 	ret = 0;
10582bfe3f2eSlogwang 
10592bfe3f2eSlogwang free_kvlist:
10602bfe3f2eSlogwang 	rte_kvargs_free(kvlist);
10612bfe3f2eSlogwang 
10622bfe3f2eSlogwang 	return ret;
10632bfe3f2eSlogwang }
10642bfe3f2eSlogwang 
10652bfe3f2eSlogwang RTE_PMD_REGISTER_PCI(net_ark, rte_ark_pmd);
10662bfe3f2eSlogwang RTE_PMD_REGISTER_KMOD_DEP(net_ark, "* igb_uio | uio_pci_generic ");
10672bfe3f2eSlogwang RTE_PMD_REGISTER_PCI_TABLE(net_ark, pci_id_ark_map);
10682bfe3f2eSlogwang RTE_PMD_REGISTER_PARAM_STRING(net_ark,
10692bfe3f2eSlogwang 			      ARK_PKTGEN_ARG "=<filename> "
10702bfe3f2eSlogwang 			      ARK_PKTCHKR_ARG "=<filename> "
10712bfe3f2eSlogwang 			      ARK_PKTDIR_ARG "=<bitmap>");
1072*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(ark_logtype, pmd.net.ark, NOTICE);
1073