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, ð_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