xref: /f-stack/dpdk/drivers/net/dpaa2/dpaa2_ethdev.c (revision 2d9fd380)
1d30ea906Sjfb8856606 /* * SPDX-License-Identifier: BSD-3-Clause
22bfe3f2eSlogwang  *
32bfe3f2eSlogwang  *   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
4*2d9fd380Sjfb8856606  *   Copyright 2016-2020 NXP
52bfe3f2eSlogwang  *
62bfe3f2eSlogwang  */
72bfe3f2eSlogwang 
82bfe3f2eSlogwang #include <time.h>
92bfe3f2eSlogwang #include <net/if.h>
102bfe3f2eSlogwang 
112bfe3f2eSlogwang #include <rte_mbuf.h>
12d30ea906Sjfb8856606 #include <rte_ethdev_driver.h>
132bfe3f2eSlogwang #include <rte_malloc.h>
142bfe3f2eSlogwang #include <rte_memcpy.h>
152bfe3f2eSlogwang #include <rte_string_fns.h>
162bfe3f2eSlogwang #include <rte_cycles.h>
172bfe3f2eSlogwang #include <rte_kvargs.h>
182bfe3f2eSlogwang #include <rte_dev.h>
192bfe3f2eSlogwang #include <rte_fslmc.h>
204418919fSjohnjiang #include <rte_flow_driver.h>
212bfe3f2eSlogwang 
22d30ea906Sjfb8856606 #include "dpaa2_pmd_logs.h"
232bfe3f2eSlogwang #include <fslmc_vfio.h>
242bfe3f2eSlogwang #include <dpaa2_hw_pvt.h>
252bfe3f2eSlogwang #include <dpaa2_hw_mempool.h>
262bfe3f2eSlogwang #include <dpaa2_hw_dpio.h>
272bfe3f2eSlogwang #include <mc/fsl_dpmng.h>
282bfe3f2eSlogwang #include "dpaa2_ethdev.h"
294418919fSjohnjiang #include "dpaa2_sparser.h"
30d30ea906Sjfb8856606 #include <fsl_qbman_debug.h>
31d30ea906Sjfb8856606 
324418919fSjohnjiang #define DRIVER_LOOPBACK_MODE "drv_loopback"
334418919fSjohnjiang #define DRIVER_NO_PREFETCH_MODE "drv_no_prefetch"
344418919fSjohnjiang 
35d30ea906Sjfb8856606 /* Supported Rx offloads */
36d30ea906Sjfb8856606 static uint64_t dev_rx_offloads_sup =
374418919fSjohnjiang 		DEV_RX_OFFLOAD_CHECKSUM |
384418919fSjohnjiang 		DEV_RX_OFFLOAD_SCTP_CKSUM |
39d30ea906Sjfb8856606 		DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
404418919fSjohnjiang 		DEV_RX_OFFLOAD_OUTER_UDP_CKSUM |
414418919fSjohnjiang 		DEV_RX_OFFLOAD_VLAN_STRIP |
42d30ea906Sjfb8856606 		DEV_RX_OFFLOAD_VLAN_FILTER |
434418919fSjohnjiang 		DEV_RX_OFFLOAD_JUMBO_FRAME |
444418919fSjohnjiang 		DEV_RX_OFFLOAD_TIMESTAMP;
45d30ea906Sjfb8856606 
46d30ea906Sjfb8856606 /* Rx offloads which cannot be disabled */
47d30ea906Sjfb8856606 static uint64_t dev_rx_offloads_nodis =
484418919fSjohnjiang 		DEV_RX_OFFLOAD_RSS_HASH |
49d30ea906Sjfb8856606 		DEV_RX_OFFLOAD_SCATTER;
50d30ea906Sjfb8856606 
51d30ea906Sjfb8856606 /* Supported Tx offloads */
52d30ea906Sjfb8856606 static uint64_t dev_tx_offloads_sup =
53d30ea906Sjfb8856606 		DEV_TX_OFFLOAD_VLAN_INSERT |
54d30ea906Sjfb8856606 		DEV_TX_OFFLOAD_IPV4_CKSUM |
55d30ea906Sjfb8856606 		DEV_TX_OFFLOAD_UDP_CKSUM |
56d30ea906Sjfb8856606 		DEV_TX_OFFLOAD_TCP_CKSUM |
57d30ea906Sjfb8856606 		DEV_TX_OFFLOAD_SCTP_CKSUM |
584418919fSjohnjiang 		DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
594418919fSjohnjiang 		DEV_TX_OFFLOAD_MT_LOCKFREE |
604418919fSjohnjiang 		DEV_TX_OFFLOAD_MBUF_FAST_FREE;
61d30ea906Sjfb8856606 
62d30ea906Sjfb8856606 /* Tx offloads which cannot be disabled */
63d30ea906Sjfb8856606 static uint64_t dev_tx_offloads_nodis =
644418919fSjohnjiang 		DEV_TX_OFFLOAD_MULTI_SEGS;
654418919fSjohnjiang 
664418919fSjohnjiang /* enable timestamp in mbuf */
67*2d9fd380Sjfb8856606 bool dpaa2_enable_ts[RTE_MAX_ETHPORTS];
68*2d9fd380Sjfb8856606 uint64_t dpaa2_timestamp_rx_dynflag;
69*2d9fd380Sjfb8856606 int dpaa2_timestamp_dynfield_offset = -1;
702bfe3f2eSlogwang 
712bfe3f2eSlogwang struct rte_dpaa2_xstats_name_off {
722bfe3f2eSlogwang 	char name[RTE_ETH_XSTATS_NAME_SIZE];
732bfe3f2eSlogwang 	uint8_t page_id; /* dpni statistics page id */
742bfe3f2eSlogwang 	uint8_t stats_id; /* stats id in the given page */
752bfe3f2eSlogwang };
762bfe3f2eSlogwang 
772bfe3f2eSlogwang static const struct rte_dpaa2_xstats_name_off dpaa2_xstats_strings[] = {
782bfe3f2eSlogwang 	{"ingress_multicast_frames", 0, 2},
792bfe3f2eSlogwang 	{"ingress_multicast_bytes", 0, 3},
802bfe3f2eSlogwang 	{"ingress_broadcast_frames", 0, 4},
812bfe3f2eSlogwang 	{"ingress_broadcast_bytes", 0, 5},
822bfe3f2eSlogwang 	{"egress_multicast_frames", 1, 2},
832bfe3f2eSlogwang 	{"egress_multicast_bytes", 1, 3},
842bfe3f2eSlogwang 	{"egress_broadcast_frames", 1, 4},
852bfe3f2eSlogwang 	{"egress_broadcast_bytes", 1, 5},
862bfe3f2eSlogwang 	{"ingress_filtered_frames", 2, 0},
872bfe3f2eSlogwang 	{"ingress_discarded_frames", 2, 1},
882bfe3f2eSlogwang 	{"ingress_nobuffer_discards", 2, 2},
892bfe3f2eSlogwang 	{"egress_discarded_frames", 2, 3},
902bfe3f2eSlogwang 	{"egress_confirmed_frames", 2, 4},
914418919fSjohnjiang 	{"cgr_reject_frames", 4, 0},
924418919fSjohnjiang 	{"cgr_reject_bytes", 4, 1},
934418919fSjohnjiang };
944418919fSjohnjiang 
954418919fSjohnjiang static const enum rte_filter_op dpaa2_supported_filter_ops[] = {
964418919fSjohnjiang 	RTE_ETH_FILTER_GET
972bfe3f2eSlogwang };
982bfe3f2eSlogwang 
992bfe3f2eSlogwang static struct rte_dpaa2_driver rte_dpaa2_pmd;
1002bfe3f2eSlogwang static int dpaa2_dev_link_update(struct rte_eth_dev *dev,
1012bfe3f2eSlogwang 				 int wait_to_complete);
1022bfe3f2eSlogwang static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev);
1032bfe3f2eSlogwang static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev);
1042bfe3f2eSlogwang static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
1052bfe3f2eSlogwang 
1062bfe3f2eSlogwang static int
dpaa2_vlan_filter_set(struct rte_eth_dev * dev,uint16_t vlan_id,int on)1072bfe3f2eSlogwang dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1082bfe3f2eSlogwang {
1092bfe3f2eSlogwang 	int ret;
1102bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
1114418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
1122bfe3f2eSlogwang 
1132bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
1142bfe3f2eSlogwang 
1152bfe3f2eSlogwang 	if (dpni == NULL) {
116d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
1172bfe3f2eSlogwang 		return -1;
1182bfe3f2eSlogwang 	}
1192bfe3f2eSlogwang 
1202bfe3f2eSlogwang 	if (on)
1214418919fSjohnjiang 		ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW, priv->token,
1224418919fSjohnjiang 				       vlan_id, 0, 0, 0);
1232bfe3f2eSlogwang 	else
1242bfe3f2eSlogwang 		ret = dpni_remove_vlan_id(dpni, CMD_PRI_LOW,
1252bfe3f2eSlogwang 					  priv->token, vlan_id);
1262bfe3f2eSlogwang 
1272bfe3f2eSlogwang 	if (ret < 0)
128d30ea906Sjfb8856606 		DPAA2_PMD_ERR("ret = %d Unable to add/rem vlan %d hwid =%d",
1292bfe3f2eSlogwang 			      ret, vlan_id, priv->hw_id);
1302bfe3f2eSlogwang 
1312bfe3f2eSlogwang 	return ret;
1322bfe3f2eSlogwang }
1332bfe3f2eSlogwang 
1342bfe3f2eSlogwang static int
dpaa2_vlan_offload_set(struct rte_eth_dev * dev,int mask)1352bfe3f2eSlogwang dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1362bfe3f2eSlogwang {
1372bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
1384418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
1390c6bd470Sfengbojiang 	int ret = 0;
1402bfe3f2eSlogwang 
1412bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
1422bfe3f2eSlogwang 
1432bfe3f2eSlogwang 	if (mask & ETH_VLAN_FILTER_MASK) {
144d30ea906Sjfb8856606 		/* VLAN Filter not avaialble */
145d30ea906Sjfb8856606 		if (!priv->max_vlan_filters) {
146d30ea906Sjfb8856606 			DPAA2_PMD_INFO("VLAN filter not available");
1470c6bd470Sfengbojiang 			return -ENOTSUP;
148d30ea906Sjfb8856606 		}
149d30ea906Sjfb8856606 
150d30ea906Sjfb8856606 		if (dev->data->dev_conf.rxmode.offloads &
151d30ea906Sjfb8856606 			DEV_RX_OFFLOAD_VLAN_FILTER)
1522bfe3f2eSlogwang 			ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW,
1532bfe3f2eSlogwang 						      priv->token, true);
1542bfe3f2eSlogwang 		else
1552bfe3f2eSlogwang 			ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW,
1562bfe3f2eSlogwang 						      priv->token, false);
1572bfe3f2eSlogwang 		if (ret < 0)
158d30ea906Sjfb8856606 			DPAA2_PMD_INFO("Unable to set vlan filter = %d", ret);
1592bfe3f2eSlogwang 	}
1602bfe3f2eSlogwang 
1610c6bd470Sfengbojiang 	return ret;
1622bfe3f2eSlogwang }
1632bfe3f2eSlogwang 
1642bfe3f2eSlogwang static int
dpaa2_vlan_tpid_set(struct rte_eth_dev * dev,enum rte_vlan_type vlan_type __rte_unused,uint16_t tpid)1654418919fSjohnjiang dpaa2_vlan_tpid_set(struct rte_eth_dev *dev,
1664418919fSjohnjiang 		      enum rte_vlan_type vlan_type __rte_unused,
1674418919fSjohnjiang 		      uint16_t tpid)
1684418919fSjohnjiang {
1694418919fSjohnjiang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
1704418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
1714418919fSjohnjiang 	int ret = -ENOTSUP;
1724418919fSjohnjiang 
1734418919fSjohnjiang 	PMD_INIT_FUNC_TRACE();
1744418919fSjohnjiang 
1754418919fSjohnjiang 	/* nothing to be done for standard vlan tpids */
1764418919fSjohnjiang 	if (tpid == 0x8100 || tpid == 0x88A8)
1774418919fSjohnjiang 		return 0;
1784418919fSjohnjiang 
1794418919fSjohnjiang 	ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW,
1804418919fSjohnjiang 				   priv->token, tpid);
1814418919fSjohnjiang 	if (ret < 0)
1824418919fSjohnjiang 		DPAA2_PMD_INFO("Unable to set vlan tpid = %d", ret);
1834418919fSjohnjiang 	/* if already configured tpids, remove them first */
1844418919fSjohnjiang 	if (ret == -EBUSY) {
1854418919fSjohnjiang 		struct dpni_custom_tpid_cfg tpid_list = {0};
1864418919fSjohnjiang 
1874418919fSjohnjiang 		ret = dpni_get_custom_tpid(dpni, CMD_PRI_LOW,
1884418919fSjohnjiang 				   priv->token, &tpid_list);
1894418919fSjohnjiang 		if (ret < 0)
1904418919fSjohnjiang 			goto fail;
1914418919fSjohnjiang 		ret = dpni_remove_custom_tpid(dpni, CMD_PRI_LOW,
1924418919fSjohnjiang 				   priv->token, tpid_list.tpid1);
1934418919fSjohnjiang 		if (ret < 0)
1944418919fSjohnjiang 			goto fail;
1954418919fSjohnjiang 		ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW,
1964418919fSjohnjiang 					   priv->token, tpid);
1974418919fSjohnjiang 	}
1984418919fSjohnjiang fail:
1994418919fSjohnjiang 	return ret;
2004418919fSjohnjiang }
2014418919fSjohnjiang 
2024418919fSjohnjiang static int
dpaa2_fw_version_get(struct rte_eth_dev * dev,char * fw_version,size_t fw_size)2032bfe3f2eSlogwang dpaa2_fw_version_get(struct rte_eth_dev *dev,
2042bfe3f2eSlogwang 		     char *fw_version,
2052bfe3f2eSlogwang 		     size_t fw_size)
2062bfe3f2eSlogwang {
2072bfe3f2eSlogwang 	int ret;
2084418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
2092bfe3f2eSlogwang 	struct mc_soc_version mc_plat_info = {0};
2102bfe3f2eSlogwang 	struct mc_version mc_ver_info = {0};
2112bfe3f2eSlogwang 
2122bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
2132bfe3f2eSlogwang 
2142bfe3f2eSlogwang 	if (mc_get_soc_version(dpni, CMD_PRI_LOW, &mc_plat_info))
215d30ea906Sjfb8856606 		DPAA2_PMD_WARN("\tmc_get_soc_version failed");
2162bfe3f2eSlogwang 
2172bfe3f2eSlogwang 	if (mc_get_version(dpni, CMD_PRI_LOW, &mc_ver_info))
218d30ea906Sjfb8856606 		DPAA2_PMD_WARN("\tmc_get_version failed");
2192bfe3f2eSlogwang 
2202bfe3f2eSlogwang 	ret = snprintf(fw_version, fw_size,
2212bfe3f2eSlogwang 		       "%x-%d.%d.%d",
2222bfe3f2eSlogwang 		       mc_plat_info.svr,
2232bfe3f2eSlogwang 		       mc_ver_info.major,
2242bfe3f2eSlogwang 		       mc_ver_info.minor,
2252bfe3f2eSlogwang 		       mc_ver_info.revision);
2262bfe3f2eSlogwang 
2272bfe3f2eSlogwang 	ret += 1; /* add the size of '\0' */
2282bfe3f2eSlogwang 	if (fw_size < (uint32_t)ret)
2292bfe3f2eSlogwang 		return ret;
2302bfe3f2eSlogwang 	else
2312bfe3f2eSlogwang 		return 0;
2322bfe3f2eSlogwang }
2332bfe3f2eSlogwang 
2344418919fSjohnjiang static int
dpaa2_dev_info_get(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)2352bfe3f2eSlogwang dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
2362bfe3f2eSlogwang {
2372bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
2382bfe3f2eSlogwang 
2392bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
2402bfe3f2eSlogwang 
2412bfe3f2eSlogwang 	dev_info->max_mac_addrs = priv->max_mac_filters;
2422bfe3f2eSlogwang 	dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN;
2432bfe3f2eSlogwang 	dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE;
2442bfe3f2eSlogwang 	dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
2452bfe3f2eSlogwang 	dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
246d30ea906Sjfb8856606 	dev_info->rx_offload_capa = dev_rx_offloads_sup |
247d30ea906Sjfb8856606 					dev_rx_offloads_nodis;
248d30ea906Sjfb8856606 	dev_info->tx_offload_capa = dev_tx_offloads_sup |
249d30ea906Sjfb8856606 					dev_tx_offloads_nodis;
2502bfe3f2eSlogwang 	dev_info->speed_capa = ETH_LINK_SPEED_1G |
2512bfe3f2eSlogwang 			ETH_LINK_SPEED_2_5G |
2522bfe3f2eSlogwang 			ETH_LINK_SPEED_10G;
253d30ea906Sjfb8856606 
254d30ea906Sjfb8856606 	dev_info->max_hash_mac_addrs = 0;
255d30ea906Sjfb8856606 	dev_info->max_vfs = 0;
256d30ea906Sjfb8856606 	dev_info->max_vmdq_pools = ETH_16_POOLS;
257d30ea906Sjfb8856606 	dev_info->flow_type_rss_offloads = DPAA2_RSS_OFFLOAD_ALL;
2584418919fSjohnjiang 
259*2d9fd380Sjfb8856606 	dev_info->default_rxportconf.burst_size = dpaa2_dqrr_size;
260*2d9fd380Sjfb8856606 	/* same is rx size for best perf */
261*2d9fd380Sjfb8856606 	dev_info->default_txportconf.burst_size = dpaa2_dqrr_size;
262*2d9fd380Sjfb8856606 
263*2d9fd380Sjfb8856606 	dev_info->default_rxportconf.nb_queues = 1;
264*2d9fd380Sjfb8856606 	dev_info->default_txportconf.nb_queues = 1;
265*2d9fd380Sjfb8856606 	dev_info->default_txportconf.ring_size = CONG_ENTER_TX_THRESHOLD;
266*2d9fd380Sjfb8856606 	dev_info->default_rxportconf.ring_size = DPAA2_RX_DEFAULT_NBDESC;
267*2d9fd380Sjfb8856606 
268*2d9fd380Sjfb8856606 	if (dpaa2_svr_family == SVR_LX2160A) {
269*2d9fd380Sjfb8856606 		dev_info->speed_capa |= ETH_LINK_SPEED_25G |
270*2d9fd380Sjfb8856606 				ETH_LINK_SPEED_40G |
271*2d9fd380Sjfb8856606 				ETH_LINK_SPEED_50G |
272*2d9fd380Sjfb8856606 				ETH_LINK_SPEED_100G;
273*2d9fd380Sjfb8856606 	}
274*2d9fd380Sjfb8856606 
2754418919fSjohnjiang 	return 0;
2762bfe3f2eSlogwang }
2772bfe3f2eSlogwang 
2782bfe3f2eSlogwang static int
dpaa2_dev_rx_burst_mode_get(struct rte_eth_dev * dev,__rte_unused uint16_t queue_id,struct rte_eth_burst_mode * mode)279*2d9fd380Sjfb8856606 dpaa2_dev_rx_burst_mode_get(struct rte_eth_dev *dev,
280*2d9fd380Sjfb8856606 			__rte_unused uint16_t queue_id,
281*2d9fd380Sjfb8856606 			struct rte_eth_burst_mode *mode)
282*2d9fd380Sjfb8856606 {
283*2d9fd380Sjfb8856606 	struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
284*2d9fd380Sjfb8856606 	int ret = -EINVAL;
285*2d9fd380Sjfb8856606 	unsigned int i;
286*2d9fd380Sjfb8856606 	const struct burst_info {
287*2d9fd380Sjfb8856606 		uint64_t flags;
288*2d9fd380Sjfb8856606 		const char *output;
289*2d9fd380Sjfb8856606 	} rx_offload_map[] = {
290*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_CHECKSUM, " Checksum,"},
291*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_SCTP_CKSUM, " SCTP csum,"},
292*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPV4 csum,"},
293*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_OUTER_UDP_CKSUM, " Outer UDP csum,"},
294*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_VLAN_STRIP, " VLAN strip,"},
295*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_VLAN_FILTER, " VLAN filter,"},
296*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_JUMBO_FRAME, " Jumbo frame,"},
297*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_TIMESTAMP, " Timestamp,"},
298*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_RSS_HASH, " RSS,"},
299*2d9fd380Sjfb8856606 			{DEV_RX_OFFLOAD_SCATTER, " Scattered,"}
300*2d9fd380Sjfb8856606 	};
301*2d9fd380Sjfb8856606 
302*2d9fd380Sjfb8856606 	/* Update Rx offload info */
303*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(rx_offload_map); i++) {
304*2d9fd380Sjfb8856606 		if (eth_conf->rxmode.offloads & rx_offload_map[i].flags) {
305*2d9fd380Sjfb8856606 			snprintf(mode->info, sizeof(mode->info), "%s",
306*2d9fd380Sjfb8856606 				rx_offload_map[i].output);
307*2d9fd380Sjfb8856606 			ret = 0;
308*2d9fd380Sjfb8856606 			break;
309*2d9fd380Sjfb8856606 		}
310*2d9fd380Sjfb8856606 	}
311*2d9fd380Sjfb8856606 	return ret;
312*2d9fd380Sjfb8856606 }
313*2d9fd380Sjfb8856606 
314*2d9fd380Sjfb8856606 static int
dpaa2_dev_tx_burst_mode_get(struct rte_eth_dev * dev,__rte_unused uint16_t queue_id,struct rte_eth_burst_mode * mode)315*2d9fd380Sjfb8856606 dpaa2_dev_tx_burst_mode_get(struct rte_eth_dev *dev,
316*2d9fd380Sjfb8856606 			__rte_unused uint16_t queue_id,
317*2d9fd380Sjfb8856606 			struct rte_eth_burst_mode *mode)
318*2d9fd380Sjfb8856606 {
319*2d9fd380Sjfb8856606 	struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
320*2d9fd380Sjfb8856606 	int ret = -EINVAL;
321*2d9fd380Sjfb8856606 	unsigned int i;
322*2d9fd380Sjfb8856606 	const struct burst_info {
323*2d9fd380Sjfb8856606 		uint64_t flags;
324*2d9fd380Sjfb8856606 		const char *output;
325*2d9fd380Sjfb8856606 	} tx_offload_map[] = {
326*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_VLAN_INSERT, " VLAN Insert,"},
327*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_IPV4_CKSUM, " IPV4 csum,"},
328*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_UDP_CKSUM, " UDP csum,"},
329*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_TCP_CKSUM, " TCP csum,"},
330*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_SCTP_CKSUM, " SCTP csum,"},
331*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPV4 csum,"},
332*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_MT_LOCKFREE, " MT lockfree,"},
333*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_MBUF_FAST_FREE, " MBUF free disable,"},
334*2d9fd380Sjfb8856606 			{DEV_TX_OFFLOAD_MULTI_SEGS, " Scattered,"}
335*2d9fd380Sjfb8856606 	};
336*2d9fd380Sjfb8856606 
337*2d9fd380Sjfb8856606 	/* Update Tx offload info */
338*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(tx_offload_map); i++) {
339*2d9fd380Sjfb8856606 		if (eth_conf->txmode.offloads & tx_offload_map[i].flags) {
340*2d9fd380Sjfb8856606 			snprintf(mode->info, sizeof(mode->info), "%s",
341*2d9fd380Sjfb8856606 				tx_offload_map[i].output);
342*2d9fd380Sjfb8856606 			ret = 0;
343*2d9fd380Sjfb8856606 			break;
344*2d9fd380Sjfb8856606 		}
345*2d9fd380Sjfb8856606 	}
346*2d9fd380Sjfb8856606 	return ret;
347*2d9fd380Sjfb8856606 }
348*2d9fd380Sjfb8856606 
349*2d9fd380Sjfb8856606 static int
dpaa2_alloc_rx_tx_queues(struct rte_eth_dev * dev)3502bfe3f2eSlogwang dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
3512bfe3f2eSlogwang {
3522bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
3532bfe3f2eSlogwang 	uint16_t dist_idx;
3542bfe3f2eSlogwang 	uint32_t vq_id;
3554418919fSjohnjiang 	uint8_t num_rxqueue_per_tc;
3562bfe3f2eSlogwang 	struct dpaa2_queue *mc_q, *mcq;
3572bfe3f2eSlogwang 	uint32_t tot_queues;
3582bfe3f2eSlogwang 	int i;
3592bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_q;
3602bfe3f2eSlogwang 
3612bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
3622bfe3f2eSlogwang 
3634418919fSjohnjiang 	num_rxqueue_per_tc = (priv->nb_rx_queues / priv->num_rx_tc);
3644418919fSjohnjiang 	if (priv->tx_conf_en)
3654418919fSjohnjiang 		tot_queues = priv->nb_rx_queues + 2 * priv->nb_tx_queues;
3664418919fSjohnjiang 	else
3672bfe3f2eSlogwang 		tot_queues = priv->nb_rx_queues + priv->nb_tx_queues;
3682bfe3f2eSlogwang 	mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues,
3692bfe3f2eSlogwang 			  RTE_CACHE_LINE_SIZE);
3702bfe3f2eSlogwang 	if (!mc_q) {
371d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Memory allocation failed for rx/tx queues");
3722bfe3f2eSlogwang 		return -1;
3732bfe3f2eSlogwang 	}
3742bfe3f2eSlogwang 
3752bfe3f2eSlogwang 	for (i = 0; i < priv->nb_rx_queues; i++) {
3764418919fSjohnjiang 		mc_q->eth_data = dev->data;
3772bfe3f2eSlogwang 		priv->rx_vq[i] = mc_q++;
3782bfe3f2eSlogwang 		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
3792bfe3f2eSlogwang 		dpaa2_q->q_storage = rte_malloc("dq_storage",
3802bfe3f2eSlogwang 					sizeof(struct queue_storage_info_t),
3812bfe3f2eSlogwang 					RTE_CACHE_LINE_SIZE);
3822bfe3f2eSlogwang 		if (!dpaa2_q->q_storage)
3832bfe3f2eSlogwang 			goto fail;
3842bfe3f2eSlogwang 
3852bfe3f2eSlogwang 		memset(dpaa2_q->q_storage, 0,
3862bfe3f2eSlogwang 		       sizeof(struct queue_storage_info_t));
3872bfe3f2eSlogwang 		if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage))
3882bfe3f2eSlogwang 			goto fail;
3892bfe3f2eSlogwang 	}
3902bfe3f2eSlogwang 
3912bfe3f2eSlogwang 	for (i = 0; i < priv->nb_tx_queues; i++) {
3924418919fSjohnjiang 		mc_q->eth_data = dev->data;
3932bfe3f2eSlogwang 		mc_q->flow_id = 0xffff;
3942bfe3f2eSlogwang 		priv->tx_vq[i] = mc_q++;
3952bfe3f2eSlogwang 		dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
3962bfe3f2eSlogwang 		dpaa2_q->cscn = rte_malloc(NULL,
3972bfe3f2eSlogwang 					   sizeof(struct qbman_result), 16);
3982bfe3f2eSlogwang 		if (!dpaa2_q->cscn)
3992bfe3f2eSlogwang 			goto fail_tx;
4002bfe3f2eSlogwang 	}
4012bfe3f2eSlogwang 
4024418919fSjohnjiang 	if (priv->tx_conf_en) {
4034418919fSjohnjiang 		/*Setup tx confirmation queues*/
4044418919fSjohnjiang 		for (i = 0; i < priv->nb_tx_queues; i++) {
4054418919fSjohnjiang 			mc_q->eth_data = dev->data;
4064418919fSjohnjiang 			mc_q->tc_index = i;
4074418919fSjohnjiang 			mc_q->flow_id = 0;
4084418919fSjohnjiang 			priv->tx_conf_vq[i] = mc_q++;
4094418919fSjohnjiang 			dpaa2_q = (struct dpaa2_queue *)priv->tx_conf_vq[i];
4104418919fSjohnjiang 			dpaa2_q->q_storage =
4114418919fSjohnjiang 				rte_malloc("dq_storage",
4124418919fSjohnjiang 					sizeof(struct queue_storage_info_t),
4134418919fSjohnjiang 					RTE_CACHE_LINE_SIZE);
4144418919fSjohnjiang 			if (!dpaa2_q->q_storage)
4154418919fSjohnjiang 				goto fail_tx_conf;
4164418919fSjohnjiang 
4174418919fSjohnjiang 			memset(dpaa2_q->q_storage, 0,
4184418919fSjohnjiang 			       sizeof(struct queue_storage_info_t));
4194418919fSjohnjiang 			if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage))
4204418919fSjohnjiang 				goto fail_tx_conf;
4214418919fSjohnjiang 		}
4224418919fSjohnjiang 	}
4234418919fSjohnjiang 
4242bfe3f2eSlogwang 	vq_id = 0;
4252bfe3f2eSlogwang 	for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
4262bfe3f2eSlogwang 		mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
4274418919fSjohnjiang 		mcq->tc_index = dist_idx / num_rxqueue_per_tc;
4284418919fSjohnjiang 		mcq->flow_id = dist_idx % num_rxqueue_per_tc;
4292bfe3f2eSlogwang 		vq_id++;
4302bfe3f2eSlogwang 	}
4312bfe3f2eSlogwang 
4322bfe3f2eSlogwang 	return 0;
4334418919fSjohnjiang fail_tx_conf:
4344418919fSjohnjiang 	i -= 1;
4354418919fSjohnjiang 	while (i >= 0) {
4364418919fSjohnjiang 		dpaa2_q = (struct dpaa2_queue *)priv->tx_conf_vq[i];
4374418919fSjohnjiang 		rte_free(dpaa2_q->q_storage);
4384418919fSjohnjiang 		priv->tx_conf_vq[i--] = NULL;
4394418919fSjohnjiang 	}
4404418919fSjohnjiang 	i = priv->nb_tx_queues;
4412bfe3f2eSlogwang fail_tx:
4422bfe3f2eSlogwang 	i -= 1;
4432bfe3f2eSlogwang 	while (i >= 0) {
4442bfe3f2eSlogwang 		dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
4452bfe3f2eSlogwang 		rte_free(dpaa2_q->cscn);
4462bfe3f2eSlogwang 		priv->tx_vq[i--] = NULL;
4472bfe3f2eSlogwang 	}
4482bfe3f2eSlogwang 	i = priv->nb_rx_queues;
4492bfe3f2eSlogwang fail:
4502bfe3f2eSlogwang 	i -= 1;
4512bfe3f2eSlogwang 	mc_q = priv->rx_vq[0];
4522bfe3f2eSlogwang 	while (i >= 0) {
4532bfe3f2eSlogwang 		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
4542bfe3f2eSlogwang 		dpaa2_free_dq_storage(dpaa2_q->q_storage);
4552bfe3f2eSlogwang 		rte_free(dpaa2_q->q_storage);
4562bfe3f2eSlogwang 		priv->rx_vq[i--] = NULL;
4572bfe3f2eSlogwang 	}
4582bfe3f2eSlogwang 	rte_free(mc_q);
4592bfe3f2eSlogwang 	return -1;
4602bfe3f2eSlogwang }
4612bfe3f2eSlogwang 
462d30ea906Sjfb8856606 static void
dpaa2_free_rx_tx_queues(struct rte_eth_dev * dev)463d30ea906Sjfb8856606 dpaa2_free_rx_tx_queues(struct rte_eth_dev *dev)
464d30ea906Sjfb8856606 {
465d30ea906Sjfb8856606 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
466d30ea906Sjfb8856606 	struct dpaa2_queue *dpaa2_q;
467d30ea906Sjfb8856606 	int i;
468d30ea906Sjfb8856606 
469d30ea906Sjfb8856606 	PMD_INIT_FUNC_TRACE();
470d30ea906Sjfb8856606 
471d30ea906Sjfb8856606 	/* Queue allocation base */
472d30ea906Sjfb8856606 	if (priv->rx_vq[0]) {
473d30ea906Sjfb8856606 		/* cleaning up queue storage */
474d30ea906Sjfb8856606 		for (i = 0; i < priv->nb_rx_queues; i++) {
475d30ea906Sjfb8856606 			dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
476d30ea906Sjfb8856606 			if (dpaa2_q->q_storage)
477d30ea906Sjfb8856606 				rte_free(dpaa2_q->q_storage);
478d30ea906Sjfb8856606 		}
479d30ea906Sjfb8856606 		/* cleanup tx queue cscn */
480d30ea906Sjfb8856606 		for (i = 0; i < priv->nb_tx_queues; i++) {
481d30ea906Sjfb8856606 			dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
482d30ea906Sjfb8856606 			rte_free(dpaa2_q->cscn);
483d30ea906Sjfb8856606 		}
4844418919fSjohnjiang 		if (priv->tx_conf_en) {
4854418919fSjohnjiang 			/* cleanup tx conf queue storage */
4864418919fSjohnjiang 			for (i = 0; i < priv->nb_tx_queues; i++) {
4874418919fSjohnjiang 				dpaa2_q = (struct dpaa2_queue *)
4884418919fSjohnjiang 						priv->tx_conf_vq[i];
4894418919fSjohnjiang 				rte_free(dpaa2_q->q_storage);
4904418919fSjohnjiang 			}
4914418919fSjohnjiang 		}
492d30ea906Sjfb8856606 		/*free memory for all queues (RX+TX) */
493d30ea906Sjfb8856606 		rte_free(priv->rx_vq[0]);
494d30ea906Sjfb8856606 		priv->rx_vq[0] = NULL;
495d30ea906Sjfb8856606 	}
496d30ea906Sjfb8856606 }
497d30ea906Sjfb8856606 
4982bfe3f2eSlogwang static int
dpaa2_eth_dev_configure(struct rte_eth_dev * dev)4992bfe3f2eSlogwang dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
5002bfe3f2eSlogwang {
5012bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
5024418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
5032bfe3f2eSlogwang 	struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
504d30ea906Sjfb8856606 	uint64_t rx_offloads = eth_conf->rxmode.offloads;
505d30ea906Sjfb8856606 	uint64_t tx_offloads = eth_conf->txmode.offloads;
506d30ea906Sjfb8856606 	int rx_l3_csum_offload = false;
507d30ea906Sjfb8856606 	int rx_l4_csum_offload = false;
508d30ea906Sjfb8856606 	int tx_l3_csum_offload = false;
509d30ea906Sjfb8856606 	int tx_l4_csum_offload = false;
510*2d9fd380Sjfb8856606 	int ret, tc_index;
5112bfe3f2eSlogwang 
5122bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
5132bfe3f2eSlogwang 
5144418919fSjohnjiang 	/* Rx offloads which are enabled by default */
515d30ea906Sjfb8856606 	if (dev_rx_offloads_nodis & ~rx_offloads) {
5164418919fSjohnjiang 		DPAA2_PMD_INFO(
5174418919fSjohnjiang 		"Some of rx offloads enabled by default - requested 0x%" PRIx64
5184418919fSjohnjiang 		" fixed are 0x%" PRIx64,
519d30ea906Sjfb8856606 		rx_offloads, dev_rx_offloads_nodis);
520d30ea906Sjfb8856606 	}
521d30ea906Sjfb8856606 
5224418919fSjohnjiang 	/* Tx offloads which are enabled by default */
523d30ea906Sjfb8856606 	if (dev_tx_offloads_nodis & ~tx_offloads) {
5244418919fSjohnjiang 		DPAA2_PMD_INFO(
5254418919fSjohnjiang 		"Some of tx offloads enabled by default - requested 0x%" PRIx64
5264418919fSjohnjiang 		" fixed are 0x%" PRIx64,
527d30ea906Sjfb8856606 		tx_offloads, dev_tx_offloads_nodis);
528d30ea906Sjfb8856606 	}
529d30ea906Sjfb8856606 
530d30ea906Sjfb8856606 	if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
5312bfe3f2eSlogwang 		if (eth_conf->rxmode.max_rx_pkt_len <= DPAA2_MAX_RX_PKT_LEN) {
532d30ea906Sjfb8856606 			ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW,
5334418919fSjohnjiang 				priv->token, eth_conf->rxmode.max_rx_pkt_len
5344418919fSjohnjiang 				- RTE_ETHER_CRC_LEN);
5352bfe3f2eSlogwang 			if (ret) {
536d30ea906Sjfb8856606 				DPAA2_PMD_ERR(
537d30ea906Sjfb8856606 					"Unable to set mtu. check config");
5382bfe3f2eSlogwang 				return ret;
5392bfe3f2eSlogwang 			}
5404418919fSjohnjiang 			dev->data->mtu =
5414418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_rx_pkt_len -
5424418919fSjohnjiang 				RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN -
5434418919fSjohnjiang 				VLAN_TAG_SIZE;
5442bfe3f2eSlogwang 		} else {
5452bfe3f2eSlogwang 			return -1;
5462bfe3f2eSlogwang 		}
5472bfe3f2eSlogwang 	}
5482bfe3f2eSlogwang 
5492bfe3f2eSlogwang 	if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) {
550*2d9fd380Sjfb8856606 		for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) {
5512bfe3f2eSlogwang 			ret = dpaa2_setup_flow_dist(dev,
552*2d9fd380Sjfb8856606 					eth_conf->rx_adv_conf.rss_conf.rss_hf,
553*2d9fd380Sjfb8856606 					tc_index);
5542bfe3f2eSlogwang 			if (ret) {
555*2d9fd380Sjfb8856606 				DPAA2_PMD_ERR(
556*2d9fd380Sjfb8856606 					"Unable to set flow distribution on tc%d."
557*2d9fd380Sjfb8856606 					"Check queue config", tc_index);
5582bfe3f2eSlogwang 				return ret;
5592bfe3f2eSlogwang 			}
5602bfe3f2eSlogwang 		}
561*2d9fd380Sjfb8856606 	}
5622bfe3f2eSlogwang 
563d30ea906Sjfb8856606 	if (rx_offloads & DEV_RX_OFFLOAD_IPV4_CKSUM)
564d30ea906Sjfb8856606 		rx_l3_csum_offload = true;
565d30ea906Sjfb8856606 
566d30ea906Sjfb8856606 	if ((rx_offloads & DEV_RX_OFFLOAD_UDP_CKSUM) ||
5674418919fSjohnjiang 		(rx_offloads & DEV_RX_OFFLOAD_TCP_CKSUM) ||
5684418919fSjohnjiang 		(rx_offloads & DEV_RX_OFFLOAD_SCTP_CKSUM))
569d30ea906Sjfb8856606 		rx_l4_csum_offload = true;
5702bfe3f2eSlogwang 
5712bfe3f2eSlogwang 	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
572d30ea906Sjfb8856606 			       DPNI_OFF_RX_L3_CSUM, rx_l3_csum_offload);
5732bfe3f2eSlogwang 	if (ret) {
574d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error to set RX l3 csum:Error = %d", ret);
5752bfe3f2eSlogwang 		return ret;
5762bfe3f2eSlogwang 	}
5772bfe3f2eSlogwang 
5782bfe3f2eSlogwang 	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
579d30ea906Sjfb8856606 			       DPNI_OFF_RX_L4_CSUM, rx_l4_csum_offload);
5802bfe3f2eSlogwang 	if (ret) {
581d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error to get RX l4 csum:Error = %d", ret);
582d30ea906Sjfb8856606 		return ret;
583d30ea906Sjfb8856606 	}
584d30ea906Sjfb8856606 
585*2d9fd380Sjfb8856606 #if !defined(RTE_LIBRTE_IEEE1588)
5864418919fSjohnjiang 	if (rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP)
587*2d9fd380Sjfb8856606 #endif
588*2d9fd380Sjfb8856606 	{
589*2d9fd380Sjfb8856606 		ret = rte_mbuf_dyn_rx_timestamp_register(
590*2d9fd380Sjfb8856606 				&dpaa2_timestamp_dynfield_offset,
591*2d9fd380Sjfb8856606 				&dpaa2_timestamp_rx_dynflag);
592*2d9fd380Sjfb8856606 		if (ret != 0) {
593*2d9fd380Sjfb8856606 			DPAA2_PMD_ERR("Error to register timestamp field/flag");
594*2d9fd380Sjfb8856606 			return -rte_errno;
595*2d9fd380Sjfb8856606 		}
596*2d9fd380Sjfb8856606 		dpaa2_enable_ts[dev->data->port_id] = true;
597*2d9fd380Sjfb8856606 	}
5984418919fSjohnjiang 
599d30ea906Sjfb8856606 	if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM)
600d30ea906Sjfb8856606 		tx_l3_csum_offload = true;
601d30ea906Sjfb8856606 
602d30ea906Sjfb8856606 	if ((tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM) ||
603d30ea906Sjfb8856606 		(tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM) ||
604d30ea906Sjfb8856606 		(tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM))
605d30ea906Sjfb8856606 		tx_l4_csum_offload = true;
606d30ea906Sjfb8856606 
607d30ea906Sjfb8856606 	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
608d30ea906Sjfb8856606 			       DPNI_OFF_TX_L3_CSUM, tx_l3_csum_offload);
609d30ea906Sjfb8856606 	if (ret) {
610d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error to set TX l3 csum:Error = %d", ret);
6112bfe3f2eSlogwang 		return ret;
6122bfe3f2eSlogwang 	}
6132bfe3f2eSlogwang 
6142bfe3f2eSlogwang 	ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
615d30ea906Sjfb8856606 			       DPNI_OFF_TX_L4_CSUM, tx_l4_csum_offload);
6162bfe3f2eSlogwang 	if (ret) {
617d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error to get TX l4 csum:Error = %d", ret);
6182bfe3f2eSlogwang 		return ret;
6192bfe3f2eSlogwang 	}
6202bfe3f2eSlogwang 
621d30ea906Sjfb8856606 	/* Enabling hash results in FD requires setting DPNI_FLCTYPE_HASH in
622d30ea906Sjfb8856606 	 * dpni_set_offload API. Setting this FLCTYPE for DPNI sets the FD[SC]
623d30ea906Sjfb8856606 	 * to 0 for LS2 in the hardware thus disabling data/annotation
624d30ea906Sjfb8856606 	 * stashing. For LX2 this is fixed in hardware and thus hash result and
625d30ea906Sjfb8856606 	 * parse results can be received in FD using this option.
626d30ea906Sjfb8856606 	 */
627d30ea906Sjfb8856606 	if (dpaa2_svr_family == SVR_LX2160A) {
6282bfe3f2eSlogwang 		ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
629d30ea906Sjfb8856606 				       DPNI_FLCTYPE_HASH, true);
6302bfe3f2eSlogwang 		if (ret) {
631d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Error setting FLCTYPE: Err = %d", ret);
6322bfe3f2eSlogwang 			return ret;
6332bfe3f2eSlogwang 		}
634d30ea906Sjfb8856606 	}
635d30ea906Sjfb8856606 
636d30ea906Sjfb8856606 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
637d30ea906Sjfb8856606 		dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
6382bfe3f2eSlogwang 
6392bfe3f2eSlogwang 	return 0;
6402bfe3f2eSlogwang }
6412bfe3f2eSlogwang 
6422bfe3f2eSlogwang /* Function to setup RX flow information. It contains traffic class ID,
6432bfe3f2eSlogwang  * flow ID, destination configuration etc.
6442bfe3f2eSlogwang  */
6452bfe3f2eSlogwang static int
dpaa2_dev_rx_queue_setup(struct rte_eth_dev * dev,uint16_t rx_queue_id,uint16_t nb_rx_desc,unsigned int socket_id __rte_unused,const struct rte_eth_rxconf * rx_conf,struct rte_mempool * mb_pool)6462bfe3f2eSlogwang dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
6472bfe3f2eSlogwang 			 uint16_t rx_queue_id,
6484418919fSjohnjiang 			 uint16_t nb_rx_desc,
6492bfe3f2eSlogwang 			 unsigned int socket_id __rte_unused,
650*2d9fd380Sjfb8856606 			 const struct rte_eth_rxconf *rx_conf,
6512bfe3f2eSlogwang 			 struct rte_mempool *mb_pool)
6522bfe3f2eSlogwang {
6532bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
6544418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
6552bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_q;
6562bfe3f2eSlogwang 	struct dpni_queue cfg;
6572bfe3f2eSlogwang 	uint8_t options = 0;
6582bfe3f2eSlogwang 	uint8_t flow_id;
6592bfe3f2eSlogwang 	uint32_t bpid;
6604418919fSjohnjiang 	int i, ret;
6612bfe3f2eSlogwang 
6622bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
6632bfe3f2eSlogwang 
664d30ea906Sjfb8856606 	DPAA2_PMD_DEBUG("dev =%p, queue =%d, pool = %p, conf =%p",
6652bfe3f2eSlogwang 			dev, rx_queue_id, mb_pool, rx_conf);
6662bfe3f2eSlogwang 
667*2d9fd380Sjfb8856606 	/* Rx deferred start is not supported */
668*2d9fd380Sjfb8856606 	if (rx_conf->rx_deferred_start) {
669*2d9fd380Sjfb8856606 		DPAA2_PMD_ERR("%p:Rx deferred start not supported",
670*2d9fd380Sjfb8856606 				(void *)dev);
671*2d9fd380Sjfb8856606 		return -EINVAL;
672*2d9fd380Sjfb8856606 	}
673*2d9fd380Sjfb8856606 
6742bfe3f2eSlogwang 	if (!priv->bp_list || priv->bp_list->mp != mb_pool) {
6752bfe3f2eSlogwang 		bpid = mempool_to_bpid(mb_pool);
6762bfe3f2eSlogwang 		ret = dpaa2_attach_bp_list(priv,
6772bfe3f2eSlogwang 					   rte_dpaa2_bpid_info[bpid].bp_list);
6782bfe3f2eSlogwang 		if (ret)
6792bfe3f2eSlogwang 			return ret;
6802bfe3f2eSlogwang 	}
6812bfe3f2eSlogwang 	dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
6822bfe3f2eSlogwang 	dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
6834418919fSjohnjiang 	dpaa2_q->bp_array = rte_dpaa2_bpid_info;
684*2d9fd380Sjfb8856606 	dpaa2_q->nb_desc = UINT16_MAX;
685*2d9fd380Sjfb8856606 	dpaa2_q->offloads = rx_conf->offloads;
6862bfe3f2eSlogwang 
6872bfe3f2eSlogwang 	/*Get the flow id from given VQ id*/
6884418919fSjohnjiang 	flow_id = dpaa2_q->flow_id;
6892bfe3f2eSlogwang 	memset(&cfg, 0, sizeof(struct dpni_queue));
6902bfe3f2eSlogwang 
6912bfe3f2eSlogwang 	options = options | DPNI_QUEUE_OPT_USER_CTX;
692d30ea906Sjfb8856606 	cfg.user_context = (size_t)(dpaa2_q);
6932bfe3f2eSlogwang 
6944418919fSjohnjiang 	/* check if a private cgr available. */
6954418919fSjohnjiang 	for (i = 0; i < priv->max_cgs; i++) {
6964418919fSjohnjiang 		if (!priv->cgid_in_use[i]) {
6974418919fSjohnjiang 			priv->cgid_in_use[i] = 1;
6984418919fSjohnjiang 			break;
6994418919fSjohnjiang 		}
7004418919fSjohnjiang 	}
7014418919fSjohnjiang 
7024418919fSjohnjiang 	if (i < priv->max_cgs) {
7034418919fSjohnjiang 		options |= DPNI_QUEUE_OPT_SET_CGID;
7044418919fSjohnjiang 		cfg.cgid = i;
7054418919fSjohnjiang 		dpaa2_q->cgid = cfg.cgid;
7064418919fSjohnjiang 	} else {
7074418919fSjohnjiang 		dpaa2_q->cgid = 0xff;
7084418919fSjohnjiang 	}
7094418919fSjohnjiang 
7102bfe3f2eSlogwang 	/*if ls2088 or rev2 device, enable the stashing */
7112bfe3f2eSlogwang 
712d30ea906Sjfb8856606 	if ((dpaa2_svr_family & 0xffff0000) != SVR_LS2080A) {
7132bfe3f2eSlogwang 		options |= DPNI_QUEUE_OPT_FLC;
7142bfe3f2eSlogwang 		cfg.flc.stash_control = true;
7152bfe3f2eSlogwang 		cfg.flc.value &= 0xFFFFFFFFFFFFFFC0;
7162bfe3f2eSlogwang 		/* 00 00 00 - last 6 bit represent annotation, context stashing,
717d30ea906Sjfb8856606 		 * data stashing setting 01 01 00 (0x14)
718d30ea906Sjfb8856606 		 * (in following order ->DS AS CS)
719d30ea906Sjfb8856606 		 * to enable 1 line data, 1 line annotation.
720d30ea906Sjfb8856606 		 * For LX2, this setting should be 01 00 00 (0x10)
7212bfe3f2eSlogwang 		 */
722d30ea906Sjfb8856606 		if ((dpaa2_svr_family & 0xffff0000) == SVR_LX2160A)
723d30ea906Sjfb8856606 			cfg.flc.value |= 0x10;
724d30ea906Sjfb8856606 		else
7252bfe3f2eSlogwang 			cfg.flc.value |= 0x14;
7262bfe3f2eSlogwang 	}
7272bfe3f2eSlogwang 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
7282bfe3f2eSlogwang 			     dpaa2_q->tc_index, flow_id, options, &cfg);
7292bfe3f2eSlogwang 	if (ret) {
730d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error in setting the rx flow: = %d", ret);
7312bfe3f2eSlogwang 		return -1;
7322bfe3f2eSlogwang 	}
7332bfe3f2eSlogwang 
7342bfe3f2eSlogwang 	if (!(priv->flags & DPAA2_RX_TAILDROP_OFF)) {
7352bfe3f2eSlogwang 		struct dpni_taildrop taildrop;
7362bfe3f2eSlogwang 
7372bfe3f2eSlogwang 		taildrop.enable = 1;
738*2d9fd380Sjfb8856606 		dpaa2_q->nb_desc = nb_rx_desc;
7394418919fSjohnjiang 		/* Private CGR will use tail drop length as nb_rx_desc.
7404418919fSjohnjiang 		 * for rest cases we can use standard byte based tail drop.
7414418919fSjohnjiang 		 * There is no HW restriction, but number of CGRs are limited,
7424418919fSjohnjiang 		 * hence this restriction is placed.
7434418919fSjohnjiang 		 */
7444418919fSjohnjiang 		if (dpaa2_q->cgid != 0xff) {
7452bfe3f2eSlogwang 			/*enabling per rx queue congestion control */
7464418919fSjohnjiang 			taildrop.threshold = nb_rx_desc;
7474418919fSjohnjiang 			taildrop.units = DPNI_CONGESTION_UNIT_FRAMES;
7484418919fSjohnjiang 			taildrop.oal = 0;
7494418919fSjohnjiang 			DPAA2_PMD_DEBUG("Enabling CG Tail Drop on queue = %d",
7504418919fSjohnjiang 					rx_queue_id);
7514418919fSjohnjiang 			ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
7524418919fSjohnjiang 						DPNI_CP_CONGESTION_GROUP,
7534418919fSjohnjiang 						DPNI_QUEUE_RX,
7544418919fSjohnjiang 						dpaa2_q->tc_index,
7550c6bd470Sfengbojiang 						dpaa2_q->cgid, &taildrop);
7564418919fSjohnjiang 		} else {
7574418919fSjohnjiang 			/*enabling per rx queue congestion control */
7584418919fSjohnjiang 			taildrop.threshold = CONG_THRESHOLD_RX_BYTES_Q;
7592bfe3f2eSlogwang 			taildrop.units = DPNI_CONGESTION_UNIT_BYTES;
7602bfe3f2eSlogwang 			taildrop.oal = CONG_RX_OAL;
7614418919fSjohnjiang 			DPAA2_PMD_DEBUG("Enabling Byte based Drop on queue= %d",
7622bfe3f2eSlogwang 					rx_queue_id);
7632bfe3f2eSlogwang 			ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
7642bfe3f2eSlogwang 						DPNI_CP_QUEUE, DPNI_QUEUE_RX,
7654418919fSjohnjiang 						dpaa2_q->tc_index, flow_id,
7664418919fSjohnjiang 						&taildrop);
7674418919fSjohnjiang 		}
7684418919fSjohnjiang 		if (ret) {
7694418919fSjohnjiang 			DPAA2_PMD_ERR("Error in setting taildrop. err=(%d)",
7704418919fSjohnjiang 				      ret);
7714418919fSjohnjiang 			return -1;
7724418919fSjohnjiang 		}
7734418919fSjohnjiang 	} else { /* Disable tail Drop */
7744418919fSjohnjiang 		struct dpni_taildrop taildrop = {0};
7754418919fSjohnjiang 		DPAA2_PMD_INFO("Tail drop is disabled on queue");
7764418919fSjohnjiang 
7774418919fSjohnjiang 		taildrop.enable = 0;
7784418919fSjohnjiang 		if (dpaa2_q->cgid != 0xff) {
7794418919fSjohnjiang 			ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
7804418919fSjohnjiang 					DPNI_CP_CONGESTION_GROUP, DPNI_QUEUE_RX,
7814418919fSjohnjiang 					dpaa2_q->tc_index,
7820c6bd470Sfengbojiang 					dpaa2_q->cgid, &taildrop);
7834418919fSjohnjiang 		} else {
7844418919fSjohnjiang 			ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
7854418919fSjohnjiang 					DPNI_CP_QUEUE, DPNI_QUEUE_RX,
7862bfe3f2eSlogwang 					dpaa2_q->tc_index, flow_id, &taildrop);
7874418919fSjohnjiang 		}
7882bfe3f2eSlogwang 		if (ret) {
789d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Error in setting taildrop. err=(%d)",
790d30ea906Sjfb8856606 				      ret);
7912bfe3f2eSlogwang 			return -1;
7922bfe3f2eSlogwang 		}
7932bfe3f2eSlogwang 	}
7942bfe3f2eSlogwang 
7952bfe3f2eSlogwang 	dev->data->rx_queues[rx_queue_id] = dpaa2_q;
7962bfe3f2eSlogwang 	return 0;
7972bfe3f2eSlogwang }
7982bfe3f2eSlogwang 
7992bfe3f2eSlogwang static int
dpaa2_dev_tx_queue_setup(struct rte_eth_dev * dev,uint16_t tx_queue_id,uint16_t nb_tx_desc,unsigned int socket_id __rte_unused,const struct rte_eth_txconf * tx_conf)8002bfe3f2eSlogwang dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,
8012bfe3f2eSlogwang 			 uint16_t tx_queue_id,
802*2d9fd380Sjfb8856606 			 uint16_t nb_tx_desc,
8032bfe3f2eSlogwang 			 unsigned int socket_id __rte_unused,
804*2d9fd380Sjfb8856606 			 const struct rte_eth_txconf *tx_conf)
8052bfe3f2eSlogwang {
8062bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
8072bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)
8082bfe3f2eSlogwang 		priv->tx_vq[tx_queue_id];
8094418919fSjohnjiang 	struct dpaa2_queue *dpaa2_tx_conf_q = (struct dpaa2_queue *)
8104418919fSjohnjiang 		priv->tx_conf_vq[tx_queue_id];
8114418919fSjohnjiang 	struct fsl_mc_io *dpni = dev->process_private;
8122bfe3f2eSlogwang 	struct dpni_queue tx_conf_cfg;
8132bfe3f2eSlogwang 	struct dpni_queue tx_flow_cfg;
8142bfe3f2eSlogwang 	uint8_t options = 0, flow_id;
8154418919fSjohnjiang 	struct dpni_queue_id qid;
8162bfe3f2eSlogwang 	uint32_t tc_id;
8172bfe3f2eSlogwang 	int ret;
8182bfe3f2eSlogwang 
8192bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
8202bfe3f2eSlogwang 
821*2d9fd380Sjfb8856606 	/* Tx deferred start is not supported */
822*2d9fd380Sjfb8856606 	if (tx_conf->tx_deferred_start) {
823*2d9fd380Sjfb8856606 		DPAA2_PMD_ERR("%p:Tx deferred start not supported",
824*2d9fd380Sjfb8856606 				(void *)dev);
825*2d9fd380Sjfb8856606 		return -EINVAL;
826*2d9fd380Sjfb8856606 	}
827*2d9fd380Sjfb8856606 
828*2d9fd380Sjfb8856606 	dpaa2_q->nb_desc = UINT16_MAX;
829*2d9fd380Sjfb8856606 	dpaa2_q->offloads = tx_conf->offloads;
830*2d9fd380Sjfb8856606 
8312bfe3f2eSlogwang 	/* Return if queue already configured */
8322bfe3f2eSlogwang 	if (dpaa2_q->flow_id != 0xffff) {
8332bfe3f2eSlogwang 		dev->data->tx_queues[tx_queue_id] = dpaa2_q;
8342bfe3f2eSlogwang 		return 0;
8352bfe3f2eSlogwang 	}
8362bfe3f2eSlogwang 
8372bfe3f2eSlogwang 	memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));
8382bfe3f2eSlogwang 	memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
8392bfe3f2eSlogwang 
8402bfe3f2eSlogwang 	tc_id = tx_queue_id;
8412bfe3f2eSlogwang 	flow_id = 0;
8422bfe3f2eSlogwang 
8432bfe3f2eSlogwang 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
8442bfe3f2eSlogwang 			tc_id, flow_id, options, &tx_flow_cfg);
8452bfe3f2eSlogwang 	if (ret) {
846d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error in setting the tx flow: "
847d30ea906Sjfb8856606 			"tc_id=%d, flow=%d err=%d",
848d30ea906Sjfb8856606 			tc_id, flow_id, ret);
8492bfe3f2eSlogwang 			return -1;
8502bfe3f2eSlogwang 	}
8512bfe3f2eSlogwang 
8522bfe3f2eSlogwang 	dpaa2_q->flow_id = flow_id;
8532bfe3f2eSlogwang 
8542bfe3f2eSlogwang 	if (tx_queue_id == 0) {
8552bfe3f2eSlogwang 		/*Set tx-conf and error configuration*/
8564418919fSjohnjiang 		if (priv->tx_conf_en)
8574418919fSjohnjiang 			ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW,
8584418919fSjohnjiang 							    priv->token,
8594418919fSjohnjiang 							    DPNI_CONF_AFFINE);
8604418919fSjohnjiang 		else
8612bfe3f2eSlogwang 			ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW,
8622bfe3f2eSlogwang 							    priv->token,
8632bfe3f2eSlogwang 							    DPNI_CONF_DISABLE);
8642bfe3f2eSlogwang 		if (ret) {
865d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Error in set tx conf mode settings: "
866d30ea906Sjfb8856606 				      "err=%d", ret);
8672bfe3f2eSlogwang 			return -1;
8682bfe3f2eSlogwang 		}
8692bfe3f2eSlogwang 	}
8702bfe3f2eSlogwang 	dpaa2_q->tc_index = tc_id;
8712bfe3f2eSlogwang 
8724418919fSjohnjiang 	ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
8734418919fSjohnjiang 			     DPNI_QUEUE_TX, dpaa2_q->tc_index,
8744418919fSjohnjiang 			     dpaa2_q->flow_id, &tx_flow_cfg, &qid);
8754418919fSjohnjiang 	if (ret) {
8764418919fSjohnjiang 		DPAA2_PMD_ERR("Error in getting LFQID err=%d", ret);
8774418919fSjohnjiang 		return -1;
8784418919fSjohnjiang 	}
8794418919fSjohnjiang 	dpaa2_q->fqid = qid.fqid;
8804418919fSjohnjiang 
8812bfe3f2eSlogwang 	if (!(priv->flags & DPAA2_TX_CGR_OFF)) {
8824418919fSjohnjiang 		struct dpni_congestion_notification_cfg cong_notif_cfg = {0};
8832bfe3f2eSlogwang 
884*2d9fd380Sjfb8856606 		dpaa2_q->nb_desc = nb_tx_desc;
885*2d9fd380Sjfb8856606 
8862bfe3f2eSlogwang 		cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES;
887*2d9fd380Sjfb8856606 		cong_notif_cfg.threshold_entry = nb_tx_desc;
8882bfe3f2eSlogwang 		/* Notify that the queue is not congested when the data in
8892bfe3f2eSlogwang 		 * the queue is below this thershold.
8902bfe3f2eSlogwang 		 */
891*2d9fd380Sjfb8856606 		cong_notif_cfg.threshold_exit = nb_tx_desc - 24;
8922bfe3f2eSlogwang 		cong_notif_cfg.message_ctx = 0;
893d30ea906Sjfb8856606 		cong_notif_cfg.message_iova =
894d30ea906Sjfb8856606 				(size_t)DPAA2_VADDR_TO_IOVA(dpaa2_q->cscn);
8952bfe3f2eSlogwang 		cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE;
8962bfe3f2eSlogwang 		cong_notif_cfg.notification_mode =
8972bfe3f2eSlogwang 					 DPNI_CONG_OPT_WRITE_MEM_ON_ENTER |
8982bfe3f2eSlogwang 					 DPNI_CONG_OPT_WRITE_MEM_ON_EXIT |
8992bfe3f2eSlogwang 					 DPNI_CONG_OPT_COHERENT_WRITE;
9004418919fSjohnjiang 		cong_notif_cfg.cg_point = DPNI_CP_QUEUE;
9012bfe3f2eSlogwang 
9022bfe3f2eSlogwang 		ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW,
9032bfe3f2eSlogwang 						       priv->token,
9042bfe3f2eSlogwang 						       DPNI_QUEUE_TX,
9052bfe3f2eSlogwang 						       tc_id,
9062bfe3f2eSlogwang 						       &cong_notif_cfg);
9072bfe3f2eSlogwang 		if (ret) {
908d30ea906Sjfb8856606 			DPAA2_PMD_ERR(
909d30ea906Sjfb8856606 			   "Error in setting tx congestion notification: "
910d30ea906Sjfb8856606 			   "err=%d", ret);
9112bfe3f2eSlogwang 			return -ret;
9122bfe3f2eSlogwang 		}
9132bfe3f2eSlogwang 	}
9144418919fSjohnjiang 	dpaa2_q->cb_eqresp_free = dpaa2_dev_free_eqresp_buf;
9152bfe3f2eSlogwang 	dev->data->tx_queues[tx_queue_id] = dpaa2_q;
9164418919fSjohnjiang 
9174418919fSjohnjiang 	if (priv->tx_conf_en) {
9184418919fSjohnjiang 		dpaa2_q->tx_conf_queue = dpaa2_tx_conf_q;
9194418919fSjohnjiang 		options = options | DPNI_QUEUE_OPT_USER_CTX;
9204418919fSjohnjiang 		tx_conf_cfg.user_context = (size_t)(dpaa2_q);
9214418919fSjohnjiang 		ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token,
9224418919fSjohnjiang 			     DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index,
9234418919fSjohnjiang 			     dpaa2_tx_conf_q->flow_id, options, &tx_conf_cfg);
9244418919fSjohnjiang 		if (ret) {
9254418919fSjohnjiang 			DPAA2_PMD_ERR("Error in setting the tx conf flow: "
9264418919fSjohnjiang 			      "tc_index=%d, flow=%d err=%d",
9274418919fSjohnjiang 			      dpaa2_tx_conf_q->tc_index,
9284418919fSjohnjiang 			      dpaa2_tx_conf_q->flow_id, ret);
9294418919fSjohnjiang 			return -1;
9304418919fSjohnjiang 		}
9314418919fSjohnjiang 
9324418919fSjohnjiang 		ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
9334418919fSjohnjiang 			     DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index,
9344418919fSjohnjiang 			     dpaa2_tx_conf_q->flow_id, &tx_conf_cfg, &qid);
9354418919fSjohnjiang 		if (ret) {
9364418919fSjohnjiang 			DPAA2_PMD_ERR("Error in getting LFQID err=%d", ret);
9374418919fSjohnjiang 			return -1;
9384418919fSjohnjiang 		}
9394418919fSjohnjiang 		dpaa2_tx_conf_q->fqid = qid.fqid;
9404418919fSjohnjiang 	}
9412bfe3f2eSlogwang 	return 0;
9422bfe3f2eSlogwang }
9432bfe3f2eSlogwang 
9442bfe3f2eSlogwang static void
dpaa2_dev_rx_queue_release(void * q __rte_unused)9452bfe3f2eSlogwang dpaa2_dev_rx_queue_release(void *q __rte_unused)
9462bfe3f2eSlogwang {
9474418919fSjohnjiang 	struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)q;
9484418919fSjohnjiang 	struct dpaa2_dev_priv *priv = dpaa2_q->eth_data->dev_private;
9494418919fSjohnjiang 	struct fsl_mc_io *dpni =
9504418919fSjohnjiang 		(struct fsl_mc_io *)priv->eth_dev->process_private;
9514418919fSjohnjiang 	uint8_t options = 0;
9524418919fSjohnjiang 	int ret;
9534418919fSjohnjiang 	struct dpni_queue cfg;
9544418919fSjohnjiang 
9554418919fSjohnjiang 	memset(&cfg, 0, sizeof(struct dpni_queue));
9562bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
9574418919fSjohnjiang 	if (dpaa2_q->cgid != 0xff) {
9584418919fSjohnjiang 		options = DPNI_QUEUE_OPT_CLEAR_CGID;
9594418919fSjohnjiang 		cfg.cgid = dpaa2_q->cgid;
9604418919fSjohnjiang 
9614418919fSjohnjiang 		ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token,
9624418919fSjohnjiang 				     DPNI_QUEUE_RX,
9634418919fSjohnjiang 				     dpaa2_q->tc_index, dpaa2_q->flow_id,
9644418919fSjohnjiang 				     options, &cfg);
9654418919fSjohnjiang 		if (ret)
9664418919fSjohnjiang 			DPAA2_PMD_ERR("Unable to clear CGR from q=%u err=%d",
9674418919fSjohnjiang 					dpaa2_q->fqid, ret);
9684418919fSjohnjiang 		priv->cgid_in_use[dpaa2_q->cgid] = 0;
9694418919fSjohnjiang 		dpaa2_q->cgid = 0xff;
9704418919fSjohnjiang 	}
9712bfe3f2eSlogwang }
9722bfe3f2eSlogwang 
9732bfe3f2eSlogwang static void
dpaa2_dev_tx_queue_release(void * q __rte_unused)9742bfe3f2eSlogwang dpaa2_dev_tx_queue_release(void *q __rte_unused)
9752bfe3f2eSlogwang {
9762bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
9772bfe3f2eSlogwang }
9782bfe3f2eSlogwang 
979d30ea906Sjfb8856606 static uint32_t
dpaa2_dev_rx_queue_count(struct rte_eth_dev * dev,uint16_t rx_queue_id)980d30ea906Sjfb8856606 dpaa2_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
981d30ea906Sjfb8856606 {
982d30ea906Sjfb8856606 	int32_t ret;
983d30ea906Sjfb8856606 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
984d30ea906Sjfb8856606 	struct dpaa2_queue *dpaa2_q;
985d30ea906Sjfb8856606 	struct qbman_swp *swp;
986d30ea906Sjfb8856606 	struct qbman_fq_query_np_rslt state;
987d30ea906Sjfb8856606 	uint32_t frame_cnt = 0;
988d30ea906Sjfb8856606 
989d30ea906Sjfb8856606 	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
990d30ea906Sjfb8856606 		ret = dpaa2_affine_qbman_swp();
991d30ea906Sjfb8856606 		if (ret) {
992*2d9fd380Sjfb8856606 			DPAA2_PMD_ERR(
993*2d9fd380Sjfb8856606 				"Failed to allocate IO portal, tid: %d\n",
994*2d9fd380Sjfb8856606 				rte_gettid());
995d30ea906Sjfb8856606 			return -EINVAL;
996d30ea906Sjfb8856606 		}
997d30ea906Sjfb8856606 	}
998d30ea906Sjfb8856606 	swp = DPAA2_PER_LCORE_PORTAL;
999d30ea906Sjfb8856606 
1000d30ea906Sjfb8856606 	dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
1001d30ea906Sjfb8856606 
1002d30ea906Sjfb8856606 	if (qbman_fq_query_state(swp, dpaa2_q->fqid, &state) == 0) {
1003d30ea906Sjfb8856606 		frame_cnt = qbman_fq_state_frame_count(&state);
1004*2d9fd380Sjfb8856606 		DPAA2_PMD_DP_DEBUG("RX frame count for q(%d) is %u",
1005d30ea906Sjfb8856606 				rx_queue_id, frame_cnt);
1006d30ea906Sjfb8856606 	}
1007d30ea906Sjfb8856606 	return frame_cnt;
1008d30ea906Sjfb8856606 }
1009d30ea906Sjfb8856606 
10102bfe3f2eSlogwang static const uint32_t *
dpaa2_supported_ptypes_get(struct rte_eth_dev * dev)10112bfe3f2eSlogwang dpaa2_supported_ptypes_get(struct rte_eth_dev *dev)
10122bfe3f2eSlogwang {
10132bfe3f2eSlogwang 	static const uint32_t ptypes[] = {
10142bfe3f2eSlogwang 		/*todo -= add more types */
10152bfe3f2eSlogwang 		RTE_PTYPE_L2_ETHER,
10162bfe3f2eSlogwang 		RTE_PTYPE_L3_IPV4,
10172bfe3f2eSlogwang 		RTE_PTYPE_L3_IPV4_EXT,
10182bfe3f2eSlogwang 		RTE_PTYPE_L3_IPV6,
10192bfe3f2eSlogwang 		RTE_PTYPE_L3_IPV6_EXT,
10202bfe3f2eSlogwang 		RTE_PTYPE_L4_TCP,
10212bfe3f2eSlogwang 		RTE_PTYPE_L4_UDP,
10222bfe3f2eSlogwang 		RTE_PTYPE_L4_SCTP,
10232bfe3f2eSlogwang 		RTE_PTYPE_L4_ICMP,
10242bfe3f2eSlogwang 		RTE_PTYPE_UNKNOWN
10252bfe3f2eSlogwang 	};
10262bfe3f2eSlogwang 
10274418919fSjohnjiang 	if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx ||
10284418919fSjohnjiang 		dev->rx_pkt_burst == dpaa2_dev_rx ||
10294418919fSjohnjiang 		dev->rx_pkt_burst == dpaa2_dev_loopback_rx)
10302bfe3f2eSlogwang 		return ptypes;
10312bfe3f2eSlogwang 	return NULL;
10322bfe3f2eSlogwang }
10332bfe3f2eSlogwang 
10342bfe3f2eSlogwang /**
10352bfe3f2eSlogwang  * Dpaa2 link Interrupt handler
10362bfe3f2eSlogwang  *
10372bfe3f2eSlogwang  * @param param
10382bfe3f2eSlogwang  *  The address of parameter (struct rte_eth_dev *) regsitered before.
10392bfe3f2eSlogwang  *
10402bfe3f2eSlogwang  * @return
10412bfe3f2eSlogwang  *  void
10422bfe3f2eSlogwang  */
10432bfe3f2eSlogwang static void
dpaa2_interrupt_handler(void * param)10442bfe3f2eSlogwang dpaa2_interrupt_handler(void *param)
10452bfe3f2eSlogwang {
10462bfe3f2eSlogwang 	struct rte_eth_dev *dev = param;
10472bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
10484418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
10492bfe3f2eSlogwang 	int ret;
10502bfe3f2eSlogwang 	int irq_index = DPNI_IRQ_INDEX;
10512bfe3f2eSlogwang 	unsigned int status = 0, clear = 0;
10522bfe3f2eSlogwang 
10532bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
10542bfe3f2eSlogwang 
10552bfe3f2eSlogwang 	if (dpni == NULL) {
1056d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
10572bfe3f2eSlogwang 		return;
10582bfe3f2eSlogwang 	}
10592bfe3f2eSlogwang 
10602bfe3f2eSlogwang 	ret = dpni_get_irq_status(dpni, CMD_PRI_LOW, priv->token,
10612bfe3f2eSlogwang 				  irq_index, &status);
10622bfe3f2eSlogwang 	if (unlikely(ret)) {
1063d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Can't get irq status (err %d)", ret);
10642bfe3f2eSlogwang 		clear = 0xffffffff;
10652bfe3f2eSlogwang 		goto out;
10662bfe3f2eSlogwang 	}
10672bfe3f2eSlogwang 
10682bfe3f2eSlogwang 	if (status & DPNI_IRQ_EVENT_LINK_CHANGED) {
10692bfe3f2eSlogwang 		clear = DPNI_IRQ_EVENT_LINK_CHANGED;
10702bfe3f2eSlogwang 		dpaa2_dev_link_update(dev, 0);
10712bfe3f2eSlogwang 		/* calling all the apps registered for link status event */
1072*2d9fd380Sjfb8856606 		rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
10732bfe3f2eSlogwang 	}
10742bfe3f2eSlogwang out:
10752bfe3f2eSlogwang 	ret = dpni_clear_irq_status(dpni, CMD_PRI_LOW, priv->token,
10762bfe3f2eSlogwang 				    irq_index, clear);
10772bfe3f2eSlogwang 	if (unlikely(ret))
1078d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Can't clear irq status (err %d)", ret);
10792bfe3f2eSlogwang }
10802bfe3f2eSlogwang 
10812bfe3f2eSlogwang static int
dpaa2_eth_setup_irqs(struct rte_eth_dev * dev,int enable)10822bfe3f2eSlogwang dpaa2_eth_setup_irqs(struct rte_eth_dev *dev, int enable)
10832bfe3f2eSlogwang {
10842bfe3f2eSlogwang 	int err = 0;
10852bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
10864418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
10872bfe3f2eSlogwang 	int irq_index = DPNI_IRQ_INDEX;
10882bfe3f2eSlogwang 	unsigned int mask = DPNI_IRQ_EVENT_LINK_CHANGED;
10892bfe3f2eSlogwang 
10902bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
10912bfe3f2eSlogwang 
10922bfe3f2eSlogwang 	err = dpni_set_irq_mask(dpni, CMD_PRI_LOW, priv->token,
10932bfe3f2eSlogwang 				irq_index, mask);
10942bfe3f2eSlogwang 	if (err < 0) {
1095d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error: dpni_set_irq_mask():%d (%s)", err,
10962bfe3f2eSlogwang 			      strerror(-err));
10972bfe3f2eSlogwang 		return err;
10982bfe3f2eSlogwang 	}
10992bfe3f2eSlogwang 
11002bfe3f2eSlogwang 	err = dpni_set_irq_enable(dpni, CMD_PRI_LOW, priv->token,
11012bfe3f2eSlogwang 				  irq_index, enable);
11022bfe3f2eSlogwang 	if (err < 0)
1103d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error: dpni_set_irq_enable():%d (%s)", err,
11042bfe3f2eSlogwang 			      strerror(-err));
11052bfe3f2eSlogwang 
11062bfe3f2eSlogwang 	return err;
11072bfe3f2eSlogwang }
11082bfe3f2eSlogwang 
11092bfe3f2eSlogwang static int
dpaa2_dev_start(struct rte_eth_dev * dev)11102bfe3f2eSlogwang dpaa2_dev_start(struct rte_eth_dev *dev)
11112bfe3f2eSlogwang {
11122bfe3f2eSlogwang 	struct rte_device *rdev = dev->device;
11132bfe3f2eSlogwang 	struct rte_dpaa2_device *dpaa2_dev;
11142bfe3f2eSlogwang 	struct rte_eth_dev_data *data = dev->data;
11152bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = data->dev_private;
11164418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
11172bfe3f2eSlogwang 	struct dpni_queue cfg;
11182bfe3f2eSlogwang 	struct dpni_error_cfg	err_cfg;
11192bfe3f2eSlogwang 	uint16_t qdid;
11202bfe3f2eSlogwang 	struct dpni_queue_id qid;
11212bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_q;
11222bfe3f2eSlogwang 	int ret, i;
11232bfe3f2eSlogwang 	struct rte_intr_handle *intr_handle;
11242bfe3f2eSlogwang 
11252bfe3f2eSlogwang 	dpaa2_dev = container_of(rdev, struct rte_dpaa2_device, device);
11262bfe3f2eSlogwang 	intr_handle = &dpaa2_dev->intr_handle;
11272bfe3f2eSlogwang 
11282bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
11292bfe3f2eSlogwang 
11302bfe3f2eSlogwang 	ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
11312bfe3f2eSlogwang 	if (ret) {
1132d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Failure in enabling dpni %d device: err=%d",
1133d30ea906Sjfb8856606 			      priv->hw_id, ret);
11342bfe3f2eSlogwang 		return ret;
11352bfe3f2eSlogwang 	}
11362bfe3f2eSlogwang 
11372bfe3f2eSlogwang 	/* Power up the phy. Needed to make the link go UP */
11382bfe3f2eSlogwang 	dpaa2_dev_set_link_up(dev);
11392bfe3f2eSlogwang 
11402bfe3f2eSlogwang 	ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token,
11412bfe3f2eSlogwang 			    DPNI_QUEUE_TX, &qdid);
11422bfe3f2eSlogwang 	if (ret) {
1143d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error in getting qdid: err=%d", ret);
11442bfe3f2eSlogwang 		return ret;
11452bfe3f2eSlogwang 	}
11462bfe3f2eSlogwang 	priv->qdid = qdid;
11472bfe3f2eSlogwang 
11482bfe3f2eSlogwang 	for (i = 0; i < data->nb_rx_queues; i++) {
11492bfe3f2eSlogwang 		dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i];
11502bfe3f2eSlogwang 		ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
11512bfe3f2eSlogwang 				     DPNI_QUEUE_RX, dpaa2_q->tc_index,
11522bfe3f2eSlogwang 				       dpaa2_q->flow_id, &cfg, &qid);
11532bfe3f2eSlogwang 		if (ret) {
1154d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Error in getting flow information: "
1155d30ea906Sjfb8856606 				      "err=%d", ret);
11562bfe3f2eSlogwang 			return ret;
11572bfe3f2eSlogwang 		}
11582bfe3f2eSlogwang 		dpaa2_q->fqid = qid.fqid;
11592bfe3f2eSlogwang 	}
11602bfe3f2eSlogwang 
11612bfe3f2eSlogwang 	/*checksum errors, send them to normal path and set it in annotation */
11622bfe3f2eSlogwang 	err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE;
11634418919fSjohnjiang 	err_cfg.errors |= DPNI_ERROR_PHE;
11642bfe3f2eSlogwang 
11652bfe3f2eSlogwang 	err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE;
11662bfe3f2eSlogwang 	err_cfg.set_frame_annotation = true;
11672bfe3f2eSlogwang 
11682bfe3f2eSlogwang 	ret = dpni_set_errors_behavior(dpni, CMD_PRI_LOW,
11692bfe3f2eSlogwang 				       priv->token, &err_cfg);
11702bfe3f2eSlogwang 	if (ret) {
1171d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error to dpni_set_errors_behavior: code = %d",
1172d30ea906Sjfb8856606 			      ret);
11732bfe3f2eSlogwang 		return ret;
11742bfe3f2eSlogwang 	}
11752bfe3f2eSlogwang 
11762bfe3f2eSlogwang 	/* if the interrupts were configured on this devices*/
11772bfe3f2eSlogwang 	if (intr_handle && (intr_handle->fd) &&
11782bfe3f2eSlogwang 	    (dev->data->dev_conf.intr_conf.lsc != 0)) {
11792bfe3f2eSlogwang 		/* Registering LSC interrupt handler */
11802bfe3f2eSlogwang 		rte_intr_callback_register(intr_handle,
11812bfe3f2eSlogwang 					   dpaa2_interrupt_handler,
11822bfe3f2eSlogwang 					   (void *)dev);
11832bfe3f2eSlogwang 
11842bfe3f2eSlogwang 		/* enable vfio intr/eventfd mapping
11852bfe3f2eSlogwang 		 * Interrupt index 0 is required, so we can not use
11862bfe3f2eSlogwang 		 * rte_intr_enable.
11872bfe3f2eSlogwang 		 */
11882bfe3f2eSlogwang 		rte_dpaa2_intr_enable(intr_handle, DPNI_IRQ_INDEX);
11892bfe3f2eSlogwang 
11902bfe3f2eSlogwang 		/* enable dpni_irqs */
11912bfe3f2eSlogwang 		dpaa2_eth_setup_irqs(dev, 1);
11922bfe3f2eSlogwang 	}
11932bfe3f2eSlogwang 
11944418919fSjohnjiang 	/* Change the tx burst function if ordered queues are used */
11954418919fSjohnjiang 	if (priv->en_ordered)
11964418919fSjohnjiang 		dev->tx_pkt_burst = dpaa2_dev_tx_ordered;
11974418919fSjohnjiang 
11982bfe3f2eSlogwang 	return 0;
11992bfe3f2eSlogwang }
12002bfe3f2eSlogwang 
12012bfe3f2eSlogwang /**
12022bfe3f2eSlogwang  *  This routine disables all traffic on the adapter by issuing a
12032bfe3f2eSlogwang  *  global reset on the MAC.
12042bfe3f2eSlogwang  */
1205*2d9fd380Sjfb8856606 static int
dpaa2_dev_stop(struct rte_eth_dev * dev)12062bfe3f2eSlogwang dpaa2_dev_stop(struct rte_eth_dev *dev)
12072bfe3f2eSlogwang {
12082bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
12094418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
12102bfe3f2eSlogwang 	int ret;
12112bfe3f2eSlogwang 	struct rte_eth_link link;
12122bfe3f2eSlogwang 	struct rte_intr_handle *intr_handle = dev->intr_handle;
12132bfe3f2eSlogwang 
12142bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
12152bfe3f2eSlogwang 
12162bfe3f2eSlogwang 	/* reset interrupt callback  */
12172bfe3f2eSlogwang 	if (intr_handle && (intr_handle->fd) &&
12182bfe3f2eSlogwang 	    (dev->data->dev_conf.intr_conf.lsc != 0)) {
12192bfe3f2eSlogwang 		/*disable dpni irqs */
12202bfe3f2eSlogwang 		dpaa2_eth_setup_irqs(dev, 0);
12212bfe3f2eSlogwang 
12222bfe3f2eSlogwang 		/* disable vfio intr before callback unregister */
12232bfe3f2eSlogwang 		rte_dpaa2_intr_disable(intr_handle, DPNI_IRQ_INDEX);
12242bfe3f2eSlogwang 
12252bfe3f2eSlogwang 		/* Unregistering LSC interrupt handler */
12262bfe3f2eSlogwang 		rte_intr_callback_unregister(intr_handle,
12272bfe3f2eSlogwang 					     dpaa2_interrupt_handler,
12282bfe3f2eSlogwang 					     (void *)dev);
12292bfe3f2eSlogwang 	}
12302bfe3f2eSlogwang 
12312bfe3f2eSlogwang 	dpaa2_dev_set_link_down(dev);
12322bfe3f2eSlogwang 
12332bfe3f2eSlogwang 	ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token);
12342bfe3f2eSlogwang 	if (ret) {
1235d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Failure (ret %d) in disabling dpni %d dev",
12362bfe3f2eSlogwang 			      ret, priv->hw_id);
1237*2d9fd380Sjfb8856606 		return ret;
12382bfe3f2eSlogwang 	}
12392bfe3f2eSlogwang 
12402bfe3f2eSlogwang 	/* clear the recorded link status */
12412bfe3f2eSlogwang 	memset(&link, 0, sizeof(link));
1242d30ea906Sjfb8856606 	rte_eth_linkstatus_set(dev, &link);
1243*2d9fd380Sjfb8856606 
1244*2d9fd380Sjfb8856606 	return 0;
12452bfe3f2eSlogwang }
12462bfe3f2eSlogwang 
1247*2d9fd380Sjfb8856606 static int
dpaa2_dev_close(struct rte_eth_dev * dev)12482bfe3f2eSlogwang dpaa2_dev_close(struct rte_eth_dev *dev)
12492bfe3f2eSlogwang {
12502bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
12514418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
1252*2d9fd380Sjfb8856606 	int i, ret;
12532bfe3f2eSlogwang 	struct rte_eth_link link;
12542bfe3f2eSlogwang 
12552bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
12562bfe3f2eSlogwang 
1257*2d9fd380Sjfb8856606 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1258*2d9fd380Sjfb8856606 		return 0;
12594418919fSjohnjiang 
1260*2d9fd380Sjfb8856606 	if (!dpni) {
1261*2d9fd380Sjfb8856606 		DPAA2_PMD_WARN("Already closed or not started");
1262*2d9fd380Sjfb8856606 		return -1;
1263*2d9fd380Sjfb8856606 	}
1264*2d9fd380Sjfb8856606 
1265*2d9fd380Sjfb8856606 	dpaa2_flow_clean(dev);
12662bfe3f2eSlogwang 	/* Clean the device first */
12672bfe3f2eSlogwang 	ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token);
12682bfe3f2eSlogwang 	if (ret) {
1269d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Failure cleaning dpni device: err=%d", ret);
1270*2d9fd380Sjfb8856606 		return -1;
12712bfe3f2eSlogwang 	}
12722bfe3f2eSlogwang 
12732bfe3f2eSlogwang 	memset(&link, 0, sizeof(link));
1274d30ea906Sjfb8856606 	rte_eth_linkstatus_set(dev, &link);
1275*2d9fd380Sjfb8856606 
1276*2d9fd380Sjfb8856606 	/* Free private queues memory */
1277*2d9fd380Sjfb8856606 	dpaa2_free_rx_tx_queues(dev);
1278*2d9fd380Sjfb8856606 	/* Close the device at underlying layer*/
1279*2d9fd380Sjfb8856606 	ret = dpni_close(dpni, CMD_PRI_LOW, priv->token);
1280*2d9fd380Sjfb8856606 	if (ret) {
1281*2d9fd380Sjfb8856606 		DPAA2_PMD_ERR("Failure closing dpni device with err code %d",
1282*2d9fd380Sjfb8856606 			      ret);
1283*2d9fd380Sjfb8856606 	}
1284*2d9fd380Sjfb8856606 
1285*2d9fd380Sjfb8856606 	/* Free the allocated memory for ethernet private data and dpni*/
1286*2d9fd380Sjfb8856606 	priv->hw = NULL;
1287*2d9fd380Sjfb8856606 	dev->process_private = NULL;
1288*2d9fd380Sjfb8856606 	rte_free(dpni);
1289*2d9fd380Sjfb8856606 
1290*2d9fd380Sjfb8856606 	for (i = 0; i < MAX_TCS; i++)
1291*2d9fd380Sjfb8856606 		rte_free((void *)(size_t)priv->extract.tc_extract_param[i]);
1292*2d9fd380Sjfb8856606 
1293*2d9fd380Sjfb8856606 	if (priv->extract.qos_extract_param)
1294*2d9fd380Sjfb8856606 		rte_free((void *)(size_t)priv->extract.qos_extract_param);
1295*2d9fd380Sjfb8856606 
1296*2d9fd380Sjfb8856606 	DPAA2_PMD_INFO("%s: netdev deleted", dev->data->name);
1297*2d9fd380Sjfb8856606 	return 0;
12982bfe3f2eSlogwang }
12992bfe3f2eSlogwang 
13004418919fSjohnjiang static int
dpaa2_dev_promiscuous_enable(struct rte_eth_dev * dev)13012bfe3f2eSlogwang dpaa2_dev_promiscuous_enable(
13022bfe3f2eSlogwang 		struct rte_eth_dev *dev)
13032bfe3f2eSlogwang {
13042bfe3f2eSlogwang 	int ret;
13052bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
13064418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
13072bfe3f2eSlogwang 
13082bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
13092bfe3f2eSlogwang 
13102bfe3f2eSlogwang 	if (dpni == NULL) {
1311d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
13124418919fSjohnjiang 		return -ENODEV;
13132bfe3f2eSlogwang 	}
13142bfe3f2eSlogwang 
13152bfe3f2eSlogwang 	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
13162bfe3f2eSlogwang 	if (ret < 0)
1317d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to enable U promisc mode %d", ret);
13182bfe3f2eSlogwang 
13192bfe3f2eSlogwang 	ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
13202bfe3f2eSlogwang 	if (ret < 0)
1321d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to enable M promisc mode %d", ret);
13224418919fSjohnjiang 
13234418919fSjohnjiang 	return ret;
13242bfe3f2eSlogwang }
13252bfe3f2eSlogwang 
13264418919fSjohnjiang static int
dpaa2_dev_promiscuous_disable(struct rte_eth_dev * dev)13272bfe3f2eSlogwang dpaa2_dev_promiscuous_disable(
13282bfe3f2eSlogwang 		struct rte_eth_dev *dev)
13292bfe3f2eSlogwang {
13302bfe3f2eSlogwang 	int ret;
13312bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
13324418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
13332bfe3f2eSlogwang 
13342bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
13352bfe3f2eSlogwang 
13362bfe3f2eSlogwang 	if (dpni == NULL) {
1337d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
13384418919fSjohnjiang 		return -ENODEV;
13392bfe3f2eSlogwang 	}
13402bfe3f2eSlogwang 
13412bfe3f2eSlogwang 	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
13422bfe3f2eSlogwang 	if (ret < 0)
1343d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to disable U promisc mode %d", ret);
13442bfe3f2eSlogwang 
13452bfe3f2eSlogwang 	if (dev->data->all_multicast == 0) {
13462bfe3f2eSlogwang 		ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW,
13472bfe3f2eSlogwang 						 priv->token, false);
13482bfe3f2eSlogwang 		if (ret < 0)
1349d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Unable to disable M promisc mode %d",
13502bfe3f2eSlogwang 				      ret);
13512bfe3f2eSlogwang 	}
13524418919fSjohnjiang 
13534418919fSjohnjiang 	return ret;
13542bfe3f2eSlogwang }
13552bfe3f2eSlogwang 
13564418919fSjohnjiang static int
dpaa2_dev_allmulticast_enable(struct rte_eth_dev * dev)13572bfe3f2eSlogwang dpaa2_dev_allmulticast_enable(
13582bfe3f2eSlogwang 		struct rte_eth_dev *dev)
13592bfe3f2eSlogwang {
13602bfe3f2eSlogwang 	int ret;
13612bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
13624418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
13632bfe3f2eSlogwang 
13642bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
13652bfe3f2eSlogwang 
13662bfe3f2eSlogwang 	if (dpni == NULL) {
1367d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
13684418919fSjohnjiang 		return -ENODEV;
13692bfe3f2eSlogwang 	}
13702bfe3f2eSlogwang 
13712bfe3f2eSlogwang 	ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
13722bfe3f2eSlogwang 	if (ret < 0)
1373d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to enable multicast mode %d", ret);
13744418919fSjohnjiang 
13754418919fSjohnjiang 	return ret;
13762bfe3f2eSlogwang }
13772bfe3f2eSlogwang 
13784418919fSjohnjiang static int
dpaa2_dev_allmulticast_disable(struct rte_eth_dev * dev)13792bfe3f2eSlogwang dpaa2_dev_allmulticast_disable(struct rte_eth_dev *dev)
13802bfe3f2eSlogwang {
13812bfe3f2eSlogwang 	int ret;
13822bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
13834418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
13842bfe3f2eSlogwang 
13852bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
13862bfe3f2eSlogwang 
13872bfe3f2eSlogwang 	if (dpni == NULL) {
1388d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
13894418919fSjohnjiang 		return -ENODEV;
13902bfe3f2eSlogwang 	}
13912bfe3f2eSlogwang 
13922bfe3f2eSlogwang 	/* must remain on for all promiscuous */
13932bfe3f2eSlogwang 	if (dev->data->promiscuous == 1)
13944418919fSjohnjiang 		return 0;
13952bfe3f2eSlogwang 
13962bfe3f2eSlogwang 	ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
13972bfe3f2eSlogwang 	if (ret < 0)
1398d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to disable multicast mode %d", ret);
13994418919fSjohnjiang 
14004418919fSjohnjiang 	return ret;
14012bfe3f2eSlogwang }
14022bfe3f2eSlogwang 
14032bfe3f2eSlogwang static int
dpaa2_dev_mtu_set(struct rte_eth_dev * dev,uint16_t mtu)14042bfe3f2eSlogwang dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
14052bfe3f2eSlogwang {
14062bfe3f2eSlogwang 	int ret;
14072bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
14084418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
14094418919fSjohnjiang 	uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN
1410d30ea906Sjfb8856606 				+ VLAN_TAG_SIZE;
14112bfe3f2eSlogwang 
14122bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
14132bfe3f2eSlogwang 
14142bfe3f2eSlogwang 	if (dpni == NULL) {
1415d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
14162bfe3f2eSlogwang 		return -EINVAL;
14172bfe3f2eSlogwang 	}
14182bfe3f2eSlogwang 
14192bfe3f2eSlogwang 	/* check that mtu is within the allowed range */
14204418919fSjohnjiang 	if (mtu < RTE_ETHER_MIN_MTU || frame_size > DPAA2_MAX_RX_PKT_LEN)
14212bfe3f2eSlogwang 		return -EINVAL;
14222bfe3f2eSlogwang 
14234418919fSjohnjiang 	if (frame_size > RTE_ETHER_MAX_LEN)
14244418919fSjohnjiang 		dev->data->dev_conf.rxmode.offloads |=
1425d30ea906Sjfb8856606 						DEV_RX_OFFLOAD_JUMBO_FRAME;
14262bfe3f2eSlogwang 	else
1427d30ea906Sjfb8856606 		dev->data->dev_conf.rxmode.offloads &=
1428d30ea906Sjfb8856606 						~DEV_RX_OFFLOAD_JUMBO_FRAME;
1429d30ea906Sjfb8856606 
1430d30ea906Sjfb8856606 	dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
14312bfe3f2eSlogwang 
14322bfe3f2eSlogwang 	/* Set the Max Rx frame length as 'mtu' +
14332bfe3f2eSlogwang 	 * Maximum Ethernet header length
14342bfe3f2eSlogwang 	 */
14352bfe3f2eSlogwang 	ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token,
14364418919fSjohnjiang 					frame_size - RTE_ETHER_CRC_LEN);
14372bfe3f2eSlogwang 	if (ret) {
1438d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Setting the max frame length failed");
14392bfe3f2eSlogwang 		return -1;
14402bfe3f2eSlogwang 	}
1441d30ea906Sjfb8856606 	DPAA2_PMD_INFO("MTU configured for the device: %d", mtu);
14422bfe3f2eSlogwang 	return 0;
14432bfe3f2eSlogwang }
14442bfe3f2eSlogwang 
14452bfe3f2eSlogwang static int
dpaa2_dev_add_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * addr,__rte_unused uint32_t index,__rte_unused uint32_t pool)14462bfe3f2eSlogwang dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev,
14474418919fSjohnjiang 		       struct rte_ether_addr *addr,
14482bfe3f2eSlogwang 		       __rte_unused uint32_t index,
14492bfe3f2eSlogwang 		       __rte_unused uint32_t pool)
14502bfe3f2eSlogwang {
14512bfe3f2eSlogwang 	int ret;
14522bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
14534418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
14542bfe3f2eSlogwang 
14552bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
14562bfe3f2eSlogwang 
14572bfe3f2eSlogwang 	if (dpni == NULL) {
1458d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
14592bfe3f2eSlogwang 		return -1;
14602bfe3f2eSlogwang 	}
14612bfe3f2eSlogwang 
14624418919fSjohnjiang 	ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW, priv->token,
14634418919fSjohnjiang 				addr->addr_bytes, 0, 0, 0);
14642bfe3f2eSlogwang 	if (ret)
1465d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
1466d30ea906Sjfb8856606 			"error: Adding the MAC ADDR failed: err = %d", ret);
14672bfe3f2eSlogwang 	return 0;
14682bfe3f2eSlogwang }
14692bfe3f2eSlogwang 
14702bfe3f2eSlogwang static void
dpaa2_dev_remove_mac_addr(struct rte_eth_dev * dev,uint32_t index)14712bfe3f2eSlogwang dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
14722bfe3f2eSlogwang 			  uint32_t index)
14732bfe3f2eSlogwang {
14742bfe3f2eSlogwang 	int ret;
14752bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
14764418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
14772bfe3f2eSlogwang 	struct rte_eth_dev_data *data = dev->data;
14784418919fSjohnjiang 	struct rte_ether_addr *macaddr;
14792bfe3f2eSlogwang 
14802bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
14812bfe3f2eSlogwang 
14822bfe3f2eSlogwang 	macaddr = &data->mac_addrs[index];
14832bfe3f2eSlogwang 
14842bfe3f2eSlogwang 	if (dpni == NULL) {
1485d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
14862bfe3f2eSlogwang 		return;
14872bfe3f2eSlogwang 	}
14882bfe3f2eSlogwang 
14892bfe3f2eSlogwang 	ret = dpni_remove_mac_addr(dpni, CMD_PRI_LOW,
14902bfe3f2eSlogwang 				   priv->token, macaddr->addr_bytes);
14912bfe3f2eSlogwang 	if (ret)
1492d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
1493d30ea906Sjfb8856606 			"error: Removing the MAC ADDR failed: err = %d", ret);
14942bfe3f2eSlogwang }
14952bfe3f2eSlogwang 
1496d30ea906Sjfb8856606 static int
dpaa2_dev_set_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * addr)14972bfe3f2eSlogwang dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
14984418919fSjohnjiang 		       struct rte_ether_addr *addr)
14992bfe3f2eSlogwang {
15002bfe3f2eSlogwang 	int ret;
15012bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
15024418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
15032bfe3f2eSlogwang 
15042bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
15052bfe3f2eSlogwang 
15062bfe3f2eSlogwang 	if (dpni == NULL) {
1507d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
1508d30ea906Sjfb8856606 		return -EINVAL;
15092bfe3f2eSlogwang 	}
15102bfe3f2eSlogwang 
15112bfe3f2eSlogwang 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
15122bfe3f2eSlogwang 					priv->token, addr->addr_bytes);
15132bfe3f2eSlogwang 
15142bfe3f2eSlogwang 	if (ret)
1515d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
1516d30ea906Sjfb8856606 			"error: Setting the MAC ADDR failed %d", ret);
1517d30ea906Sjfb8856606 
1518d30ea906Sjfb8856606 	return ret;
15192bfe3f2eSlogwang }
1520d30ea906Sjfb8856606 
15212bfe3f2eSlogwang static
dpaa2_dev_stats_get(struct rte_eth_dev * dev,struct rte_eth_stats * stats)15222bfe3f2eSlogwang int dpaa2_dev_stats_get(struct rte_eth_dev *dev,
15232bfe3f2eSlogwang 			 struct rte_eth_stats *stats)
15242bfe3f2eSlogwang {
15252bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
15264418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
15272bfe3f2eSlogwang 	int32_t  retcode;
15282bfe3f2eSlogwang 	uint8_t page0 = 0, page1 = 1, page2 = 2;
15292bfe3f2eSlogwang 	union dpni_statistics value;
1530d30ea906Sjfb8856606 	int i;
1531d30ea906Sjfb8856606 	struct dpaa2_queue *dpaa2_rxq, *dpaa2_txq;
15322bfe3f2eSlogwang 
15332bfe3f2eSlogwang 	memset(&value, 0, sizeof(union dpni_statistics));
15342bfe3f2eSlogwang 
15352bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
15362bfe3f2eSlogwang 
15372bfe3f2eSlogwang 	if (!dpni) {
1538d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
15392bfe3f2eSlogwang 		return -EINVAL;
15402bfe3f2eSlogwang 	}
15412bfe3f2eSlogwang 
15422bfe3f2eSlogwang 	if (!stats) {
1543d30ea906Sjfb8856606 		DPAA2_PMD_ERR("stats is NULL");
15442bfe3f2eSlogwang 		return -EINVAL;
15452bfe3f2eSlogwang 	}
15462bfe3f2eSlogwang 
15472bfe3f2eSlogwang 	/*Get Counters from page_0*/
15482bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
15492bfe3f2eSlogwang 				      page0, 0, &value);
15502bfe3f2eSlogwang 	if (retcode)
15512bfe3f2eSlogwang 		goto err;
15522bfe3f2eSlogwang 
15532bfe3f2eSlogwang 	stats->ipackets = value.page_0.ingress_all_frames;
15542bfe3f2eSlogwang 	stats->ibytes = value.page_0.ingress_all_bytes;
15552bfe3f2eSlogwang 
15562bfe3f2eSlogwang 	/*Get Counters from page_1*/
15572bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
15582bfe3f2eSlogwang 				      page1, 0, &value);
15592bfe3f2eSlogwang 	if (retcode)
15602bfe3f2eSlogwang 		goto err;
15612bfe3f2eSlogwang 
15622bfe3f2eSlogwang 	stats->opackets = value.page_1.egress_all_frames;
15632bfe3f2eSlogwang 	stats->obytes = value.page_1.egress_all_bytes;
15642bfe3f2eSlogwang 
15652bfe3f2eSlogwang 	/*Get Counters from page_2*/
15662bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
15672bfe3f2eSlogwang 				      page2, 0, &value);
15682bfe3f2eSlogwang 	if (retcode)
15692bfe3f2eSlogwang 		goto err;
15702bfe3f2eSlogwang 
15712bfe3f2eSlogwang 	/* Ingress drop frame count due to configured rules */
15722bfe3f2eSlogwang 	stats->ierrors = value.page_2.ingress_filtered_frames;
15732bfe3f2eSlogwang 	/* Ingress drop frame count due to error */
15742bfe3f2eSlogwang 	stats->ierrors += value.page_2.ingress_discarded_frames;
15752bfe3f2eSlogwang 
15762bfe3f2eSlogwang 	stats->oerrors = value.page_2.egress_discarded_frames;
15772bfe3f2eSlogwang 	stats->imissed = value.page_2.ingress_nobuffer_discards;
15782bfe3f2eSlogwang 
1579d30ea906Sjfb8856606 	/* Fill in per queue stats */
1580d30ea906Sjfb8856606 	for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
1581d30ea906Sjfb8856606 		(i < priv->nb_rx_queues || i < priv->nb_tx_queues); ++i) {
1582d30ea906Sjfb8856606 		dpaa2_rxq = (struct dpaa2_queue *)priv->rx_vq[i];
1583d30ea906Sjfb8856606 		dpaa2_txq = (struct dpaa2_queue *)priv->tx_vq[i];
1584d30ea906Sjfb8856606 		if (dpaa2_rxq)
1585d30ea906Sjfb8856606 			stats->q_ipackets[i] = dpaa2_rxq->rx_pkts;
1586d30ea906Sjfb8856606 		if (dpaa2_txq)
1587d30ea906Sjfb8856606 			stats->q_opackets[i] = dpaa2_txq->tx_pkts;
1588d30ea906Sjfb8856606 
1589d30ea906Sjfb8856606 		/* Byte counting is not implemented */
1590d30ea906Sjfb8856606 		stats->q_ibytes[i]   = 0;
1591d30ea906Sjfb8856606 		stats->q_obytes[i]   = 0;
1592d30ea906Sjfb8856606 	}
1593d30ea906Sjfb8856606 
15942bfe3f2eSlogwang 	return 0;
15952bfe3f2eSlogwang 
15962bfe3f2eSlogwang err:
1597d30ea906Sjfb8856606 	DPAA2_PMD_ERR("Operation not completed:Error Code = %d", retcode);
15982bfe3f2eSlogwang 	return retcode;
15992bfe3f2eSlogwang };
16002bfe3f2eSlogwang 
16012bfe3f2eSlogwang static int
dpaa2_dev_xstats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,unsigned int n)16022bfe3f2eSlogwang dpaa2_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
16032bfe3f2eSlogwang 		     unsigned int n)
16042bfe3f2eSlogwang {
16052bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
16064418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
16072bfe3f2eSlogwang 	int32_t  retcode;
16084418919fSjohnjiang 	union dpni_statistics value[5] = {};
16092bfe3f2eSlogwang 	unsigned int i = 0, num = RTE_DIM(dpaa2_xstats_strings);
16102bfe3f2eSlogwang 
16112bfe3f2eSlogwang 	if (n < num)
16122bfe3f2eSlogwang 		return num;
16132bfe3f2eSlogwang 
1614579bf1e2Sjfb8856606 	if (xstats == NULL)
1615579bf1e2Sjfb8856606 		return 0;
1616579bf1e2Sjfb8856606 
16172bfe3f2eSlogwang 	/* Get Counters from page_0*/
16182bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
16192bfe3f2eSlogwang 				      0, 0, &value[0]);
16202bfe3f2eSlogwang 	if (retcode)
16212bfe3f2eSlogwang 		goto err;
16222bfe3f2eSlogwang 
16232bfe3f2eSlogwang 	/* Get Counters from page_1*/
16242bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
16252bfe3f2eSlogwang 				      1, 0, &value[1]);
16262bfe3f2eSlogwang 	if (retcode)
16272bfe3f2eSlogwang 		goto err;
16282bfe3f2eSlogwang 
16292bfe3f2eSlogwang 	/* Get Counters from page_2*/
16302bfe3f2eSlogwang 	retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
16312bfe3f2eSlogwang 				      2, 0, &value[2]);
16322bfe3f2eSlogwang 	if (retcode)
16332bfe3f2eSlogwang 		goto err;
16342bfe3f2eSlogwang 
16354418919fSjohnjiang 	for (i = 0; i < priv->max_cgs; i++) {
16364418919fSjohnjiang 		if (!priv->cgid_in_use[i]) {
16374418919fSjohnjiang 			/* Get Counters from page_4*/
16384418919fSjohnjiang 			retcode = dpni_get_statistics(dpni, CMD_PRI_LOW,
16394418919fSjohnjiang 						      priv->token,
16404418919fSjohnjiang 						      4, 0, &value[4]);
16414418919fSjohnjiang 			if (retcode)
16424418919fSjohnjiang 				goto err;
16434418919fSjohnjiang 			break;
16444418919fSjohnjiang 		}
16454418919fSjohnjiang 	}
16464418919fSjohnjiang 
16472bfe3f2eSlogwang 	for (i = 0; i < num; i++) {
16482bfe3f2eSlogwang 		xstats[i].id = i;
16492bfe3f2eSlogwang 		xstats[i].value = value[dpaa2_xstats_strings[i].page_id].
16502bfe3f2eSlogwang 			raw.counter[dpaa2_xstats_strings[i].stats_id];
16512bfe3f2eSlogwang 	}
16522bfe3f2eSlogwang 	return i;
16532bfe3f2eSlogwang err:
1654d30ea906Sjfb8856606 	DPAA2_PMD_ERR("Error in obtaining extended stats (%d)", retcode);
16552bfe3f2eSlogwang 	return retcode;
16562bfe3f2eSlogwang }
16572bfe3f2eSlogwang 
16582bfe3f2eSlogwang static int
dpaa2_xstats_get_names(__rte_unused struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,unsigned int limit)16592bfe3f2eSlogwang dpaa2_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
16602bfe3f2eSlogwang 		       struct rte_eth_xstat_name *xstats_names,
1661579bf1e2Sjfb8856606 		       unsigned int limit)
16622bfe3f2eSlogwang {
16632bfe3f2eSlogwang 	unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
16642bfe3f2eSlogwang 
1665579bf1e2Sjfb8856606 	if (limit < stat_cnt)
1666579bf1e2Sjfb8856606 		return stat_cnt;
1667579bf1e2Sjfb8856606 
16682bfe3f2eSlogwang 	if (xstats_names != NULL)
16692bfe3f2eSlogwang 		for (i = 0; i < stat_cnt; i++)
16704418919fSjohnjiang 			strlcpy(xstats_names[i].name,
16714418919fSjohnjiang 				dpaa2_xstats_strings[i].name,
16724418919fSjohnjiang 				sizeof(xstats_names[i].name));
16732bfe3f2eSlogwang 
16742bfe3f2eSlogwang 	return stat_cnt;
16752bfe3f2eSlogwang }
16762bfe3f2eSlogwang 
16772bfe3f2eSlogwang static int
dpaa2_xstats_get_by_id(struct rte_eth_dev * dev,const uint64_t * ids,uint64_t * values,unsigned int n)16782bfe3f2eSlogwang dpaa2_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
16792bfe3f2eSlogwang 		       uint64_t *values, unsigned int n)
16802bfe3f2eSlogwang {
16812bfe3f2eSlogwang 	unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
16822bfe3f2eSlogwang 	uint64_t values_copy[stat_cnt];
16832bfe3f2eSlogwang 
16842bfe3f2eSlogwang 	if (!ids) {
16852bfe3f2eSlogwang 		struct dpaa2_dev_priv *priv = dev->data->dev_private;
16864418919fSjohnjiang 		struct fsl_mc_io *dpni =
16874418919fSjohnjiang 			(struct fsl_mc_io *)dev->process_private;
16882bfe3f2eSlogwang 		int32_t  retcode;
16894418919fSjohnjiang 		union dpni_statistics value[5] = {};
16902bfe3f2eSlogwang 
16912bfe3f2eSlogwang 		if (n < stat_cnt)
16922bfe3f2eSlogwang 			return stat_cnt;
16932bfe3f2eSlogwang 
16942bfe3f2eSlogwang 		if (!values)
16952bfe3f2eSlogwang 			return 0;
16962bfe3f2eSlogwang 
16972bfe3f2eSlogwang 		/* Get Counters from page_0*/
16982bfe3f2eSlogwang 		retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
16992bfe3f2eSlogwang 					      0, 0, &value[0]);
17002bfe3f2eSlogwang 		if (retcode)
17012bfe3f2eSlogwang 			return 0;
17022bfe3f2eSlogwang 
17032bfe3f2eSlogwang 		/* Get Counters from page_1*/
17042bfe3f2eSlogwang 		retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
17052bfe3f2eSlogwang 					      1, 0, &value[1]);
17062bfe3f2eSlogwang 		if (retcode)
17072bfe3f2eSlogwang 			return 0;
17082bfe3f2eSlogwang 
17092bfe3f2eSlogwang 		/* Get Counters from page_2*/
17102bfe3f2eSlogwang 		retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
17112bfe3f2eSlogwang 					      2, 0, &value[2]);
17122bfe3f2eSlogwang 		if (retcode)
17132bfe3f2eSlogwang 			return 0;
17142bfe3f2eSlogwang 
17154418919fSjohnjiang 		/* Get Counters from page_4*/
17164418919fSjohnjiang 		retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
17174418919fSjohnjiang 					      4, 0, &value[4]);
17184418919fSjohnjiang 		if (retcode)
17194418919fSjohnjiang 			return 0;
17204418919fSjohnjiang 
17212bfe3f2eSlogwang 		for (i = 0; i < stat_cnt; i++) {
17222bfe3f2eSlogwang 			values[i] = value[dpaa2_xstats_strings[i].page_id].
17232bfe3f2eSlogwang 				raw.counter[dpaa2_xstats_strings[i].stats_id];
17242bfe3f2eSlogwang 		}
17252bfe3f2eSlogwang 		return stat_cnt;
17262bfe3f2eSlogwang 	}
17272bfe3f2eSlogwang 
17282bfe3f2eSlogwang 	dpaa2_xstats_get_by_id(dev, NULL, values_copy, stat_cnt);
17292bfe3f2eSlogwang 
17302bfe3f2eSlogwang 	for (i = 0; i < n; i++) {
17312bfe3f2eSlogwang 		if (ids[i] >= stat_cnt) {
1732d30ea906Sjfb8856606 			DPAA2_PMD_ERR("xstats id value isn't valid");
17332bfe3f2eSlogwang 			return -1;
17342bfe3f2eSlogwang 		}
17352bfe3f2eSlogwang 		values[i] = values_copy[ids[i]];
17362bfe3f2eSlogwang 	}
17372bfe3f2eSlogwang 	return n;
17382bfe3f2eSlogwang }
17392bfe3f2eSlogwang 
17402bfe3f2eSlogwang static int
dpaa2_xstats_get_names_by_id(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,const uint64_t * ids,unsigned int limit)17412bfe3f2eSlogwang dpaa2_xstats_get_names_by_id(
17422bfe3f2eSlogwang 	struct rte_eth_dev *dev,
17432bfe3f2eSlogwang 	struct rte_eth_xstat_name *xstats_names,
17442bfe3f2eSlogwang 	const uint64_t *ids,
17452bfe3f2eSlogwang 	unsigned int limit)
17462bfe3f2eSlogwang {
17472bfe3f2eSlogwang 	unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
17482bfe3f2eSlogwang 	struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
17492bfe3f2eSlogwang 
17502bfe3f2eSlogwang 	if (!ids)
17512bfe3f2eSlogwang 		return dpaa2_xstats_get_names(dev, xstats_names, limit);
17522bfe3f2eSlogwang 
17532bfe3f2eSlogwang 	dpaa2_xstats_get_names(dev, xstats_names_copy, limit);
17542bfe3f2eSlogwang 
17552bfe3f2eSlogwang 	for (i = 0; i < limit; i++) {
17562bfe3f2eSlogwang 		if (ids[i] >= stat_cnt) {
1757d30ea906Sjfb8856606 			DPAA2_PMD_ERR("xstats id value isn't valid");
17582bfe3f2eSlogwang 			return -1;
17592bfe3f2eSlogwang 		}
17602bfe3f2eSlogwang 		strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
17612bfe3f2eSlogwang 	}
17622bfe3f2eSlogwang 	return limit;
17632bfe3f2eSlogwang }
17642bfe3f2eSlogwang 
17654418919fSjohnjiang static int
dpaa2_dev_stats_reset(struct rte_eth_dev * dev)17662bfe3f2eSlogwang dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
17672bfe3f2eSlogwang {
17682bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
17694418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
17704418919fSjohnjiang 	int retcode;
1771d30ea906Sjfb8856606 	int i;
1772d30ea906Sjfb8856606 	struct dpaa2_queue *dpaa2_q;
17732bfe3f2eSlogwang 
17742bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
17752bfe3f2eSlogwang 
17762bfe3f2eSlogwang 	if (dpni == NULL) {
1777d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
17784418919fSjohnjiang 		return -EINVAL;
17792bfe3f2eSlogwang 	}
17802bfe3f2eSlogwang 
17812bfe3f2eSlogwang 	retcode =  dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token);
17822bfe3f2eSlogwang 	if (retcode)
17832bfe3f2eSlogwang 		goto error;
17842bfe3f2eSlogwang 
1785d30ea906Sjfb8856606 	/* Reset the per queue stats in dpaa2_queue structure */
1786d30ea906Sjfb8856606 	for (i = 0; i < priv->nb_rx_queues; i++) {
1787d30ea906Sjfb8856606 		dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
1788d30ea906Sjfb8856606 		if (dpaa2_q)
1789d30ea906Sjfb8856606 			dpaa2_q->rx_pkts = 0;
1790d30ea906Sjfb8856606 	}
1791d30ea906Sjfb8856606 
1792d30ea906Sjfb8856606 	for (i = 0; i < priv->nb_tx_queues; i++) {
1793d30ea906Sjfb8856606 		dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
1794d30ea906Sjfb8856606 		if (dpaa2_q)
1795d30ea906Sjfb8856606 			dpaa2_q->tx_pkts = 0;
1796d30ea906Sjfb8856606 	}
1797d30ea906Sjfb8856606 
17984418919fSjohnjiang 	return 0;
17992bfe3f2eSlogwang 
18002bfe3f2eSlogwang error:
1801d30ea906Sjfb8856606 	DPAA2_PMD_ERR("Operation not completed:Error Code = %d", retcode);
18024418919fSjohnjiang 	return retcode;
18032bfe3f2eSlogwang };
18042bfe3f2eSlogwang 
18052bfe3f2eSlogwang /* return 0 means link status changed, -1 means not changed */
18062bfe3f2eSlogwang static int
dpaa2_dev_link_update(struct rte_eth_dev * dev,int wait_to_complete __rte_unused)18072bfe3f2eSlogwang dpaa2_dev_link_update(struct rte_eth_dev *dev,
18082bfe3f2eSlogwang 			int wait_to_complete __rte_unused)
18092bfe3f2eSlogwang {
18102bfe3f2eSlogwang 	int ret;
18112bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
18124418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
1813d30ea906Sjfb8856606 	struct rte_eth_link link;
18142bfe3f2eSlogwang 	struct dpni_link_state state = {0};
18152bfe3f2eSlogwang 
18162bfe3f2eSlogwang 	if (dpni == NULL) {
1817d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
18182bfe3f2eSlogwang 		return 0;
18192bfe3f2eSlogwang 	}
18202bfe3f2eSlogwang 
18212bfe3f2eSlogwang 	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
18222bfe3f2eSlogwang 	if (ret < 0) {
1823d30ea906Sjfb8856606 		DPAA2_PMD_DEBUG("error: dpni_get_link_state %d", ret);
18242bfe3f2eSlogwang 		return -1;
18252bfe3f2eSlogwang 	}
18262bfe3f2eSlogwang 
18272bfe3f2eSlogwang 	memset(&link, 0, sizeof(struct rte_eth_link));
18282bfe3f2eSlogwang 	link.link_status = state.up;
18292bfe3f2eSlogwang 	link.link_speed = state.rate;
18302bfe3f2eSlogwang 
18312bfe3f2eSlogwang 	if (state.options & DPNI_LINK_OPT_HALF_DUPLEX)
18322bfe3f2eSlogwang 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
18332bfe3f2eSlogwang 	else
18342bfe3f2eSlogwang 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
18352bfe3f2eSlogwang 
1836d30ea906Sjfb8856606 	ret = rte_eth_linkstatus_set(dev, &link);
1837d30ea906Sjfb8856606 	if (ret == -1)
1838d30ea906Sjfb8856606 		DPAA2_PMD_DEBUG("No change in status");
18395af785ecSfengbojiang(姜凤波) 	else
1840d30ea906Sjfb8856606 		DPAA2_PMD_INFO("Port %d Link is %s\n", dev->data->port_id,
1841d30ea906Sjfb8856606 			       link.link_status ? "Up" : "Down");
1842d30ea906Sjfb8856606 
1843d30ea906Sjfb8856606 	return ret;
18442bfe3f2eSlogwang }
18452bfe3f2eSlogwang 
18462bfe3f2eSlogwang /**
18472bfe3f2eSlogwang  * Toggle the DPNI to enable, if not already enabled.
18482bfe3f2eSlogwang  * This is not strictly PHY up/down - it is more of logical toggling.
18492bfe3f2eSlogwang  */
18502bfe3f2eSlogwang static int
dpaa2_dev_set_link_up(struct rte_eth_dev * dev)18512bfe3f2eSlogwang dpaa2_dev_set_link_up(struct rte_eth_dev *dev)
18522bfe3f2eSlogwang {
18532bfe3f2eSlogwang 	int ret = -EINVAL;
18542bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv;
18552bfe3f2eSlogwang 	struct fsl_mc_io *dpni;
18562bfe3f2eSlogwang 	int en = 0;
18572bfe3f2eSlogwang 	struct dpni_link_state state = {0};
18582bfe3f2eSlogwang 
18592bfe3f2eSlogwang 	priv = dev->data->dev_private;
18604418919fSjohnjiang 	dpni = (struct fsl_mc_io *)dev->process_private;
18612bfe3f2eSlogwang 
18622bfe3f2eSlogwang 	if (dpni == NULL) {
1863d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
18642bfe3f2eSlogwang 		return ret;
18652bfe3f2eSlogwang 	}
18662bfe3f2eSlogwang 
18672bfe3f2eSlogwang 	/* Check if DPNI is currently enabled */
18682bfe3f2eSlogwang 	ret = dpni_is_enabled(dpni, CMD_PRI_LOW, priv->token, &en);
18692bfe3f2eSlogwang 	if (ret) {
18702bfe3f2eSlogwang 		/* Unable to obtain dpni status; Not continuing */
1871d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Interface Link UP failed (%d)", ret);
18722bfe3f2eSlogwang 		return -EINVAL;
18732bfe3f2eSlogwang 	}
18742bfe3f2eSlogwang 
18752bfe3f2eSlogwang 	/* Enable link if not already enabled */
18762bfe3f2eSlogwang 	if (!en) {
18772bfe3f2eSlogwang 		ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
18782bfe3f2eSlogwang 		if (ret) {
1879d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Interface Link UP failed (%d)", ret);
18802bfe3f2eSlogwang 			return -EINVAL;
18812bfe3f2eSlogwang 		}
18822bfe3f2eSlogwang 	}
18832bfe3f2eSlogwang 	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
18842bfe3f2eSlogwang 	if (ret < 0) {
1885d30ea906Sjfb8856606 		DPAA2_PMD_DEBUG("Unable to get link state (%d)", ret);
18862bfe3f2eSlogwang 		return -1;
18872bfe3f2eSlogwang 	}
18882bfe3f2eSlogwang 
18892bfe3f2eSlogwang 	/* changing tx burst function to start enqueues */
18902bfe3f2eSlogwang 	dev->tx_pkt_burst = dpaa2_dev_tx;
18912bfe3f2eSlogwang 	dev->data->dev_link.link_status = state.up;
18920c6bd470Sfengbojiang 	dev->data->dev_link.link_speed = state.rate;
18932bfe3f2eSlogwang 
18942bfe3f2eSlogwang 	if (state.up)
1895d30ea906Sjfb8856606 		DPAA2_PMD_INFO("Port %d Link is Up", dev->data->port_id);
18962bfe3f2eSlogwang 	else
1897d30ea906Sjfb8856606 		DPAA2_PMD_INFO("Port %d Link is Down", dev->data->port_id);
18982bfe3f2eSlogwang 	return ret;
18992bfe3f2eSlogwang }
19002bfe3f2eSlogwang 
19012bfe3f2eSlogwang /**
19022bfe3f2eSlogwang  * Toggle the DPNI to disable, if not already disabled.
19032bfe3f2eSlogwang  * This is not strictly PHY up/down - it is more of logical toggling.
19042bfe3f2eSlogwang  */
19052bfe3f2eSlogwang static int
dpaa2_dev_set_link_down(struct rte_eth_dev * dev)19062bfe3f2eSlogwang dpaa2_dev_set_link_down(struct rte_eth_dev *dev)
19072bfe3f2eSlogwang {
19082bfe3f2eSlogwang 	int ret = -EINVAL;
19092bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv;
19102bfe3f2eSlogwang 	struct fsl_mc_io *dpni;
19112bfe3f2eSlogwang 	int dpni_enabled = 0;
19122bfe3f2eSlogwang 	int retries = 10;
19132bfe3f2eSlogwang 
19142bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
19152bfe3f2eSlogwang 
19162bfe3f2eSlogwang 	priv = dev->data->dev_private;
19174418919fSjohnjiang 	dpni = (struct fsl_mc_io *)dev->process_private;
19182bfe3f2eSlogwang 
19192bfe3f2eSlogwang 	if (dpni == NULL) {
1920d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Device has not yet been configured");
19212bfe3f2eSlogwang 		return ret;
19222bfe3f2eSlogwang 	}
19232bfe3f2eSlogwang 
19242bfe3f2eSlogwang 	/*changing  tx burst function to avoid any more enqueues */
19252bfe3f2eSlogwang 	dev->tx_pkt_burst = dummy_dev_tx;
19262bfe3f2eSlogwang 
19272bfe3f2eSlogwang 	/* Loop while dpni_disable() attempts to drain the egress FQs
19282bfe3f2eSlogwang 	 * and confirm them back to us.
19292bfe3f2eSlogwang 	 */
19302bfe3f2eSlogwang 	do {
19312bfe3f2eSlogwang 		ret = dpni_disable(dpni, 0, priv->token);
19322bfe3f2eSlogwang 		if (ret) {
1933d30ea906Sjfb8856606 			DPAA2_PMD_ERR("dpni disable failed (%d)", ret);
19342bfe3f2eSlogwang 			return ret;
19352bfe3f2eSlogwang 		}
19362bfe3f2eSlogwang 		ret = dpni_is_enabled(dpni, 0, priv->token, &dpni_enabled);
19372bfe3f2eSlogwang 		if (ret) {
1938d30ea906Sjfb8856606 			DPAA2_PMD_ERR("dpni enable check failed (%d)", ret);
19392bfe3f2eSlogwang 			return ret;
19402bfe3f2eSlogwang 		}
19412bfe3f2eSlogwang 		if (dpni_enabled)
19422bfe3f2eSlogwang 			/* Allow the MC some slack */
19432bfe3f2eSlogwang 			rte_delay_us(100 * 1000);
19442bfe3f2eSlogwang 	} while (dpni_enabled && --retries);
19452bfe3f2eSlogwang 
19462bfe3f2eSlogwang 	if (!retries) {
1947d30ea906Sjfb8856606 		DPAA2_PMD_WARN("Retry count exceeded disabling dpni");
19482bfe3f2eSlogwang 		/* todo- we may have to manually cleanup queues.
19492bfe3f2eSlogwang 		 */
19502bfe3f2eSlogwang 	} else {
1951d30ea906Sjfb8856606 		DPAA2_PMD_INFO("Port %d Link DOWN successful",
19522bfe3f2eSlogwang 			       dev->data->port_id);
19532bfe3f2eSlogwang 	}
19542bfe3f2eSlogwang 
19552bfe3f2eSlogwang 	dev->data->dev_link.link_status = 0;
19562bfe3f2eSlogwang 
19572bfe3f2eSlogwang 	return ret;
19582bfe3f2eSlogwang }
19592bfe3f2eSlogwang 
19602bfe3f2eSlogwang static int
dpaa2_flow_ctrl_get(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)19612bfe3f2eSlogwang dpaa2_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
19622bfe3f2eSlogwang {
19632bfe3f2eSlogwang 	int ret = -EINVAL;
19642bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv;
19652bfe3f2eSlogwang 	struct fsl_mc_io *dpni;
19662bfe3f2eSlogwang 	struct dpni_link_state state = {0};
19672bfe3f2eSlogwang 
19682bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
19692bfe3f2eSlogwang 
19702bfe3f2eSlogwang 	priv = dev->data->dev_private;
19714418919fSjohnjiang 	dpni = (struct fsl_mc_io *)dev->process_private;
19722bfe3f2eSlogwang 
19732bfe3f2eSlogwang 	if (dpni == NULL || fc_conf == NULL) {
1974d30ea906Sjfb8856606 		DPAA2_PMD_ERR("device not configured");
19752bfe3f2eSlogwang 		return ret;
19762bfe3f2eSlogwang 	}
19772bfe3f2eSlogwang 
19782bfe3f2eSlogwang 	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
19792bfe3f2eSlogwang 	if (ret) {
1980d30ea906Sjfb8856606 		DPAA2_PMD_ERR("error: dpni_get_link_state %d", ret);
19812bfe3f2eSlogwang 		return ret;
19822bfe3f2eSlogwang 	}
19832bfe3f2eSlogwang 
19842bfe3f2eSlogwang 	memset(fc_conf, 0, sizeof(struct rte_eth_fc_conf));
19852bfe3f2eSlogwang 	if (state.options & DPNI_LINK_OPT_PAUSE) {
19862bfe3f2eSlogwang 		/* DPNI_LINK_OPT_PAUSE set
19872bfe3f2eSlogwang 		 *  if ASYM_PAUSE not set,
19882bfe3f2eSlogwang 		 *	RX Side flow control (handle received Pause frame)
19892bfe3f2eSlogwang 		 *	TX side flow control (send Pause frame)
19902bfe3f2eSlogwang 		 *  if ASYM_PAUSE set,
19912bfe3f2eSlogwang 		 *	RX Side flow control (handle received Pause frame)
19922bfe3f2eSlogwang 		 *	No TX side flow control (send Pause frame disabled)
19932bfe3f2eSlogwang 		 */
19942bfe3f2eSlogwang 		if (!(state.options & DPNI_LINK_OPT_ASYM_PAUSE))
19952bfe3f2eSlogwang 			fc_conf->mode = RTE_FC_FULL;
19962bfe3f2eSlogwang 		else
19972bfe3f2eSlogwang 			fc_conf->mode = RTE_FC_RX_PAUSE;
19982bfe3f2eSlogwang 	} else {
19992bfe3f2eSlogwang 		/* DPNI_LINK_OPT_PAUSE not set
20002bfe3f2eSlogwang 		 *  if ASYM_PAUSE set,
20012bfe3f2eSlogwang 		 *	TX side flow control (send Pause frame)
20022bfe3f2eSlogwang 		 *	No RX side flow control (No action on pause frame rx)
20032bfe3f2eSlogwang 		 *  if ASYM_PAUSE not set,
20042bfe3f2eSlogwang 		 *	Flow control disabled
20052bfe3f2eSlogwang 		 */
20062bfe3f2eSlogwang 		if (state.options & DPNI_LINK_OPT_ASYM_PAUSE)
20072bfe3f2eSlogwang 			fc_conf->mode = RTE_FC_TX_PAUSE;
20082bfe3f2eSlogwang 		else
20092bfe3f2eSlogwang 			fc_conf->mode = RTE_FC_NONE;
20102bfe3f2eSlogwang 	}
20112bfe3f2eSlogwang 
20122bfe3f2eSlogwang 	return ret;
20132bfe3f2eSlogwang }
20142bfe3f2eSlogwang 
20152bfe3f2eSlogwang static int
dpaa2_flow_ctrl_set(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)20162bfe3f2eSlogwang dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
20172bfe3f2eSlogwang {
20182bfe3f2eSlogwang 	int ret = -EINVAL;
20192bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv;
20202bfe3f2eSlogwang 	struct fsl_mc_io *dpni;
20212bfe3f2eSlogwang 	struct dpni_link_state state = {0};
20222bfe3f2eSlogwang 	struct dpni_link_cfg cfg = {0};
20232bfe3f2eSlogwang 
20242bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
20252bfe3f2eSlogwang 
20262bfe3f2eSlogwang 	priv = dev->data->dev_private;
20274418919fSjohnjiang 	dpni = (struct fsl_mc_io *)dev->process_private;
20282bfe3f2eSlogwang 
20292bfe3f2eSlogwang 	if (dpni == NULL) {
2030d30ea906Sjfb8856606 		DPAA2_PMD_ERR("dpni is NULL");
20312bfe3f2eSlogwang 		return ret;
20322bfe3f2eSlogwang 	}
20332bfe3f2eSlogwang 
20342bfe3f2eSlogwang 	/* It is necessary to obtain the current state before setting fc_conf
20352bfe3f2eSlogwang 	 * as MC would return error in case rate, autoneg or duplex values are
20362bfe3f2eSlogwang 	 * different.
20372bfe3f2eSlogwang 	 */
20382bfe3f2eSlogwang 	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
20392bfe3f2eSlogwang 	if (ret) {
2040d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to get link state (err=%d)", ret);
20412bfe3f2eSlogwang 		return -1;
20422bfe3f2eSlogwang 	}
20432bfe3f2eSlogwang 
20442bfe3f2eSlogwang 	/* Disable link before setting configuration */
20452bfe3f2eSlogwang 	dpaa2_dev_set_link_down(dev);
20462bfe3f2eSlogwang 
20472bfe3f2eSlogwang 	/* Based on fc_conf, update cfg */
20482bfe3f2eSlogwang 	cfg.rate = state.rate;
20492bfe3f2eSlogwang 	cfg.options = state.options;
20502bfe3f2eSlogwang 
20512bfe3f2eSlogwang 	/* update cfg with fc_conf */
20522bfe3f2eSlogwang 	switch (fc_conf->mode) {
20532bfe3f2eSlogwang 	case RTE_FC_FULL:
20542bfe3f2eSlogwang 		/* Full flow control;
20552bfe3f2eSlogwang 		 * OPT_PAUSE set, ASYM_PAUSE not set
20562bfe3f2eSlogwang 		 */
20572bfe3f2eSlogwang 		cfg.options |= DPNI_LINK_OPT_PAUSE;
20582bfe3f2eSlogwang 		cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
20592bfe3f2eSlogwang 		break;
20602bfe3f2eSlogwang 	case RTE_FC_TX_PAUSE:
20612bfe3f2eSlogwang 		/* Enable RX flow control
20622bfe3f2eSlogwang 		 * OPT_PAUSE not set;
20632bfe3f2eSlogwang 		 * ASYM_PAUSE set;
20642bfe3f2eSlogwang 		 */
20652bfe3f2eSlogwang 		cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE;
20662bfe3f2eSlogwang 		cfg.options &= ~DPNI_LINK_OPT_PAUSE;
20672bfe3f2eSlogwang 		break;
20682bfe3f2eSlogwang 	case RTE_FC_RX_PAUSE:
20692bfe3f2eSlogwang 		/* Enable TX Flow control
20702bfe3f2eSlogwang 		 * OPT_PAUSE set
20712bfe3f2eSlogwang 		 * ASYM_PAUSE set
20722bfe3f2eSlogwang 		 */
20732bfe3f2eSlogwang 		cfg.options |= DPNI_LINK_OPT_PAUSE;
20742bfe3f2eSlogwang 		cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE;
20752bfe3f2eSlogwang 		break;
20762bfe3f2eSlogwang 	case RTE_FC_NONE:
20772bfe3f2eSlogwang 		/* Disable Flow control
20782bfe3f2eSlogwang 		 * OPT_PAUSE not set
20792bfe3f2eSlogwang 		 * ASYM_PAUSE not set
20802bfe3f2eSlogwang 		 */
20812bfe3f2eSlogwang 		cfg.options &= ~DPNI_LINK_OPT_PAUSE;
20822bfe3f2eSlogwang 		cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
20832bfe3f2eSlogwang 		break;
20842bfe3f2eSlogwang 	default:
2085d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Incorrect Flow control flag (%d)",
20862bfe3f2eSlogwang 			      fc_conf->mode);
20872bfe3f2eSlogwang 		return -1;
20882bfe3f2eSlogwang 	}
20892bfe3f2eSlogwang 
20902bfe3f2eSlogwang 	ret = dpni_set_link_cfg(dpni, CMD_PRI_LOW, priv->token, &cfg);
20912bfe3f2eSlogwang 	if (ret)
2092d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to set Link configuration (err=%d)",
20932bfe3f2eSlogwang 			      ret);
20942bfe3f2eSlogwang 
20952bfe3f2eSlogwang 	/* Enable link */
20962bfe3f2eSlogwang 	dpaa2_dev_set_link_up(dev);
20972bfe3f2eSlogwang 
20982bfe3f2eSlogwang 	return ret;
20992bfe3f2eSlogwang }
21002bfe3f2eSlogwang 
21012bfe3f2eSlogwang static int
dpaa2_dev_rss_hash_update(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)21022bfe3f2eSlogwang dpaa2_dev_rss_hash_update(struct rte_eth_dev *dev,
21032bfe3f2eSlogwang 			  struct rte_eth_rss_conf *rss_conf)
21042bfe3f2eSlogwang {
21052bfe3f2eSlogwang 	struct rte_eth_dev_data *data = dev->data;
2106*2d9fd380Sjfb8856606 	struct dpaa2_dev_priv *priv = data->dev_private;
21072bfe3f2eSlogwang 	struct rte_eth_conf *eth_conf = &data->dev_conf;
2108*2d9fd380Sjfb8856606 	int ret, tc_index;
21092bfe3f2eSlogwang 
21102bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
21112bfe3f2eSlogwang 
21122bfe3f2eSlogwang 	if (rss_conf->rss_hf) {
2113*2d9fd380Sjfb8856606 		for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) {
2114*2d9fd380Sjfb8856606 			ret = dpaa2_setup_flow_dist(dev, rss_conf->rss_hf,
2115*2d9fd380Sjfb8856606 				tc_index);
21162bfe3f2eSlogwang 			if (ret) {
2117*2d9fd380Sjfb8856606 				DPAA2_PMD_ERR("Unable to set flow dist on tc%d",
2118*2d9fd380Sjfb8856606 					tc_index);
21192bfe3f2eSlogwang 				return ret;
21202bfe3f2eSlogwang 			}
2121*2d9fd380Sjfb8856606 		}
21222bfe3f2eSlogwang 	} else {
2123*2d9fd380Sjfb8856606 		for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) {
2124*2d9fd380Sjfb8856606 			ret = dpaa2_remove_flow_dist(dev, tc_index);
21252bfe3f2eSlogwang 			if (ret) {
2126*2d9fd380Sjfb8856606 				DPAA2_PMD_ERR(
2127*2d9fd380Sjfb8856606 					"Unable to remove flow dist on tc%d",
2128*2d9fd380Sjfb8856606 					tc_index);
21292bfe3f2eSlogwang 				return ret;
21302bfe3f2eSlogwang 			}
21312bfe3f2eSlogwang 		}
2132*2d9fd380Sjfb8856606 	}
21332bfe3f2eSlogwang 	eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_conf->rss_hf;
21342bfe3f2eSlogwang 	return 0;
21352bfe3f2eSlogwang }
21362bfe3f2eSlogwang 
21372bfe3f2eSlogwang static int
dpaa2_dev_rss_hash_conf_get(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)21382bfe3f2eSlogwang dpaa2_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
21392bfe3f2eSlogwang 			    struct rte_eth_rss_conf *rss_conf)
21402bfe3f2eSlogwang {
21412bfe3f2eSlogwang 	struct rte_eth_dev_data *data = dev->data;
21422bfe3f2eSlogwang 	struct rte_eth_conf *eth_conf = &data->dev_conf;
21432bfe3f2eSlogwang 
21442bfe3f2eSlogwang 	/* dpaa2 does not support rss_key, so length should be 0*/
21452bfe3f2eSlogwang 	rss_conf->rss_key_len = 0;
21462bfe3f2eSlogwang 	rss_conf->rss_hf = eth_conf->rx_adv_conf.rss_conf.rss_hf;
21472bfe3f2eSlogwang 	return 0;
21482bfe3f2eSlogwang }
21492bfe3f2eSlogwang 
dpaa2_eth_eventq_attach(const struct rte_eth_dev * dev,int eth_rx_queue_id,struct dpaa2_dpcon_dev * dpcon,const struct rte_event_eth_rx_adapter_queue_conf * queue_conf)21502bfe3f2eSlogwang int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev,
21512bfe3f2eSlogwang 		int eth_rx_queue_id,
21524418919fSjohnjiang 		struct dpaa2_dpcon_dev *dpcon,
21532bfe3f2eSlogwang 		const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
21542bfe3f2eSlogwang {
21552bfe3f2eSlogwang 	struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
21564418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
21572bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
21582bfe3f2eSlogwang 	uint8_t flow_id = dpaa2_ethq->flow_id;
21592bfe3f2eSlogwang 	struct dpni_queue cfg;
21604418919fSjohnjiang 	uint8_t options, priority;
21612bfe3f2eSlogwang 	int ret;
21622bfe3f2eSlogwang 
21632bfe3f2eSlogwang 	if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL)
21642bfe3f2eSlogwang 		dpaa2_ethq->cb = dpaa2_dev_process_parallel_event;
2165d30ea906Sjfb8856606 	else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC)
2166d30ea906Sjfb8856606 		dpaa2_ethq->cb = dpaa2_dev_process_atomic_event;
21674418919fSjohnjiang 	else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED)
21684418919fSjohnjiang 		dpaa2_ethq->cb = dpaa2_dev_process_ordered_event;
21692bfe3f2eSlogwang 	else
21702bfe3f2eSlogwang 		return -EINVAL;
21712bfe3f2eSlogwang 
21724418919fSjohnjiang 	priority = (RTE_EVENT_DEV_PRIORITY_LOWEST / queue_conf->ev.priority) *
21734418919fSjohnjiang 		   (dpcon->num_priorities - 1);
21744418919fSjohnjiang 
21752bfe3f2eSlogwang 	memset(&cfg, 0, sizeof(struct dpni_queue));
21762bfe3f2eSlogwang 	options = DPNI_QUEUE_OPT_DEST;
21772bfe3f2eSlogwang 	cfg.destination.type = DPNI_DEST_DPCON;
21784418919fSjohnjiang 	cfg.destination.id = dpcon->dpcon_id;
21794418919fSjohnjiang 	cfg.destination.priority = priority;
21802bfe3f2eSlogwang 
2181d30ea906Sjfb8856606 	if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC) {
2182d30ea906Sjfb8856606 		options |= DPNI_QUEUE_OPT_HOLD_ACTIVE;
2183d30ea906Sjfb8856606 		cfg.destination.hold_active = 1;
2184d30ea906Sjfb8856606 	}
2185d30ea906Sjfb8856606 
21864418919fSjohnjiang 	if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED &&
21874418919fSjohnjiang 			!eth_priv->en_ordered) {
21884418919fSjohnjiang 		struct opr_cfg ocfg;
21894418919fSjohnjiang 
21904418919fSjohnjiang 		/* Restoration window size = 256 frames */
21914418919fSjohnjiang 		ocfg.oprrws = 3;
21924418919fSjohnjiang 		/* Restoration window size = 512 frames for LX2 */
21934418919fSjohnjiang 		if (dpaa2_svr_family == SVR_LX2160A)
21944418919fSjohnjiang 			ocfg.oprrws = 4;
21954418919fSjohnjiang 		/* Auto advance NESN window enabled */
21964418919fSjohnjiang 		ocfg.oa = 1;
21974418919fSjohnjiang 		/* Late arrival window size disabled */
21984418919fSjohnjiang 		ocfg.olws = 0;
21994418919fSjohnjiang 		/* ORL resource exhaustaion advance NESN disabled */
22004418919fSjohnjiang 		ocfg.oeane = 0;
22014418919fSjohnjiang 		/* Loose ordering enabled */
22024418919fSjohnjiang 		ocfg.oloe = 1;
22034418919fSjohnjiang 		eth_priv->en_loose_ordered = 1;
22044418919fSjohnjiang 		/* Strict ordering enabled if explicitly set */
22054418919fSjohnjiang 		if (getenv("DPAA2_STRICT_ORDERING_ENABLE")) {
22064418919fSjohnjiang 			ocfg.oloe = 0;
22074418919fSjohnjiang 			eth_priv->en_loose_ordered = 0;
22084418919fSjohnjiang 		}
22094418919fSjohnjiang 
22104418919fSjohnjiang 		ret = dpni_set_opr(dpni, CMD_PRI_LOW, eth_priv->token,
22114418919fSjohnjiang 				   dpaa2_ethq->tc_index, flow_id,
22124418919fSjohnjiang 				   OPR_OPT_CREATE, &ocfg);
22134418919fSjohnjiang 		if (ret) {
22144418919fSjohnjiang 			DPAA2_PMD_ERR("Error setting opr: ret: %d\n", ret);
22154418919fSjohnjiang 			return ret;
22164418919fSjohnjiang 		}
22174418919fSjohnjiang 
22184418919fSjohnjiang 		eth_priv->en_ordered = 1;
22194418919fSjohnjiang 	}
22204418919fSjohnjiang 
22212bfe3f2eSlogwang 	options |= DPNI_QUEUE_OPT_USER_CTX;
2222d30ea906Sjfb8856606 	cfg.user_context = (size_t)(dpaa2_ethq);
22232bfe3f2eSlogwang 
22242bfe3f2eSlogwang 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
22252bfe3f2eSlogwang 			     dpaa2_ethq->tc_index, flow_id, options, &cfg);
22262bfe3f2eSlogwang 	if (ret) {
2227d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error in dpni_set_queue: ret: %d", ret);
22282bfe3f2eSlogwang 		return ret;
22292bfe3f2eSlogwang 	}
22302bfe3f2eSlogwang 
22312bfe3f2eSlogwang 	memcpy(&dpaa2_ethq->ev, &queue_conf->ev, sizeof(struct rte_event));
22322bfe3f2eSlogwang 
22332bfe3f2eSlogwang 	return 0;
22342bfe3f2eSlogwang }
22352bfe3f2eSlogwang 
dpaa2_eth_eventq_detach(const struct rte_eth_dev * dev,int eth_rx_queue_id)22362bfe3f2eSlogwang int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev,
22372bfe3f2eSlogwang 		int eth_rx_queue_id)
22382bfe3f2eSlogwang {
22392bfe3f2eSlogwang 	struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
22404418919fSjohnjiang 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
22412bfe3f2eSlogwang 	struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
22422bfe3f2eSlogwang 	uint8_t flow_id = dpaa2_ethq->flow_id;
22432bfe3f2eSlogwang 	struct dpni_queue cfg;
22442bfe3f2eSlogwang 	uint8_t options;
22452bfe3f2eSlogwang 	int ret;
22462bfe3f2eSlogwang 
22472bfe3f2eSlogwang 	memset(&cfg, 0, sizeof(struct dpni_queue));
22482bfe3f2eSlogwang 	options = DPNI_QUEUE_OPT_DEST;
22492bfe3f2eSlogwang 	cfg.destination.type = DPNI_DEST_NONE;
22502bfe3f2eSlogwang 
22512bfe3f2eSlogwang 	ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
22522bfe3f2eSlogwang 			     dpaa2_ethq->tc_index, flow_id, options, &cfg);
22532bfe3f2eSlogwang 	if (ret)
2254d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error in dpni_set_queue: ret: %d", ret);
22552bfe3f2eSlogwang 
22562bfe3f2eSlogwang 	return ret;
22572bfe3f2eSlogwang }
22582bfe3f2eSlogwang 
22594418919fSjohnjiang static inline int
dpaa2_dev_verify_filter_ops(enum rte_filter_op filter_op)22604418919fSjohnjiang dpaa2_dev_verify_filter_ops(enum rte_filter_op filter_op)
22614418919fSjohnjiang {
22624418919fSjohnjiang 	unsigned int i;
22634418919fSjohnjiang 
22644418919fSjohnjiang 	for (i = 0; i < RTE_DIM(dpaa2_supported_filter_ops); i++) {
22654418919fSjohnjiang 		if (dpaa2_supported_filter_ops[i] == filter_op)
22664418919fSjohnjiang 			return 0;
22674418919fSjohnjiang 	}
22684418919fSjohnjiang 	return -ENOTSUP;
22694418919fSjohnjiang }
22704418919fSjohnjiang 
22714418919fSjohnjiang static int
dpaa2_dev_flow_ctrl(struct rte_eth_dev * dev,enum rte_filter_type filter_type,enum rte_filter_op filter_op,void * arg)22724418919fSjohnjiang dpaa2_dev_flow_ctrl(struct rte_eth_dev *dev,
22734418919fSjohnjiang 		    enum rte_filter_type filter_type,
22744418919fSjohnjiang 				 enum rte_filter_op filter_op,
22754418919fSjohnjiang 				 void *arg)
22764418919fSjohnjiang {
22774418919fSjohnjiang 	int ret = 0;
22784418919fSjohnjiang 
22794418919fSjohnjiang 	if (!dev)
22804418919fSjohnjiang 		return -ENODEV;
22814418919fSjohnjiang 
22824418919fSjohnjiang 	switch (filter_type) {
22834418919fSjohnjiang 	case RTE_ETH_FILTER_GENERIC:
22844418919fSjohnjiang 		if (dpaa2_dev_verify_filter_ops(filter_op) < 0) {
22854418919fSjohnjiang 			ret = -ENOTSUP;
22864418919fSjohnjiang 			break;
22874418919fSjohnjiang 		}
22884418919fSjohnjiang 		*(const void **)arg = &dpaa2_flow_ops;
22894418919fSjohnjiang 		dpaa2_filter_type |= filter_type;
22904418919fSjohnjiang 		break;
22914418919fSjohnjiang 	default:
22924418919fSjohnjiang 		RTE_LOG(ERR, PMD, "Filter type (%d) not supported",
22934418919fSjohnjiang 			filter_type);
22944418919fSjohnjiang 		ret = -ENOTSUP;
22954418919fSjohnjiang 		break;
22964418919fSjohnjiang 	}
22974418919fSjohnjiang 	return ret;
22984418919fSjohnjiang }
22994418919fSjohnjiang 
2300*2d9fd380Sjfb8856606 static void
dpaa2_rxq_info_get(struct rte_eth_dev * dev,uint16_t queue_id,struct rte_eth_rxq_info * qinfo)2301*2d9fd380Sjfb8856606 dpaa2_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2302*2d9fd380Sjfb8856606 	struct rte_eth_rxq_info *qinfo)
2303*2d9fd380Sjfb8856606 {
2304*2d9fd380Sjfb8856606 	struct dpaa2_queue *rxq;
2305*2d9fd380Sjfb8856606 
2306*2d9fd380Sjfb8856606 	rxq = (struct dpaa2_queue *)dev->data->rx_queues[queue_id];
2307*2d9fd380Sjfb8856606 
2308*2d9fd380Sjfb8856606 	qinfo->mp = rxq->mb_pool;
2309*2d9fd380Sjfb8856606 	qinfo->scattered_rx = dev->data->scattered_rx;
2310*2d9fd380Sjfb8856606 	qinfo->nb_desc = rxq->nb_desc;
2311*2d9fd380Sjfb8856606 
2312*2d9fd380Sjfb8856606 	qinfo->conf.rx_free_thresh = 1;
2313*2d9fd380Sjfb8856606 	qinfo->conf.rx_drop_en = 1;
2314*2d9fd380Sjfb8856606 	qinfo->conf.rx_deferred_start = 0;
2315*2d9fd380Sjfb8856606 	qinfo->conf.offloads = rxq->offloads;
2316*2d9fd380Sjfb8856606 }
2317*2d9fd380Sjfb8856606 
2318*2d9fd380Sjfb8856606 static void
dpaa2_txq_info_get(struct rte_eth_dev * dev,uint16_t queue_id,struct rte_eth_txq_info * qinfo)2319*2d9fd380Sjfb8856606 dpaa2_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2320*2d9fd380Sjfb8856606 	struct rte_eth_txq_info *qinfo)
2321*2d9fd380Sjfb8856606 {
2322*2d9fd380Sjfb8856606 	struct dpaa2_queue *txq;
2323*2d9fd380Sjfb8856606 
2324*2d9fd380Sjfb8856606 	txq = dev->data->tx_queues[queue_id];
2325*2d9fd380Sjfb8856606 
2326*2d9fd380Sjfb8856606 	qinfo->nb_desc = txq->nb_desc;
2327*2d9fd380Sjfb8856606 	qinfo->conf.tx_thresh.pthresh = 0;
2328*2d9fd380Sjfb8856606 	qinfo->conf.tx_thresh.hthresh = 0;
2329*2d9fd380Sjfb8856606 	qinfo->conf.tx_thresh.wthresh = 0;
2330*2d9fd380Sjfb8856606 
2331*2d9fd380Sjfb8856606 	qinfo->conf.tx_free_thresh = 0;
2332*2d9fd380Sjfb8856606 	qinfo->conf.tx_rs_thresh = 0;
2333*2d9fd380Sjfb8856606 	qinfo->conf.offloads = txq->offloads;
2334*2d9fd380Sjfb8856606 	qinfo->conf.tx_deferred_start = 0;
2335*2d9fd380Sjfb8856606 }
2336*2d9fd380Sjfb8856606 
23372bfe3f2eSlogwang static struct eth_dev_ops dpaa2_ethdev_ops = {
23382bfe3f2eSlogwang 	.dev_configure	  = dpaa2_eth_dev_configure,
23392bfe3f2eSlogwang 	.dev_start	      = dpaa2_dev_start,
23402bfe3f2eSlogwang 	.dev_stop	      = dpaa2_dev_stop,
23412bfe3f2eSlogwang 	.dev_close	      = dpaa2_dev_close,
23422bfe3f2eSlogwang 	.promiscuous_enable   = dpaa2_dev_promiscuous_enable,
23432bfe3f2eSlogwang 	.promiscuous_disable  = dpaa2_dev_promiscuous_disable,
23442bfe3f2eSlogwang 	.allmulticast_enable  = dpaa2_dev_allmulticast_enable,
23452bfe3f2eSlogwang 	.allmulticast_disable = dpaa2_dev_allmulticast_disable,
23462bfe3f2eSlogwang 	.dev_set_link_up      = dpaa2_dev_set_link_up,
23472bfe3f2eSlogwang 	.dev_set_link_down    = dpaa2_dev_set_link_down,
23482bfe3f2eSlogwang 	.link_update	   = dpaa2_dev_link_update,
23492bfe3f2eSlogwang 	.stats_get	       = dpaa2_dev_stats_get,
23502bfe3f2eSlogwang 	.xstats_get	       = dpaa2_dev_xstats_get,
23512bfe3f2eSlogwang 	.xstats_get_by_id     = dpaa2_xstats_get_by_id,
23522bfe3f2eSlogwang 	.xstats_get_names_by_id = dpaa2_xstats_get_names_by_id,
23532bfe3f2eSlogwang 	.xstats_get_names      = dpaa2_xstats_get_names,
23542bfe3f2eSlogwang 	.stats_reset	   = dpaa2_dev_stats_reset,
23552bfe3f2eSlogwang 	.xstats_reset	      = dpaa2_dev_stats_reset,
23562bfe3f2eSlogwang 	.fw_version_get	   = dpaa2_fw_version_get,
23572bfe3f2eSlogwang 	.dev_infos_get	   = dpaa2_dev_info_get,
23582bfe3f2eSlogwang 	.dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
23592bfe3f2eSlogwang 	.mtu_set           = dpaa2_dev_mtu_set,
23602bfe3f2eSlogwang 	.vlan_filter_set      = dpaa2_vlan_filter_set,
23612bfe3f2eSlogwang 	.vlan_offload_set     = dpaa2_vlan_offload_set,
23624418919fSjohnjiang 	.vlan_tpid_set	      = dpaa2_vlan_tpid_set,
23632bfe3f2eSlogwang 	.rx_queue_setup    = dpaa2_dev_rx_queue_setup,
23642bfe3f2eSlogwang 	.rx_queue_release  = dpaa2_dev_rx_queue_release,
23652bfe3f2eSlogwang 	.tx_queue_setup    = dpaa2_dev_tx_queue_setup,
23662bfe3f2eSlogwang 	.tx_queue_release  = dpaa2_dev_tx_queue_release,
2367*2d9fd380Sjfb8856606 	.rx_burst_mode_get = dpaa2_dev_rx_burst_mode_get,
2368*2d9fd380Sjfb8856606 	.tx_burst_mode_get = dpaa2_dev_tx_burst_mode_get,
23692bfe3f2eSlogwang 	.flow_ctrl_get	      = dpaa2_flow_ctrl_get,
23702bfe3f2eSlogwang 	.flow_ctrl_set	      = dpaa2_flow_ctrl_set,
23712bfe3f2eSlogwang 	.mac_addr_add         = dpaa2_dev_add_mac_addr,
23722bfe3f2eSlogwang 	.mac_addr_remove      = dpaa2_dev_remove_mac_addr,
23732bfe3f2eSlogwang 	.mac_addr_set         = dpaa2_dev_set_mac_addr,
23742bfe3f2eSlogwang 	.rss_hash_update      = dpaa2_dev_rss_hash_update,
23752bfe3f2eSlogwang 	.rss_hash_conf_get    = dpaa2_dev_rss_hash_conf_get,
23764418919fSjohnjiang 	.filter_ctrl          = dpaa2_dev_flow_ctrl,
2377*2d9fd380Sjfb8856606 	.rxq_info_get	      = dpaa2_rxq_info_get,
2378*2d9fd380Sjfb8856606 	.txq_info_get	      = dpaa2_txq_info_get,
23794418919fSjohnjiang #if defined(RTE_LIBRTE_IEEE1588)
23804418919fSjohnjiang 	.timesync_enable      = dpaa2_timesync_enable,
23814418919fSjohnjiang 	.timesync_disable     = dpaa2_timesync_disable,
23824418919fSjohnjiang 	.timesync_read_time   = dpaa2_timesync_read_time,
23834418919fSjohnjiang 	.timesync_write_time  = dpaa2_timesync_write_time,
23844418919fSjohnjiang 	.timesync_adjust_time = dpaa2_timesync_adjust_time,
23854418919fSjohnjiang 	.timesync_read_rx_timestamp = dpaa2_timesync_read_rx_timestamp,
23864418919fSjohnjiang 	.timesync_read_tx_timestamp = dpaa2_timesync_read_tx_timestamp,
23874418919fSjohnjiang #endif
23882bfe3f2eSlogwang };
23892bfe3f2eSlogwang 
2390d30ea906Sjfb8856606 /* Populate the mac address from physically available (u-boot/firmware) and/or
2391d30ea906Sjfb8856606  * one set by higher layers like MC (restool) etc.
2392d30ea906Sjfb8856606  * Returns the table of MAC entries (multiple entries)
2393d30ea906Sjfb8856606  */
2394d30ea906Sjfb8856606 static int
populate_mac_addr(struct fsl_mc_io * dpni_dev,struct dpaa2_dev_priv * priv,struct rte_ether_addr * mac_entry)2395d30ea906Sjfb8856606 populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv,
23964418919fSjohnjiang 		  struct rte_ether_addr *mac_entry)
2397d30ea906Sjfb8856606 {
2398d30ea906Sjfb8856606 	int ret;
23994418919fSjohnjiang 	struct rte_ether_addr phy_mac, prime_mac;
2400d30ea906Sjfb8856606 
24014418919fSjohnjiang 	memset(&phy_mac, 0, sizeof(struct rte_ether_addr));
24024418919fSjohnjiang 	memset(&prime_mac, 0, sizeof(struct rte_ether_addr));
2403d30ea906Sjfb8856606 
2404d30ea906Sjfb8856606 	/* Get the physical device MAC address */
2405d30ea906Sjfb8856606 	ret = dpni_get_port_mac_addr(dpni_dev, CMD_PRI_LOW, priv->token,
2406d30ea906Sjfb8856606 				     phy_mac.addr_bytes);
2407d30ea906Sjfb8856606 	if (ret) {
2408d30ea906Sjfb8856606 		DPAA2_PMD_ERR("DPNI get physical port MAC failed: %d", ret);
2409d30ea906Sjfb8856606 		goto cleanup;
2410d30ea906Sjfb8856606 	}
2411d30ea906Sjfb8856606 
2412d30ea906Sjfb8856606 	ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW, priv->token,
2413d30ea906Sjfb8856606 					prime_mac.addr_bytes);
2414d30ea906Sjfb8856606 	if (ret) {
2415d30ea906Sjfb8856606 		DPAA2_PMD_ERR("DPNI get Prime port MAC failed: %d", ret);
2416d30ea906Sjfb8856606 		goto cleanup;
2417d30ea906Sjfb8856606 	}
2418d30ea906Sjfb8856606 
2419d30ea906Sjfb8856606 	/* Now that both MAC have been obtained, do:
2420d30ea906Sjfb8856606 	 *  if not_empty_mac(phy) && phy != Prime, overwrite prime with Phy
2421d30ea906Sjfb8856606 	 *     and return phy
2422d30ea906Sjfb8856606 	 *  If empty_mac(phy), return prime.
2423d30ea906Sjfb8856606 	 *  if both are empty, create random MAC, set as prime and return
2424d30ea906Sjfb8856606 	 */
24254418919fSjohnjiang 	if (!rte_is_zero_ether_addr(&phy_mac)) {
2426d30ea906Sjfb8856606 		/* If the addresses are not same, overwrite prime */
24274418919fSjohnjiang 		if (!rte_is_same_ether_addr(&phy_mac, &prime_mac)) {
2428d30ea906Sjfb8856606 			ret = dpni_set_primary_mac_addr(dpni_dev, CMD_PRI_LOW,
2429d30ea906Sjfb8856606 							priv->token,
2430d30ea906Sjfb8856606 							phy_mac.addr_bytes);
2431d30ea906Sjfb8856606 			if (ret) {
2432d30ea906Sjfb8856606 				DPAA2_PMD_ERR("Unable to set MAC Address: %d",
2433d30ea906Sjfb8856606 					      ret);
2434d30ea906Sjfb8856606 				goto cleanup;
2435d30ea906Sjfb8856606 			}
24364418919fSjohnjiang 			memcpy(&prime_mac, &phy_mac,
24374418919fSjohnjiang 				sizeof(struct rte_ether_addr));
2438d30ea906Sjfb8856606 		}
24394418919fSjohnjiang 	} else if (rte_is_zero_ether_addr(&prime_mac)) {
2440d30ea906Sjfb8856606 		/* In case phys and prime, both are zero, create random MAC */
24414418919fSjohnjiang 		rte_eth_random_addr(prime_mac.addr_bytes);
2442d30ea906Sjfb8856606 		ret = dpni_set_primary_mac_addr(dpni_dev, CMD_PRI_LOW,
2443d30ea906Sjfb8856606 						priv->token,
2444d30ea906Sjfb8856606 						prime_mac.addr_bytes);
2445d30ea906Sjfb8856606 		if (ret) {
2446d30ea906Sjfb8856606 			DPAA2_PMD_ERR("Unable to set MAC Address: %d", ret);
2447d30ea906Sjfb8856606 			goto cleanup;
2448d30ea906Sjfb8856606 		}
2449d30ea906Sjfb8856606 	}
2450d30ea906Sjfb8856606 
2451d30ea906Sjfb8856606 	/* prime_mac the final MAC address */
24524418919fSjohnjiang 	memcpy(mac_entry, &prime_mac, sizeof(struct rte_ether_addr));
2453d30ea906Sjfb8856606 	return 0;
2454d30ea906Sjfb8856606 
2455d30ea906Sjfb8856606 cleanup:
2456d30ea906Sjfb8856606 	return -1;
2457d30ea906Sjfb8856606 }
2458d30ea906Sjfb8856606 
24592bfe3f2eSlogwang static int
check_devargs_handler(__rte_unused const char * key,const char * value,__rte_unused void * opaque)24604418919fSjohnjiang check_devargs_handler(__rte_unused const char *key, const char *value,
24614418919fSjohnjiang 		      __rte_unused void *opaque)
24624418919fSjohnjiang {
24634418919fSjohnjiang 	if (strcmp(value, "1"))
24644418919fSjohnjiang 		return -1;
24654418919fSjohnjiang 
24664418919fSjohnjiang 	return 0;
24674418919fSjohnjiang }
24684418919fSjohnjiang 
24694418919fSjohnjiang static int
dpaa2_get_devargs(struct rte_devargs * devargs,const char * key)24704418919fSjohnjiang dpaa2_get_devargs(struct rte_devargs *devargs, const char *key)
24714418919fSjohnjiang {
24724418919fSjohnjiang 	struct rte_kvargs *kvlist;
24734418919fSjohnjiang 
24744418919fSjohnjiang 	if (!devargs)
24754418919fSjohnjiang 		return 0;
24764418919fSjohnjiang 
24774418919fSjohnjiang 	kvlist = rte_kvargs_parse(devargs->args, NULL);
24784418919fSjohnjiang 	if (!kvlist)
24794418919fSjohnjiang 		return 0;
24804418919fSjohnjiang 
24814418919fSjohnjiang 	if (!rte_kvargs_count(kvlist, key)) {
24824418919fSjohnjiang 		rte_kvargs_free(kvlist);
24834418919fSjohnjiang 		return 0;
24844418919fSjohnjiang 	}
24854418919fSjohnjiang 
24864418919fSjohnjiang 	if (rte_kvargs_process(kvlist, key,
24874418919fSjohnjiang 			       check_devargs_handler, NULL) < 0) {
24884418919fSjohnjiang 		rte_kvargs_free(kvlist);
24894418919fSjohnjiang 		return 0;
24904418919fSjohnjiang 	}
24914418919fSjohnjiang 	rte_kvargs_free(kvlist);
24924418919fSjohnjiang 
24934418919fSjohnjiang 	return 1;
24944418919fSjohnjiang }
24954418919fSjohnjiang 
24964418919fSjohnjiang static int
dpaa2_dev_init(struct rte_eth_dev * eth_dev)24972bfe3f2eSlogwang dpaa2_dev_init(struct rte_eth_dev *eth_dev)
24982bfe3f2eSlogwang {
24992bfe3f2eSlogwang 	struct rte_device *dev = eth_dev->device;
25002bfe3f2eSlogwang 	struct rte_dpaa2_device *dpaa2_dev;
25012bfe3f2eSlogwang 	struct fsl_mc_io *dpni_dev;
25022bfe3f2eSlogwang 	struct dpni_attr attr;
25032bfe3f2eSlogwang 	struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
25042bfe3f2eSlogwang 	struct dpni_buffer_layout layout;
25054418919fSjohnjiang 	int ret, hw_id, i;
25062bfe3f2eSlogwang 
25072bfe3f2eSlogwang 	PMD_INIT_FUNC_TRACE();
25082bfe3f2eSlogwang 
25094418919fSjohnjiang 	dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0);
25104418919fSjohnjiang 	if (!dpni_dev) {
25114418919fSjohnjiang 		DPAA2_PMD_ERR("Memory allocation failed for dpni device");
25124418919fSjohnjiang 		return -1;
25134418919fSjohnjiang 	}
2514*2d9fd380Sjfb8856606 	dpni_dev->regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
25154418919fSjohnjiang 	eth_dev->process_private = (void *)dpni_dev;
25164418919fSjohnjiang 
25172bfe3f2eSlogwang 	/* For secondary processes, the primary has done all the work */
25181646932aSjfb8856606 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
25191646932aSjfb8856606 		/* In case of secondary, only burst and ops API need to be
25201646932aSjfb8856606 		 * plugged.
25211646932aSjfb8856606 		 */
25221646932aSjfb8856606 		eth_dev->dev_ops = &dpaa2_ethdev_ops;
2523*2d9fd380Sjfb8856606 		eth_dev->rx_queue_count = dpaa2_dev_rx_queue_count;
25244418919fSjohnjiang 		if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE))
25254418919fSjohnjiang 			eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx;
25264418919fSjohnjiang 		else if (dpaa2_get_devargs(dev->devargs,
25274418919fSjohnjiang 					DRIVER_NO_PREFETCH_MODE))
25284418919fSjohnjiang 			eth_dev->rx_pkt_burst = dpaa2_dev_rx;
25294418919fSjohnjiang 		else
25301646932aSjfb8856606 			eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx;
25311646932aSjfb8856606 		eth_dev->tx_pkt_burst = dpaa2_dev_tx;
25322bfe3f2eSlogwang 		return 0;
25331646932aSjfb8856606 	}
25342bfe3f2eSlogwang 
25352bfe3f2eSlogwang 	dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
25362bfe3f2eSlogwang 
25372bfe3f2eSlogwang 	hw_id = dpaa2_dev->object_id;
25382bfe3f2eSlogwang 	ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token);
25392bfe3f2eSlogwang 	if (ret) {
2540d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
2541d30ea906Sjfb8856606 			     "Failure in opening dpni@%d with err code %d",
25422bfe3f2eSlogwang 			     hw_id, ret);
25432bfe3f2eSlogwang 		rte_free(dpni_dev);
25442bfe3f2eSlogwang 		return -1;
25452bfe3f2eSlogwang 	}
25462bfe3f2eSlogwang 
25472bfe3f2eSlogwang 	/* Clean the device first */
25482bfe3f2eSlogwang 	ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token);
25492bfe3f2eSlogwang 	if (ret) {
2550d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Failure cleaning dpni@%d with err code %d",
25512bfe3f2eSlogwang 			      hw_id, ret);
25522bfe3f2eSlogwang 		goto init_err;
25532bfe3f2eSlogwang 	}
25542bfe3f2eSlogwang 
25552bfe3f2eSlogwang 	ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr);
25562bfe3f2eSlogwang 	if (ret) {
2557d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
2558d30ea906Sjfb8856606 			     "Failure in get dpni@%d attribute, err code %d",
25592bfe3f2eSlogwang 			     hw_id, ret);
25602bfe3f2eSlogwang 		goto init_err;
25612bfe3f2eSlogwang 	}
25622bfe3f2eSlogwang 
25632bfe3f2eSlogwang 	priv->num_rx_tc = attr.num_rx_tcs;
2564*2d9fd380Sjfb8856606 	priv->qos_entries = attr.qos_entries;
2565*2d9fd380Sjfb8856606 	priv->fs_entries = attr.fs_entries;
2566*2d9fd380Sjfb8856606 	priv->dist_queues = attr.num_queues;
2567*2d9fd380Sjfb8856606 
25684418919fSjohnjiang 	/* only if the custom CG is enabled */
25694418919fSjohnjiang 	if (attr.options & DPNI_OPT_CUSTOM_CG)
25704418919fSjohnjiang 		priv->max_cgs = attr.num_cgs;
25714418919fSjohnjiang 	else
25724418919fSjohnjiang 		priv->max_cgs = 0;
25732bfe3f2eSlogwang 
25744418919fSjohnjiang 	for (i = 0; i < priv->max_cgs; i++)
25754418919fSjohnjiang 		priv->cgid_in_use[i] = 0;
25764418919fSjohnjiang 
25774418919fSjohnjiang 	for (i = 0; i < attr.num_rx_tcs; i++)
25784418919fSjohnjiang 		priv->nb_rx_queues += attr.num_queues;
25792bfe3f2eSlogwang 
25802bfe3f2eSlogwang 	/* Using number of TX queues as number of TX TCs */
25812bfe3f2eSlogwang 	priv->nb_tx_queues = attr.num_tx_tcs;
25822bfe3f2eSlogwang 
25834418919fSjohnjiang 	DPAA2_PMD_DEBUG("RX-TC= %d, rx_queues= %d, tx_queues=%d, max_cgs=%d",
2584d30ea906Sjfb8856606 			priv->num_rx_tc, priv->nb_rx_queues,
25854418919fSjohnjiang 			priv->nb_tx_queues, priv->max_cgs);
25862bfe3f2eSlogwang 
25872bfe3f2eSlogwang 	priv->hw = dpni_dev;
25882bfe3f2eSlogwang 	priv->hw_id = hw_id;
25892bfe3f2eSlogwang 	priv->options = attr.options;
25902bfe3f2eSlogwang 	priv->max_mac_filters = attr.mac_filter_entries;
25912bfe3f2eSlogwang 	priv->max_vlan_filters = attr.vlan_filter_entries;
25922bfe3f2eSlogwang 	priv->flags = 0;
25934418919fSjohnjiang #if defined(RTE_LIBRTE_IEEE1588)
25944418919fSjohnjiang 	priv->tx_conf_en = 1;
25954418919fSjohnjiang #else
25964418919fSjohnjiang 	priv->tx_conf_en = 0;
25974418919fSjohnjiang #endif
25982bfe3f2eSlogwang 
25992bfe3f2eSlogwang 	/* Allocate memory for hardware structure for queues */
26002bfe3f2eSlogwang 	ret = dpaa2_alloc_rx_tx_queues(eth_dev);
26012bfe3f2eSlogwang 	if (ret) {
2602d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Queue allocation Failed");
26032bfe3f2eSlogwang 		goto init_err;
26042bfe3f2eSlogwang 	}
26052bfe3f2eSlogwang 
2606d30ea906Sjfb8856606 	/* Allocate memory for storing MAC addresses.
2607d30ea906Sjfb8856606 	 * Table of mac_filter_entries size is allocated so that RTE ether lib
2608d30ea906Sjfb8856606 	 * can add MAC entries when rte_eth_dev_mac_addr_add is called.
2609d30ea906Sjfb8856606 	 */
26102bfe3f2eSlogwang 	eth_dev->data->mac_addrs = rte_zmalloc("dpni",
26114418919fSjohnjiang 		RTE_ETHER_ADDR_LEN * attr.mac_filter_entries, 0);
26122bfe3f2eSlogwang 	if (eth_dev->data->mac_addrs == NULL) {
2613d30ea906Sjfb8856606 		DPAA2_PMD_ERR(
26142bfe3f2eSlogwang 		   "Failed to allocate %d bytes needed to store MAC addresses",
26154418919fSjohnjiang 		   RTE_ETHER_ADDR_LEN * attr.mac_filter_entries);
26162bfe3f2eSlogwang 		ret = -ENOMEM;
26172bfe3f2eSlogwang 		goto init_err;
26182bfe3f2eSlogwang 	}
26192bfe3f2eSlogwang 
2620d30ea906Sjfb8856606 	ret = populate_mac_addr(dpni_dev, priv, &eth_dev->data->mac_addrs[0]);
26212bfe3f2eSlogwang 	if (ret) {
2622d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Unable to fetch MAC Address for device");
2623d30ea906Sjfb8856606 		rte_free(eth_dev->data->mac_addrs);
2624d30ea906Sjfb8856606 		eth_dev->data->mac_addrs = NULL;
26252bfe3f2eSlogwang 		goto init_err;
26262bfe3f2eSlogwang 	}
26272bfe3f2eSlogwang 
26282bfe3f2eSlogwang 	/* ... tx buffer layout ... */
26292bfe3f2eSlogwang 	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
26304418919fSjohnjiang 	if (priv->tx_conf_en) {
26314418919fSjohnjiang 		layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
26324418919fSjohnjiang 				 DPNI_BUF_LAYOUT_OPT_TIMESTAMP;
26334418919fSjohnjiang 		layout.pass_timestamp = true;
26344418919fSjohnjiang 	} else {
26352bfe3f2eSlogwang 		layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
26364418919fSjohnjiang 	}
26372bfe3f2eSlogwang 	layout.pass_frame_status = 1;
26382bfe3f2eSlogwang 	ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
26392bfe3f2eSlogwang 				     DPNI_QUEUE_TX, &layout);
26402bfe3f2eSlogwang 	if (ret) {
2641d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error (%d) in setting tx buffer layout", ret);
26422bfe3f2eSlogwang 		goto init_err;
26432bfe3f2eSlogwang 	}
26442bfe3f2eSlogwang 
26452bfe3f2eSlogwang 	/* ... tx-conf and error buffer layout ... */
26462bfe3f2eSlogwang 	memset(&layout, 0, sizeof(struct dpni_buffer_layout));
26474418919fSjohnjiang 	if (priv->tx_conf_en) {
26484418919fSjohnjiang 		layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
26494418919fSjohnjiang 				 DPNI_BUF_LAYOUT_OPT_TIMESTAMP;
26504418919fSjohnjiang 		layout.pass_timestamp = true;
26514418919fSjohnjiang 	} else {
26522bfe3f2eSlogwang 		layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
26534418919fSjohnjiang 	}
26542bfe3f2eSlogwang 	layout.pass_frame_status = 1;
26552bfe3f2eSlogwang 	ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
26562bfe3f2eSlogwang 				     DPNI_QUEUE_TX_CONFIRM, &layout);
26572bfe3f2eSlogwang 	if (ret) {
2658d30ea906Sjfb8856606 		DPAA2_PMD_ERR("Error (%d) in setting tx-conf buffer layout",
26592bfe3f2eSlogwang 			     ret);
26602bfe3f2eSlogwang 		goto init_err;
26612bfe3f2eSlogwang 	}
26622bfe3f2eSlogwang 
26632bfe3f2eSlogwang 	eth_dev->dev_ops = &dpaa2_ethdev_ops;
26642bfe3f2eSlogwang 
26654418919fSjohnjiang 	if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE)) {
26664418919fSjohnjiang 		eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx;
26674418919fSjohnjiang 		DPAA2_PMD_INFO("Loopback mode");
26684418919fSjohnjiang 	} else if (dpaa2_get_devargs(dev->devargs, DRIVER_NO_PREFETCH_MODE)) {
26694418919fSjohnjiang 		eth_dev->rx_pkt_burst = dpaa2_dev_rx;
26704418919fSjohnjiang 		DPAA2_PMD_INFO("No Prefetch mode");
26714418919fSjohnjiang 	} else {
26722bfe3f2eSlogwang 		eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx;
26734418919fSjohnjiang 	}
26742bfe3f2eSlogwang 	eth_dev->tx_pkt_burst = dpaa2_dev_tx;
26752bfe3f2eSlogwang 
26764418919fSjohnjiang 	/*Init fields w.r.t. classficaition*/
2677*2d9fd380Sjfb8856606 	memset(&priv->extract.qos_key_extract, 0,
2678*2d9fd380Sjfb8856606 		sizeof(struct dpaa2_key_extract));
26794418919fSjohnjiang 	priv->extract.qos_extract_param = (size_t)rte_malloc(NULL, 256, 64);
26804418919fSjohnjiang 	if (!priv->extract.qos_extract_param) {
26814418919fSjohnjiang 		DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow "
26824418919fSjohnjiang 			    " classificaiton ", ret);
26834418919fSjohnjiang 		goto init_err;
26844418919fSjohnjiang 	}
2685*2d9fd380Sjfb8856606 	priv->extract.qos_key_extract.key_info.ipv4_src_offset =
2686*2d9fd380Sjfb8856606 		IP_ADDRESS_OFFSET_INVALID;
2687*2d9fd380Sjfb8856606 	priv->extract.qos_key_extract.key_info.ipv4_dst_offset =
2688*2d9fd380Sjfb8856606 		IP_ADDRESS_OFFSET_INVALID;
2689*2d9fd380Sjfb8856606 	priv->extract.qos_key_extract.key_info.ipv6_src_offset =
2690*2d9fd380Sjfb8856606 		IP_ADDRESS_OFFSET_INVALID;
2691*2d9fd380Sjfb8856606 	priv->extract.qos_key_extract.key_info.ipv6_dst_offset =
2692*2d9fd380Sjfb8856606 		IP_ADDRESS_OFFSET_INVALID;
2693*2d9fd380Sjfb8856606 
26944418919fSjohnjiang 	for (i = 0; i < MAX_TCS; i++) {
2695*2d9fd380Sjfb8856606 		memset(&priv->extract.tc_key_extract[i], 0,
2696*2d9fd380Sjfb8856606 			sizeof(struct dpaa2_key_extract));
2697*2d9fd380Sjfb8856606 		priv->extract.tc_extract_param[i] =
26984418919fSjohnjiang 			(size_t)rte_malloc(NULL, 256, 64);
2699*2d9fd380Sjfb8856606 		if (!priv->extract.tc_extract_param[i]) {
27004418919fSjohnjiang 			DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow classificaiton",
27014418919fSjohnjiang 				     ret);
27024418919fSjohnjiang 			goto init_err;
27034418919fSjohnjiang 		}
2704*2d9fd380Sjfb8856606 		priv->extract.tc_key_extract[i].key_info.ipv4_src_offset =
2705*2d9fd380Sjfb8856606 			IP_ADDRESS_OFFSET_INVALID;
2706*2d9fd380Sjfb8856606 		priv->extract.tc_key_extract[i].key_info.ipv4_dst_offset =
2707*2d9fd380Sjfb8856606 			IP_ADDRESS_OFFSET_INVALID;
2708*2d9fd380Sjfb8856606 		priv->extract.tc_key_extract[i].key_info.ipv6_src_offset =
2709*2d9fd380Sjfb8856606 			IP_ADDRESS_OFFSET_INVALID;
2710*2d9fd380Sjfb8856606 		priv->extract.tc_key_extract[i].key_info.ipv6_dst_offset =
2711*2d9fd380Sjfb8856606 			IP_ADDRESS_OFFSET_INVALID;
27124418919fSjohnjiang 	}
27134418919fSjohnjiang 
27144418919fSjohnjiang 	ret = dpni_set_max_frame_length(dpni_dev, CMD_PRI_LOW, priv->token,
27154418919fSjohnjiang 					RTE_ETHER_MAX_LEN - RTE_ETHER_CRC_LEN
27164418919fSjohnjiang 					+ VLAN_TAG_SIZE);
27174418919fSjohnjiang 	if (ret) {
27184418919fSjohnjiang 		DPAA2_PMD_ERR("Unable to set mtu. check config");
27194418919fSjohnjiang 		goto init_err;
27204418919fSjohnjiang 	}
27214418919fSjohnjiang 
27224418919fSjohnjiang 	/*TODO To enable soft parser support DPAA2 driver needs to integrate
27234418919fSjohnjiang 	 * with external entity to receive byte code for software sequence
27244418919fSjohnjiang 	 * and same will be offload to the H/W using MC interface.
27254418919fSjohnjiang 	 * Currently it is assumed that DPAA2 driver has byte code by some
27264418919fSjohnjiang 	 * mean and same if offloaded to H/W.
27274418919fSjohnjiang 	 */
27284418919fSjohnjiang 	if (getenv("DPAA2_ENABLE_SOFT_PARSER")) {
27294418919fSjohnjiang 		WRIOP_SS_INITIALIZER(priv);
27304418919fSjohnjiang 		ret = dpaa2_eth_load_wriop_soft_parser(priv, DPNI_SS_INGRESS);
27314418919fSjohnjiang 		if (ret < 0) {
27324418919fSjohnjiang 			DPAA2_PMD_ERR(" Error(%d) in loading softparser\n",
27334418919fSjohnjiang 				      ret);
27344418919fSjohnjiang 			return ret;
27354418919fSjohnjiang 		}
27364418919fSjohnjiang 
27374418919fSjohnjiang 		ret = dpaa2_eth_enable_wriop_soft_parser(priv,
27384418919fSjohnjiang 							 DPNI_SS_INGRESS);
27394418919fSjohnjiang 		if (ret < 0) {
27404418919fSjohnjiang 			DPAA2_PMD_ERR(" Error(%d) in enabling softparser\n",
27414418919fSjohnjiang 				      ret);
27424418919fSjohnjiang 			return ret;
27434418919fSjohnjiang 		}
27444418919fSjohnjiang 	}
27452bfe3f2eSlogwang 	RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name);
27462bfe3f2eSlogwang 	return 0;
27472bfe3f2eSlogwang init_err:
27482bfe3f2eSlogwang 	dpaa2_dev_close(eth_dev);
27492bfe3f2eSlogwang 
2750*2d9fd380Sjfb8856606 	return ret;
27512bfe3f2eSlogwang }
27522bfe3f2eSlogwang 
27532bfe3f2eSlogwang static int
rte_dpaa2_probe(struct rte_dpaa2_driver * dpaa2_drv,struct rte_dpaa2_device * dpaa2_dev)27542bfe3f2eSlogwang rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
27552bfe3f2eSlogwang 		struct rte_dpaa2_device *dpaa2_dev)
27562bfe3f2eSlogwang {
27572bfe3f2eSlogwang 	struct rte_eth_dev *eth_dev;
27584418919fSjohnjiang 	struct dpaa2_dev_priv *dev_priv;
27592bfe3f2eSlogwang 	int diag;
27602bfe3f2eSlogwang 
27614b05018fSfengbojiang 	if ((DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE) >
27624b05018fSfengbojiang 		RTE_PKTMBUF_HEADROOM) {
27634b05018fSfengbojiang 		DPAA2_PMD_ERR(
27644b05018fSfengbojiang 		"RTE_PKTMBUF_HEADROOM(%d) shall be > DPAA2 Annotation req(%d)",
27654b05018fSfengbojiang 		RTE_PKTMBUF_HEADROOM,
27664b05018fSfengbojiang 		DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE);
27674b05018fSfengbojiang 
27684b05018fSfengbojiang 		return -1;
27694b05018fSfengbojiang 	}
27704b05018fSfengbojiang 
27712bfe3f2eSlogwang 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
27722bfe3f2eSlogwang 		eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name);
27732bfe3f2eSlogwang 		if (!eth_dev)
27742bfe3f2eSlogwang 			return -ENODEV;
27754418919fSjohnjiang 		dev_priv = rte_zmalloc("ethdev private structure",
27762bfe3f2eSlogwang 				       sizeof(struct dpaa2_dev_priv),
27772bfe3f2eSlogwang 				       RTE_CACHE_LINE_SIZE);
27784418919fSjohnjiang 		if (dev_priv == NULL) {
2779d30ea906Sjfb8856606 			DPAA2_PMD_CRIT(
2780d30ea906Sjfb8856606 				"Unable to allocate memory for private data");
27812bfe3f2eSlogwang 			rte_eth_dev_release_port(eth_dev);
27822bfe3f2eSlogwang 			return -ENOMEM;
27832bfe3f2eSlogwang 		}
27844418919fSjohnjiang 		eth_dev->data->dev_private = (void *)dev_priv;
27854418919fSjohnjiang 		/* Store a pointer to eth_dev in dev_private */
27864418919fSjohnjiang 		dev_priv->eth_dev = eth_dev;
27874418919fSjohnjiang 		dev_priv->tx_conf_en = 0;
27882bfe3f2eSlogwang 	} else {
27892bfe3f2eSlogwang 		eth_dev = rte_eth_dev_attach_secondary(dpaa2_dev->device.name);
27904418919fSjohnjiang 		if (!eth_dev) {
27914418919fSjohnjiang 			DPAA2_PMD_DEBUG("returning enodev");
27922bfe3f2eSlogwang 			return -ENODEV;
27932bfe3f2eSlogwang 		}
27944418919fSjohnjiang 	}
27952bfe3f2eSlogwang 
27962bfe3f2eSlogwang 	eth_dev->device = &dpaa2_dev->device;
27972bfe3f2eSlogwang 
27982bfe3f2eSlogwang 	dpaa2_dev->eth_dev = eth_dev;
27992bfe3f2eSlogwang 	eth_dev->data->rx_mbuf_alloc_failed = 0;
28002bfe3f2eSlogwang 
2801d30ea906Sjfb8856606 	if (dpaa2_drv->drv_flags & RTE_DPAA2_DRV_INTR_LSC)
2802d30ea906Sjfb8856606 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
2803d30ea906Sjfb8856606 
2804*2d9fd380Sjfb8856606 	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
2805*2d9fd380Sjfb8856606 
28062bfe3f2eSlogwang 	/* Invoke PMD device initialization function */
28072bfe3f2eSlogwang 	diag = dpaa2_dev_init(eth_dev);
2808d30ea906Sjfb8856606 	if (diag == 0) {
2809d30ea906Sjfb8856606 		rte_eth_dev_probing_finish(eth_dev);
28102bfe3f2eSlogwang 		return 0;
2811d30ea906Sjfb8856606 	}
28122bfe3f2eSlogwang 
28132bfe3f2eSlogwang 	rte_eth_dev_release_port(eth_dev);
28142bfe3f2eSlogwang 	return diag;
28152bfe3f2eSlogwang }
28162bfe3f2eSlogwang 
28172bfe3f2eSlogwang static int
rte_dpaa2_remove(struct rte_dpaa2_device * dpaa2_dev)28182bfe3f2eSlogwang rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
28192bfe3f2eSlogwang {
28202bfe3f2eSlogwang 	struct rte_eth_dev *eth_dev;
2821*2d9fd380Sjfb8856606 	int ret;
28222bfe3f2eSlogwang 
28232bfe3f2eSlogwang 	eth_dev = dpaa2_dev->eth_dev;
2824*2d9fd380Sjfb8856606 	dpaa2_dev_close(eth_dev);
2825*2d9fd380Sjfb8856606 	ret = rte_eth_dev_release_port(eth_dev);
28262bfe3f2eSlogwang 
2827*2d9fd380Sjfb8856606 	return ret;
28282bfe3f2eSlogwang }
28292bfe3f2eSlogwang 
28302bfe3f2eSlogwang static struct rte_dpaa2_driver rte_dpaa2_pmd = {
2831d30ea906Sjfb8856606 	.drv_flags = RTE_DPAA2_DRV_INTR_LSC | RTE_DPAA2_DRV_IOVA_AS_VA,
28322bfe3f2eSlogwang 	.drv_type = DPAA2_ETH,
28332bfe3f2eSlogwang 	.probe = rte_dpaa2_probe,
28342bfe3f2eSlogwang 	.remove = rte_dpaa2_remove,
28352bfe3f2eSlogwang };
28362bfe3f2eSlogwang 
28372bfe3f2eSlogwang RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd);
28384418919fSjohnjiang RTE_PMD_REGISTER_PARAM_STRING(net_dpaa2,
28394418919fSjohnjiang 		DRIVER_LOOPBACK_MODE "=<int> "
28404418919fSjohnjiang 		DRIVER_NO_PREFETCH_MODE "=<int>");
2841*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(dpaa2_logtype_pmd, pmd.net.dpaa2, NOTICE);
2842