X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fdpaa2%2Fdpaa2_ethdev.c;h=b58add9f7228b8c95446c901c280d2bf1dbf2fc6;hb=b58690951bd7809697ece01aca924305348ff92b;hp=0ab43cadf81c09feffbf74716874bd82ec4dd446;hpb=16c4a3c46ab76d8fe130dac909c26e41b2684898;p=dpdk.git diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 0ab43cadf8..b58add9f72 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * */ @@ -17,6 +17,7 @@ #include #include #include +#include #include "dpaa2_pmd_logs.h" #include @@ -25,20 +26,26 @@ #include #include #include "dpaa2_ethdev.h" +#include "dpaa2_sparser.h" #include +#define DRIVER_LOOPBACK_MODE "drv_loopback" +#define DRIVER_NO_PREFETCH_MODE "drv_no_prefetch" + /* Supported Rx offloads */ static uint64_t dev_rx_offloads_sup = - DEV_RX_OFFLOAD_VLAN_STRIP | - DEV_RX_OFFLOAD_IPV4_CKSUM | - DEV_RX_OFFLOAD_UDP_CKSUM | - DEV_RX_OFFLOAD_TCP_CKSUM | + DEV_RX_OFFLOAD_CHECKSUM | + DEV_RX_OFFLOAD_SCTP_CKSUM | DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_RX_OFFLOAD_OUTER_UDP_CKSUM | + DEV_RX_OFFLOAD_VLAN_STRIP | DEV_RX_OFFLOAD_VLAN_FILTER | - DEV_RX_OFFLOAD_JUMBO_FRAME; + DEV_RX_OFFLOAD_JUMBO_FRAME | + DEV_RX_OFFLOAD_TIMESTAMP; /* Rx offloads which cannot be disabled */ static uint64_t dev_rx_offloads_nodis = + DEV_RX_OFFLOAD_RSS_HASH | DEV_RX_OFFLOAD_SCATTER; /* Supported Tx offloads */ @@ -48,16 +55,16 @@ static uint64_t dev_tx_offloads_sup = DEV_TX_OFFLOAD_UDP_CKSUM | DEV_TX_OFFLOAD_TCP_CKSUM | DEV_TX_OFFLOAD_SCTP_CKSUM | - DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM; + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_TX_OFFLOAD_MT_LOCKFREE | + DEV_TX_OFFLOAD_MBUF_FAST_FREE; /* Tx offloads which cannot be disabled */ static uint64_t dev_tx_offloads_nodis = - DEV_TX_OFFLOAD_MULTI_SEGS | - DEV_TX_OFFLOAD_MT_LOCKFREE | - DEV_TX_OFFLOAD_MBUF_FAST_FREE; + DEV_TX_OFFLOAD_MULTI_SEGS; /* enable timestamp in mbuf */ -enum pmd_dpaa2_ts dpaa2_enable_ts; +bool dpaa2_enable_ts[RTE_MAX_ETHPORTS]; struct rte_dpaa2_xstats_name_off { char name[RTE_ETH_XSTATS_NAME_SIZE]; @@ -79,6 +86,16 @@ static const struct rte_dpaa2_xstats_name_off dpaa2_xstats_strings[] = { {"ingress_nobuffer_discards", 2, 2}, {"egress_discarded_frames", 2, 3}, {"egress_confirmed_frames", 2, 4}, + {"cgr_reject_frames", 4, 0}, + {"cgr_reject_bytes", 4, 1}, +}; + +static const enum rte_filter_op dpaa2_supported_filter_ops[] = { + RTE_ETH_FILTER_ADD, + RTE_ETH_FILTER_DELETE, + RTE_ETH_FILTER_UPDATE, + RTE_ETH_FILTER_FLUSH, + RTE_ETH_FILTER_GET }; static struct rte_dpaa2_driver rte_dpaa2_pmd; @@ -89,20 +106,12 @@ static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev); static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev); static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); -int dpaa2_logtype_pmd; - -__rte_experimental void -rte_pmd_dpaa2_set_timestamp(enum pmd_dpaa2_ts enable) -{ - dpaa2_enable_ts = enable; -} - static int dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = priv->hw; + struct fsl_mc_io *dpni = dev->process_private; PMD_INIT_FUNC_TRACE(); @@ -112,8 +121,8 @@ dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) } if (on) - ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW, - priv->token, vlan_id); + ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW, priv->token, + vlan_id, 0, 0, 0); else ret = dpni_remove_vlan_id(dpni, CMD_PRI_LOW, priv->token, vlan_id); @@ -129,8 +138,8 @@ static int dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = priv->hw; - int ret; + struct fsl_mc_io *dpni = dev->process_private; + int ret = 0; PMD_INIT_FUNC_TRACE(); @@ -138,7 +147,7 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) /* VLAN Filter not avaialble */ if (!priv->max_vlan_filters) { DPAA2_PMD_INFO("VLAN filter not available"); - goto next_mask; + return -ENOTSUP; } if (dev->data->dev_conf.rxmode.offloads & @@ -151,14 +160,8 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) if (ret < 0) DPAA2_PMD_INFO("Unable to set vlan filter = %d", ret); } -next_mask: - if (mask & ETH_VLAN_EXTEND_MASK) { - if (dev->data->dev_conf.rxmode.offloads & - DEV_RX_OFFLOAD_VLAN_EXTEND) - DPAA2_PMD_INFO("VLAN extend offload not supported"); - } - return 0; + return ret; } static int @@ -167,7 +170,7 @@ dpaa2_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = priv->hw; + struct fsl_mc_io *dpni = dev->process_private; int ret = -ENOTSUP; PMD_INIT_FUNC_TRACE(); @@ -205,8 +208,7 @@ dpaa2_fw_version_get(struct rte_eth_dev *dev, size_t fw_size) { int ret; - struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = priv->hw; + struct fsl_mc_io *dpni = dev->process_private; struct mc_soc_version mc_plat_info = {0}; struct mc_version mc_ver_info = {0}; @@ -232,7 +234,7 @@ dpaa2_fw_version_get(struct rte_eth_dev *dev, return 0; } -static void +static int dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct dpaa2_dev_priv *priv = dev->data->dev_private; @@ -258,6 +260,95 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_vfs = 0; dev_info->max_vmdq_pools = ETH_16_POOLS; dev_info->flow_type_rss_offloads = DPAA2_RSS_OFFLOAD_ALL; + + dev_info->default_rxportconf.burst_size = dpaa2_dqrr_size; + /* same is rx size for best perf */ + dev_info->default_txportconf.burst_size = dpaa2_dqrr_size; + + dev_info->default_rxportconf.nb_queues = 1; + dev_info->default_txportconf.nb_queues = 1; + dev_info->default_txportconf.ring_size = CONG_ENTER_TX_THRESHOLD; + dev_info->default_rxportconf.ring_size = DPAA2_RX_DEFAULT_NBDESC; + + if (dpaa2_svr_family == SVR_LX2160A) { + dev_info->speed_capa |= ETH_LINK_SPEED_25G | + ETH_LINK_SPEED_40G | + ETH_LINK_SPEED_50G | + ETH_LINK_SPEED_100G; + } + + return 0; +} + +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) +{ + struct rte_eth_conf *eth_conf = &dev->data->dev_conf; + int ret = -EINVAL; + unsigned int i; + const struct burst_info { + uint64_t flags; + const char *output; + } rx_offload_map[] = { + {DEV_RX_OFFLOAD_CHECKSUM, " Checksum,"}, + {DEV_RX_OFFLOAD_SCTP_CKSUM, " SCTP csum,"}, + {DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPV4 csum,"}, + {DEV_RX_OFFLOAD_OUTER_UDP_CKSUM, " Outer UDP csum,"}, + {DEV_RX_OFFLOAD_VLAN_STRIP, " VLAN strip,"}, + {DEV_RX_OFFLOAD_VLAN_FILTER, " VLAN filter,"}, + {DEV_RX_OFFLOAD_JUMBO_FRAME, " Jumbo frame,"}, + {DEV_RX_OFFLOAD_TIMESTAMP, " Timestamp,"}, + {DEV_RX_OFFLOAD_RSS_HASH, " RSS,"}, + {DEV_RX_OFFLOAD_SCATTER, " Scattered,"} + }; + + /* Update Rx offload info */ + for (i = 0; i < RTE_DIM(rx_offload_map); i++) { + if (eth_conf->rxmode.offloads & rx_offload_map[i].flags) { + snprintf(mode->info, sizeof(mode->info), "%s", + rx_offload_map[i].output); + ret = 0; + break; + } + } + return ret; +} + +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) +{ + struct rte_eth_conf *eth_conf = &dev->data->dev_conf; + int ret = -EINVAL; + unsigned int i; + const struct burst_info { + uint64_t flags; + const char *output; + } tx_offload_map[] = { + {DEV_TX_OFFLOAD_VLAN_INSERT, " VLAN Insert,"}, + {DEV_TX_OFFLOAD_IPV4_CKSUM, " IPV4 csum,"}, + {DEV_TX_OFFLOAD_UDP_CKSUM, " UDP csum,"}, + {DEV_TX_OFFLOAD_TCP_CKSUM, " TCP csum,"}, + {DEV_TX_OFFLOAD_SCTP_CKSUM, " SCTP csum,"}, + {DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPV4 csum,"}, + {DEV_TX_OFFLOAD_MT_LOCKFREE, " MT lockfree,"}, + {DEV_TX_OFFLOAD_MBUF_FAST_FREE, " MBUF free disable,"}, + {DEV_TX_OFFLOAD_MULTI_SEGS, " Scattered,"} + }; + + /* Update Tx offload info */ + for (i = 0; i < RTE_DIM(tx_offload_map); i++) { + if (eth_conf->txmode.offloads & tx_offload_map[i].flags) { + snprintf(mode->info, sizeof(mode->info), "%s", + tx_offload_map[i].output); + ret = 0; + break; + } + } + return ret; } static int @@ -266,6 +357,7 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) struct dpaa2_dev_priv *priv = dev->data->dev_private; uint16_t dist_idx; uint32_t vq_id; + uint8_t num_rxqueue_per_tc; struct dpaa2_queue *mc_q, *mcq; uint32_t tot_queues; int i; @@ -273,7 +365,11 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); - tot_queues = priv->nb_rx_queues + priv->nb_tx_queues; + num_rxqueue_per_tc = (priv->nb_rx_queues / priv->num_rx_tc); + if (priv->tx_conf_en) + tot_queues = priv->nb_rx_queues + 2 * priv->nb_tx_queues; + else + tot_queues = priv->nb_rx_queues + priv->nb_tx_queues; mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues, RTE_CACHE_LINE_SIZE); if (!mc_q) { @@ -308,15 +404,45 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) goto fail_tx; } + if (priv->tx_conf_en) { + /*Setup tx confirmation queues*/ + for (i = 0; i < priv->nb_tx_queues; i++) { + mc_q->eth_data = dev->data; + mc_q->tc_index = i; + mc_q->flow_id = 0; + priv->tx_conf_vq[i] = mc_q++; + dpaa2_q = (struct dpaa2_queue *)priv->tx_conf_vq[i]; + dpaa2_q->q_storage = + rte_malloc("dq_storage", + sizeof(struct queue_storage_info_t), + RTE_CACHE_LINE_SIZE); + if (!dpaa2_q->q_storage) + goto fail_tx_conf; + + memset(dpaa2_q->q_storage, 0, + sizeof(struct queue_storage_info_t)); + if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage)) + goto fail_tx_conf; + } + } + vq_id = 0; for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) { mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id]; - mcq->tc_index = DPAA2_DEF_TC; - mcq->flow_id = dist_idx; + mcq->tc_index = dist_idx / num_rxqueue_per_tc; + mcq->flow_id = dist_idx % num_rxqueue_per_tc; vq_id++; } return 0; +fail_tx_conf: + i -= 1; + while (i >= 0) { + dpaa2_q = (struct dpaa2_queue *)priv->tx_conf_vq[i]; + rte_free(dpaa2_q->q_storage); + priv->tx_conf_vq[i--] = NULL; + } + i = priv->nb_tx_queues; fail_tx: i -= 1; while (i >= 0) { @@ -360,6 +486,14 @@ dpaa2_free_rx_tx_queues(struct rte_eth_dev *dev) dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i]; rte_free(dpaa2_q->cscn); } + if (priv->tx_conf_en) { + /* cleanup tx conf queue storage */ + for (i = 0; i < priv->nb_tx_queues; i++) { + dpaa2_q = (struct dpaa2_queue *) + priv->tx_conf_vq[i]; + rte_free(dpaa2_q->q_storage); + } + } /*free memory for all queues (RX+TX) */ rte_free(priv->rx_vq[0]); priv->rx_vq[0] = NULL; @@ -370,7 +504,7 @@ static int dpaa2_eth_dev_configure(struct rte_eth_dev *dev) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = priv->hw; + struct fsl_mc_io *dpni = dev->process_private; struct rte_eth_conf *eth_conf = &dev->data->dev_conf; uint64_t rx_offloads = eth_conf->rxmode.offloads; uint64_t tx_offloads = eth_conf->txmode.offloads; @@ -378,47 +512,56 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) int rx_l4_csum_offload = false; int tx_l3_csum_offload = false; int tx_l4_csum_offload = false; - int ret; + int ret, tc_index; PMD_INIT_FUNC_TRACE(); - /* Rx offloads validation */ + /* Rx offloads which are enabled by default */ if (dev_rx_offloads_nodis & ~rx_offloads) { - DPAA2_PMD_WARN( - "Rx offloads non configurable - requested 0x%" PRIx64 - " ignored 0x%" PRIx64, - rx_offloads, dev_rx_offloads_nodis); + DPAA2_PMD_INFO( + "Some of rx offloads enabled by default - requested 0x%" PRIx64 + " fixed are 0x%" PRIx64, + rx_offloads, dev_rx_offloads_nodis); } - /* Tx offloads validation */ + /* Tx offloads which are enabled by default */ if (dev_tx_offloads_nodis & ~tx_offloads) { - DPAA2_PMD_WARN( - "Tx offloads non configurable - requested 0x%" PRIx64 - " ignored 0x%" PRIx64, - tx_offloads, dev_tx_offloads_nodis); + DPAA2_PMD_INFO( + "Some of tx offloads enabled by default - requested 0x%" PRIx64 + " fixed are 0x%" PRIx64, + tx_offloads, dev_tx_offloads_nodis); } if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { if (eth_conf->rxmode.max_rx_pkt_len <= DPAA2_MAX_RX_PKT_LEN) { ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, - priv->token, eth_conf->rxmode.max_rx_pkt_len); + priv->token, eth_conf->rxmode.max_rx_pkt_len + - RTE_ETHER_CRC_LEN); if (ret) { DPAA2_PMD_ERR( "Unable to set mtu. check config"); return ret; } + dev->data->mtu = + dev->data->dev_conf.rxmode.max_rx_pkt_len - + RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN - + VLAN_TAG_SIZE; } else { return -1; } } if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) { - ret = dpaa2_setup_flow_dist(dev, - eth_conf->rx_adv_conf.rss_conf.rss_hf); - if (ret) { - DPAA2_PMD_ERR("Unable to set flow distribution." - "Check queue config"); - return ret; + for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) { + ret = dpaa2_setup_flow_dist(dev, + eth_conf->rx_adv_conf.rss_conf.rss_hf, + tc_index); + if (ret) { + DPAA2_PMD_ERR( + "Unable to set flow distribution on tc%d." + "Check queue config", tc_index); + return ret; + } } } @@ -426,7 +569,8 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) rx_l3_csum_offload = true; if ((rx_offloads & DEV_RX_OFFLOAD_UDP_CKSUM) || - (rx_offloads & DEV_RX_OFFLOAD_TCP_CKSUM)) + (rx_offloads & DEV_RX_OFFLOAD_TCP_CKSUM) || + (rx_offloads & DEV_RX_OFFLOAD_SCTP_CKSUM)) rx_l4_csum_offload = true; ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, @@ -443,6 +587,11 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) return ret; } +#if !defined(RTE_LIBRTE_IEEE1588) + if (rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) +#endif + dpaa2_enable_ts[dev->data->port_id] = true; + if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) tx_l3_csum_offload = true; @@ -483,9 +632,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); - /* update the current status */ - dpaa2_dev_link_update(dev, 0); - return 0; } @@ -495,25 +641,32 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) static int dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, - uint16_t nb_rx_desc __rte_unused, + uint16_t nb_rx_desc, unsigned int socket_id __rte_unused, - const struct rte_eth_rxconf *rx_conf __rte_unused, + const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mb_pool) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct dpaa2_queue *dpaa2_q; struct dpni_queue cfg; uint8_t options = 0; uint8_t flow_id; uint32_t bpid; - int ret; + int i, ret; PMD_INIT_FUNC_TRACE(); DPAA2_PMD_DEBUG("dev =%p, queue =%d, pool = %p, conf =%p", dev, rx_queue_id, mb_pool, rx_conf); + /* Rx deferred start is not supported */ + if (rx_conf->rx_deferred_start) { + DPAA2_PMD_ERR("%p:Rx deferred start not supported", + (void *)dev); + return -EINVAL; + } + if (!priv->bp_list || priv->bp_list->mp != mb_pool) { bpid = mempool_to_bpid(mb_pool); ret = dpaa2_attach_bp_list(priv, @@ -526,12 +679,28 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, dpaa2_q->bp_array = rte_dpaa2_bpid_info; /*Get the flow id from given VQ id*/ - flow_id = rx_queue_id % priv->nb_rx_queues; + flow_id = dpaa2_q->flow_id; memset(&cfg, 0, sizeof(struct dpni_queue)); options = options | DPNI_QUEUE_OPT_USER_CTX; cfg.user_context = (size_t)(dpaa2_q); + /* check if a private cgr available. */ + for (i = 0; i < priv->max_cgs; i++) { + if (!priv->cgid_in_use[i]) { + priv->cgid_in_use[i] = 1; + break; + } + } + + if (i < priv->max_cgs) { + options |= DPNI_QUEUE_OPT_SET_CGID; + cfg.cgid = i; + dpaa2_q->cgid = cfg.cgid; + } else { + dpaa2_q->cgid = 0xff; + } + /*if ls2088 or rev2 device, enable the stashing */ if ((dpaa2_svr_family & 0xffff0000) != SVR_LS2080A) { @@ -560,15 +729,56 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, struct dpni_taildrop taildrop; taildrop.enable = 1; - /*enabling per rx queue congestion control */ - taildrop.threshold = CONG_THRESHOLD_RX_Q; - taildrop.units = DPNI_CONGESTION_UNIT_BYTES; - taildrop.oal = CONG_RX_OAL; - DPAA2_PMD_DEBUG("Enabling Early Drop on queue = %d", - rx_queue_id); - ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, + + /* Private CGR will use tail drop length as nb_rx_desc. + * for rest cases we can use standard byte based tail drop. + * There is no HW restriction, but number of CGRs are limited, + * hence this restriction is placed. + */ + if (dpaa2_q->cgid != 0xff) { + /*enabling per rx queue congestion control */ + taildrop.threshold = nb_rx_desc; + taildrop.units = DPNI_CONGESTION_UNIT_FRAMES; + taildrop.oal = 0; + DPAA2_PMD_DEBUG("Enabling CG Tail Drop on queue = %d", + rx_queue_id); + ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, + DPNI_CP_CONGESTION_GROUP, + DPNI_QUEUE_RX, + dpaa2_q->tc_index, + dpaa2_q->cgid, &taildrop); + } else { + /*enabling per rx queue congestion control */ + taildrop.threshold = CONG_THRESHOLD_RX_BYTES_Q; + taildrop.units = DPNI_CONGESTION_UNIT_BYTES; + taildrop.oal = CONG_RX_OAL; + DPAA2_PMD_DEBUG("Enabling Byte based Drop on queue= %d", + rx_queue_id); + ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, + DPNI_CP_QUEUE, DPNI_QUEUE_RX, + dpaa2_q->tc_index, flow_id, + &taildrop); + } + if (ret) { + DPAA2_PMD_ERR("Error in setting taildrop. err=(%d)", + ret); + return -1; + } + } else { /* Disable tail Drop */ + struct dpni_taildrop taildrop = {0}; + DPAA2_PMD_INFO("Tail drop is disabled on queue"); + + taildrop.enable = 0; + if (dpaa2_q->cgid != 0xff) { + ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, + DPNI_CP_CONGESTION_GROUP, DPNI_QUEUE_RX, + dpaa2_q->tc_index, + dpaa2_q->cgid, &taildrop); + } else { + ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, DPNI_CP_QUEUE, DPNI_QUEUE_RX, dpaa2_q->tc_index, flow_id, &taildrop); + } if (ret) { DPAA2_PMD_ERR("Error in setting taildrop. err=(%d)", ret); @@ -583,22 +793,32 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, static int dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, - uint16_t nb_tx_desc __rte_unused, + uint16_t nb_tx_desc, unsigned int socket_id __rte_unused, - const struct rte_eth_txconf *tx_conf __rte_unused) + const struct rte_eth_txconf *tx_conf) { struct dpaa2_dev_priv *priv = dev->data->dev_private; struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *) priv->tx_vq[tx_queue_id]; - struct fsl_mc_io *dpni = priv->hw; + struct dpaa2_queue *dpaa2_tx_conf_q = (struct dpaa2_queue *) + priv->tx_conf_vq[tx_queue_id]; + struct fsl_mc_io *dpni = dev->process_private; struct dpni_queue tx_conf_cfg; struct dpni_queue tx_flow_cfg; uint8_t options = 0, flow_id; + struct dpni_queue_id qid; uint32_t tc_id; int ret; PMD_INIT_FUNC_TRACE(); + /* Tx deferred start is not supported */ + if (tx_conf->tx_deferred_start) { + DPAA2_PMD_ERR("%p:Tx deferred start not supported", + (void *)dev); + return -EINVAL; + } + /* Return if queue already configured */ if (dpaa2_q->flow_id != 0xffff) { dev->data->tx_queues[tx_queue_id] = dpaa2_q; @@ -612,11 +832,11 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, flow_id = 0; ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX, - tc_id, flow_id, options, &tx_flow_cfg); + tc_id, flow_id, options, &tx_flow_cfg); if (ret) { DPAA2_PMD_ERR("Error in setting the tx flow: " - "tc_id=%d, flow=%d err=%d", - tc_id, flow_id, ret); + "tc_id=%d, flow=%d err=%d", + tc_id, flow_id, ret); return -1; } @@ -624,9 +844,14 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, if (tx_queue_id == 0) { /*Set tx-conf and error configuration*/ - ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW, - priv->token, - DPNI_CONF_DISABLE); + if (priv->tx_conf_en) + ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW, + priv->token, + DPNI_CONF_AFFINE); + else + ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW, + priv->token, + DPNI_CONF_DISABLE); if (ret) { DPAA2_PMD_ERR("Error in set tx conf mode settings: " "err=%d", ret); @@ -635,15 +860,24 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, } dpaa2_q->tc_index = tc_id; + ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token, + DPNI_QUEUE_TX, dpaa2_q->tc_index, + dpaa2_q->flow_id, &tx_flow_cfg, &qid); + if (ret) { + DPAA2_PMD_ERR("Error in getting LFQID err=%d", ret); + return -1; + } + dpaa2_q->fqid = qid.fqid; + if (!(priv->flags & DPAA2_TX_CGR_OFF)) { - struct dpni_congestion_notification_cfg cong_notif_cfg; + struct dpni_congestion_notification_cfg cong_notif_cfg = {0}; cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES; - cong_notif_cfg.threshold_entry = CONG_ENTER_TX_THRESHOLD; + cong_notif_cfg.threshold_entry = nb_tx_desc; /* Notify that the queue is not congested when the data in * the queue is below this thershold. */ - cong_notif_cfg.threshold_exit = CONG_EXIT_TX_THRESHOLD; + cong_notif_cfg.threshold_exit = nb_tx_desc - 24; cong_notif_cfg.message_ctx = 0; cong_notif_cfg.message_iova = (size_t)DPAA2_VADDR_TO_IOVA(dpaa2_q->cscn); @@ -652,6 +886,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, DPNI_CONG_OPT_WRITE_MEM_ON_ENTER | DPNI_CONG_OPT_WRITE_MEM_ON_EXIT | DPNI_CONG_OPT_COHERENT_WRITE; + cong_notif_cfg.cg_point = DPNI_CP_QUEUE; ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW, priv->token, @@ -667,13 +902,61 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, } dpaa2_q->cb_eqresp_free = dpaa2_dev_free_eqresp_buf; dev->data->tx_queues[tx_queue_id] = dpaa2_q; + + if (priv->tx_conf_en) { + dpaa2_q->tx_conf_queue = dpaa2_tx_conf_q; + options = options | DPNI_QUEUE_OPT_USER_CTX; + tx_conf_cfg.user_context = (size_t)(dpaa2_q); + ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, + DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index, + dpaa2_tx_conf_q->flow_id, options, &tx_conf_cfg); + if (ret) { + DPAA2_PMD_ERR("Error in setting the tx conf flow: " + "tc_index=%d, flow=%d err=%d", + dpaa2_tx_conf_q->tc_index, + dpaa2_tx_conf_q->flow_id, ret); + return -1; + } + + ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token, + DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index, + dpaa2_tx_conf_q->flow_id, &tx_conf_cfg, &qid); + if (ret) { + DPAA2_PMD_ERR("Error in getting LFQID err=%d", ret); + return -1; + } + dpaa2_tx_conf_q->fqid = qid.fqid; + } return 0; } static void dpaa2_dev_rx_queue_release(void *q __rte_unused) { + struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)q; + struct dpaa2_dev_priv *priv = dpaa2_q->eth_data->dev_private; + struct fsl_mc_io *dpni = + (struct fsl_mc_io *)priv->eth_dev->process_private; + uint8_t options = 0; + int ret; + struct dpni_queue cfg; + + memset(&cfg, 0, sizeof(struct dpni_queue)); PMD_INIT_FUNC_TRACE(); + if (dpaa2_q->cgid != 0xff) { + options = DPNI_QUEUE_OPT_CLEAR_CGID; + cfg.cgid = dpaa2_q->cgid; + + ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, + DPNI_QUEUE_RX, + dpaa2_q->tc_index, dpaa2_q->flow_id, + options, &cfg); + if (ret) + DPAA2_PMD_ERR("Unable to clear CGR from q=%u err=%d", + dpaa2_q->fqid, ret); + priv->cgid_in_use[dpaa2_q->cgid] = 0; + dpaa2_q->cgid = 0xff; + } } static void @@ -692,12 +975,12 @@ dpaa2_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) struct qbman_fq_query_np_rslt state; uint32_t frame_cnt = 0; - PMD_INIT_FUNC_TRACE(); - if (unlikely(!DPAA2_PER_LCORE_DPIO)) { ret = dpaa2_affine_qbman_swp(); if (ret) { - DPAA2_PMD_ERR("Failure in affining portal"); + DPAA2_PMD_ERR( + "Failed to allocate IO portal, tid: %d\n", + rte_gettid()); return -EINVAL; } } @@ -707,7 +990,7 @@ dpaa2_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) if (qbman_fq_query_state(swp, dpaa2_q->fqid, &state) == 0) { frame_cnt = qbman_fq_state_frame_count(&state); - DPAA2_PMD_DEBUG("RX frame count for q(%d) is %u", + DPAA2_PMD_DP_DEBUG("RX frame count for q(%d) is %u", rx_queue_id, frame_cnt); } return frame_cnt; @@ -730,7 +1013,9 @@ dpaa2_supported_ptypes_get(struct rte_eth_dev *dev) RTE_PTYPE_UNKNOWN }; - if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx) + if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx || + dev->rx_pkt_burst == dpaa2_dev_rx || + dev->rx_pkt_burst == dpaa2_dev_loopback_rx) return ptypes; return NULL; } @@ -749,7 +1034,7 @@ dpaa2_interrupt_handler(void *param) { struct rte_eth_dev *dev = param; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int ret; int irq_index = DPNI_IRQ_INDEX; unsigned int status = 0, clear = 0; @@ -788,7 +1073,7 @@ dpaa2_eth_setup_irqs(struct rte_eth_dev *dev, int enable) { int err = 0; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int irq_index = DPNI_IRQ_INDEX; unsigned int mask = DPNI_IRQ_EVENT_LINK_CHANGED; @@ -818,7 +1103,7 @@ dpaa2_dev_start(struct rte_eth_dev *dev) struct rte_dpaa2_device *dpaa2_dev; struct rte_eth_dev_data *data = dev->data; struct dpaa2_dev_priv *priv = data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct dpni_queue cfg; struct dpni_error_cfg err_cfg; uint16_t qdid; @@ -865,6 +1150,7 @@ dpaa2_dev_start(struct rte_eth_dev *dev) /*checksum errors, send them to normal path and set it in annotation */ err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE; + err_cfg.errors |= DPNI_ERROR_PHE; err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE; err_cfg.set_frame_annotation = true; @@ -910,7 +1196,7 @@ static void dpaa2_dev_stop(struct rte_eth_dev *dev) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int ret; struct rte_eth_link link; struct rte_intr_handle *intr_handle = dev->intr_handle; @@ -950,12 +1236,14 @@ static void dpaa2_dev_close(struct rte_eth_dev *dev) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int ret; struct rte_eth_link link; PMD_INIT_FUNC_TRACE(); + dpaa2_flow_clean(dev); + /* Clean the device first */ ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token); if (ret) { @@ -967,19 +1255,19 @@ dpaa2_dev_close(struct rte_eth_dev *dev) rte_eth_linkstatus_set(dev, &link); } -static void +static int dpaa2_dev_promiscuous_enable( struct rte_eth_dev *dev) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); - return; + return -ENODEV; } ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); @@ -989,21 +1277,23 @@ dpaa2_dev_promiscuous_enable( ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); if (ret < 0) DPAA2_PMD_ERR("Unable to enable M promisc mode %d", ret); + + return ret; } -static void +static int dpaa2_dev_promiscuous_disable( struct rte_eth_dev *dev) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); - return; + return -ENODEV; } ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); @@ -1017,49 +1307,55 @@ dpaa2_dev_promiscuous_disable( DPAA2_PMD_ERR("Unable to disable M promisc mode %d", ret); } + + return ret; } -static void +static int dpaa2_dev_allmulticast_enable( struct rte_eth_dev *dev) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); - return; + return -ENODEV; } ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); if (ret < 0) DPAA2_PMD_ERR("Unable to enable multicast mode %d", ret); + + return ret; } -static void +static int dpaa2_dev_allmulticast_disable(struct rte_eth_dev *dev) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); - return; + return -ENODEV; } /* must remain on for all promiscuous */ if (dev->data->promiscuous == 1) - return; + return 0; ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); if (ret < 0) DPAA2_PMD_ERR("Unable to disable multicast mode %d", ret); + + return ret; } static int @@ -1067,8 +1363,8 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; - uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; + uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + VLAN_TAG_SIZE; PMD_INIT_FUNC_TRACE(); @@ -1079,11 +1375,11 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) } /* check that mtu is within the allowed range */ - if ((mtu < ETHER_MIN_MTU) || (frame_size > DPAA2_MAX_RX_PKT_LEN)) + if (mtu < RTE_ETHER_MIN_MTU || frame_size > DPAA2_MAX_RX_PKT_LEN) return -EINVAL; - if (frame_size > ETHER_MAX_LEN) - dev->data->dev_conf.rxmode.offloads &= + if (frame_size > RTE_ETHER_MAX_LEN) + dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else dev->data->dev_conf.rxmode.offloads &= @@ -1095,7 +1391,7 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) * Maximum Ethernet header length */ ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token, - frame_size); + frame_size - RTE_ETHER_CRC_LEN); if (ret) { DPAA2_PMD_ERR("Setting the max frame length failed"); return -1; @@ -1106,13 +1402,13 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) static int dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev, - struct ether_addr *addr, + struct rte_ether_addr *addr, __rte_unused uint32_t index, __rte_unused uint32_t pool) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); @@ -1121,8 +1417,8 @@ dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev, return -1; } - ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW, - priv->token, addr->addr_bytes); + ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW, priv->token, + addr->addr_bytes, 0, 0, 0); if (ret) DPAA2_PMD_ERR( "error: Adding the MAC ADDR failed: err = %d", ret); @@ -1135,9 +1431,9 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev, { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct rte_eth_dev_data *data = dev->data; - struct ether_addr *macaddr; + struct rte_ether_addr *macaddr; PMD_INIT_FUNC_TRACE(); @@ -1157,11 +1453,11 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev, static int dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev, - struct ether_addr *addr) + struct rte_ether_addr *addr) { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; PMD_INIT_FUNC_TRACE(); @@ -1185,7 +1481,7 @@ int dpaa2_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int32_t retcode; uint8_t page0 = 0, page1 = 1, page2 = 2; union dpni_statistics value; @@ -1265,9 +1561,9 @@ dpaa2_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned int n) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; int32_t retcode; - union dpni_statistics value[3] = {}; + union dpni_statistics value[5] = {}; unsigned int i = 0, num = RTE_DIM(dpaa2_xstats_strings); if (n < num) @@ -1294,6 +1590,18 @@ dpaa2_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, if (retcode) goto err; + for (i = 0; i < priv->max_cgs; i++) { + if (!priv->cgid_in_use[i]) { + /* Get Counters from page_4*/ + retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, + priv->token, + 4, 0, &value[4]); + if (retcode) + goto err; + break; + } + } + for (i = 0; i < num; i++) { xstats[i].id = i; xstats[i].value = value[dpaa2_xstats_strings[i].page_id]. @@ -1317,10 +1625,9 @@ dpaa2_xstats_get_names(__rte_unused struct rte_eth_dev *dev, if (xstats_names != NULL) for (i = 0; i < stat_cnt; i++) - snprintf(xstats_names[i].name, - sizeof(xstats_names[i].name), - "%s", - dpaa2_xstats_strings[i].name); + strlcpy(xstats_names[i].name, + dpaa2_xstats_strings[i].name, + sizeof(xstats_names[i].name)); return stat_cnt; } @@ -1334,9 +1641,10 @@ dpaa2_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, if (!ids) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = + (struct fsl_mc_io *)dev->process_private; int32_t retcode; - union dpni_statistics value[3] = {}; + union dpni_statistics value[5] = {}; if (n < stat_cnt) return stat_cnt; @@ -1362,6 +1670,12 @@ dpaa2_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, if (retcode) return 0; + /* Get Counters from page_4*/ + retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, + 4, 0, &value[4]); + if (retcode) + return 0; + for (i = 0; i < stat_cnt; i++) { values[i] = value[dpaa2_xstats_strings[i].page_id]. raw.counter[dpaa2_xstats_strings[i].stats_id]; @@ -1406,12 +1720,12 @@ dpaa2_xstats_get_names_by_id( return limit; } -static void +static int dpaa2_dev_stats_reset(struct rte_eth_dev *dev) { struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; - int32_t retcode; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; + int retcode; int i; struct dpaa2_queue *dpaa2_q; @@ -1419,7 +1733,7 @@ dpaa2_dev_stats_reset(struct rte_eth_dev *dev) if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); - return; + return -EINVAL; } retcode = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token); @@ -1439,11 +1753,11 @@ dpaa2_dev_stats_reset(struct rte_eth_dev *dev) dpaa2_q->tx_pkts = 0; } - return; + return 0; error: DPAA2_PMD_ERR("Operation not completed:Error Code = %d", retcode); - return; + return retcode; }; /* return 0 means link status changed, -1 means not changed */ @@ -1453,7 +1767,7 @@ dpaa2_dev_link_update(struct rte_eth_dev *dev, { int ret; struct dpaa2_dev_priv *priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct rte_eth_link link; struct dpni_link_state state = {0}; @@ -1501,7 +1815,7 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) struct dpni_link_state state = {0}; priv = dev->data->dev_private; - dpni = (struct fsl_mc_io *)priv->hw; + dpni = (struct fsl_mc_io *)dev->process_private; if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); @@ -1533,6 +1847,7 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) /* changing tx burst function to start enqueues */ dev->tx_pkt_burst = dpaa2_dev_tx; dev->data->dev_link.link_status = state.up; + dev->data->dev_link.link_speed = state.rate; if (state.up) DPAA2_PMD_INFO("Port %d Link is Up", dev->data->port_id); @@ -1557,7 +1872,7 @@ dpaa2_dev_set_link_down(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); priv = dev->data->dev_private; - dpni = (struct fsl_mc_io *)priv->hw; + dpni = (struct fsl_mc_io *)dev->process_private; if (dpni == NULL) { DPAA2_PMD_ERR("Device has not yet been configured"); @@ -1611,7 +1926,7 @@ dpaa2_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) PMD_INIT_FUNC_TRACE(); priv = dev->data->dev_private; - dpni = (struct fsl_mc_io *)priv->hw; + dpni = (struct fsl_mc_io *)dev->process_private; if (dpni == NULL || fc_conf == NULL) { DPAA2_PMD_ERR("device not configured"); @@ -1667,7 +1982,7 @@ dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) PMD_INIT_FUNC_TRACE(); priv = dev->data->dev_private; - dpni = (struct fsl_mc_io *)priv->hw; + dpni = (struct fsl_mc_io *)dev->process_private; if (dpni == NULL) { DPAA2_PMD_ERR("dpni is NULL"); @@ -1746,22 +2061,31 @@ dpaa2_dev_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct rte_eth_dev_data *data = dev->data; + struct dpaa2_dev_priv *priv = data->dev_private; struct rte_eth_conf *eth_conf = &data->dev_conf; - int ret; + int ret, tc_index; PMD_INIT_FUNC_TRACE(); if (rss_conf->rss_hf) { - ret = dpaa2_setup_flow_dist(dev, rss_conf->rss_hf); - if (ret) { - DPAA2_PMD_ERR("Unable to set flow dist"); - return ret; + for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) { + ret = dpaa2_setup_flow_dist(dev, rss_conf->rss_hf, + tc_index); + if (ret) { + DPAA2_PMD_ERR("Unable to set flow dist on tc%d", + tc_index); + return ret; + } } } else { - ret = dpaa2_remove_flow_dist(dev, 0); - if (ret) { - DPAA2_PMD_ERR("Unable to remove flow dist"); - return ret; + for (tc_index = 0; tc_index < priv->num_rx_tc; tc_index++) { + ret = dpaa2_remove_flow_dist(dev, tc_index); + if (ret) { + DPAA2_PMD_ERR( + "Unable to remove flow dist on tc%d", + tc_index); + return ret; + } } } eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_conf->rss_hf; @@ -1783,15 +2107,15 @@ dpaa2_dev_rss_hash_conf_get(struct rte_eth_dev *dev, int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev, int eth_rx_queue_id, - uint16_t dpcon_id, + struct dpaa2_dpcon_dev *dpcon, const struct rte_event_eth_rx_adapter_queue_conf *queue_conf) { struct dpaa2_dev_priv *eth_priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)eth_priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id]; uint8_t flow_id = dpaa2_ethq->flow_id; struct dpni_queue cfg; - uint8_t options; + uint8_t options, priority; int ret; if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL) @@ -1803,11 +2127,14 @@ int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev, else return -EINVAL; + priority = (RTE_EVENT_DEV_PRIORITY_LOWEST / queue_conf->ev.priority) * + (dpcon->num_priorities - 1); + memset(&cfg, 0, sizeof(struct dpni_queue)); options = DPNI_QUEUE_OPT_DEST; cfg.destination.type = DPNI_DEST_DPCON; - cfg.destination.id = dpcon_id; - cfg.destination.priority = queue_conf->ev.priority; + cfg.destination.id = dpcon->dpcon_id; + cfg.destination.priority = priority; if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC) { options |= DPNI_QUEUE_OPT_HOLD_ACTIVE; @@ -1868,7 +2195,7 @@ int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev, int eth_rx_queue_id) { struct dpaa2_dev_priv *eth_priv = dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)eth_priv->hw; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id]; uint8_t flow_id = dpaa2_ethq->flow_id; struct dpni_queue cfg; @@ -1887,6 +2214,47 @@ int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev, return ret; } +static inline int +dpaa2_dev_verify_filter_ops(enum rte_filter_op filter_op) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(dpaa2_supported_filter_ops); i++) { + if (dpaa2_supported_filter_ops[i] == filter_op) + return 0; + } + return -ENOTSUP; +} + +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) +{ + int ret = 0; + + if (!dev) + return -ENODEV; + + switch (filter_type) { + case RTE_ETH_FILTER_GENERIC: + if (dpaa2_dev_verify_filter_ops(filter_op) < 0) { + ret = -ENOTSUP; + break; + } + *(const void **)arg = &dpaa2_flow_ops; + dpaa2_filter_type |= filter_type; + break; + default: + RTE_LOG(ERR, PMD, "Filter type (%d) not supported", + filter_type); + ret = -ENOTSUP; + break; + } + return ret; +} + static struct eth_dev_ops dpaa2_ethdev_ops = { .dev_configure = dpaa2_eth_dev_configure, .dev_start = dpaa2_dev_start, @@ -1917,6 +2285,8 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { .rx_queue_release = dpaa2_dev_rx_queue_release, .tx_queue_setup = dpaa2_dev_tx_queue_setup, .tx_queue_release = dpaa2_dev_tx_queue_release, + .rx_burst_mode_get = dpaa2_dev_rx_burst_mode_get, + .tx_burst_mode_get = dpaa2_dev_tx_burst_mode_get, .rx_queue_count = dpaa2_dev_rx_queue_count, .flow_ctrl_get = dpaa2_flow_ctrl_get, .flow_ctrl_set = dpaa2_flow_ctrl_set, @@ -1925,6 +2295,16 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { .mac_addr_set = dpaa2_dev_set_mac_addr, .rss_hash_update = dpaa2_dev_rss_hash_update, .rss_hash_conf_get = dpaa2_dev_rss_hash_conf_get, + .filter_ctrl = dpaa2_dev_flow_ctrl, +#if defined(RTE_LIBRTE_IEEE1588) + .timesync_enable = dpaa2_timesync_enable, + .timesync_disable = dpaa2_timesync_disable, + .timesync_read_time = dpaa2_timesync_read_time, + .timesync_write_time = dpaa2_timesync_write_time, + .timesync_adjust_time = dpaa2_timesync_adjust_time, + .timesync_read_rx_timestamp = dpaa2_timesync_read_rx_timestamp, + .timesync_read_tx_timestamp = dpaa2_timesync_read_tx_timestamp, +#endif }; /* Populate the mac address from physically available (u-boot/firmware) and/or @@ -1933,13 +2313,13 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { */ static int populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv, - struct ether_addr *mac_entry) + struct rte_ether_addr *mac_entry) { int ret; - struct ether_addr phy_mac, prime_mac; + struct rte_ether_addr phy_mac, prime_mac; - memset(&phy_mac, 0, sizeof(struct ether_addr)); - memset(&prime_mac, 0, sizeof(struct ether_addr)); + memset(&phy_mac, 0, sizeof(struct rte_ether_addr)); + memset(&prime_mac, 0, sizeof(struct rte_ether_addr)); /* Get the physical device MAC address */ ret = dpni_get_port_mac_addr(dpni_dev, CMD_PRI_LOW, priv->token, @@ -1962,9 +2342,9 @@ populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv, * If empty_mac(phy), return prime. * if both are empty, create random MAC, set as prime and return */ - if (!is_zero_ether_addr(&phy_mac)) { + if (!rte_is_zero_ether_addr(&phy_mac)) { /* If the addresses are not same, overwrite prime */ - if (!is_same_ether_addr(&phy_mac, &prime_mac)) { + if (!rte_is_same_ether_addr(&phy_mac, &prime_mac)) { ret = dpni_set_primary_mac_addr(dpni_dev, CMD_PRI_LOW, priv->token, phy_mac.addr_bytes); @@ -1973,11 +2353,12 @@ populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv, ret); goto cleanup; } - memcpy(&prime_mac, &phy_mac, sizeof(struct ether_addr)); + memcpy(&prime_mac, &phy_mac, + sizeof(struct rte_ether_addr)); } - } else if (is_zero_ether_addr(&prime_mac)) { + } else if (rte_is_zero_ether_addr(&prime_mac)) { /* In case phys and prime, both are zero, create random MAC */ - eth_random_addr(prime_mac.addr_bytes); + rte_eth_random_addr(prime_mac.addr_bytes); ret = dpni_set_primary_mac_addr(dpni_dev, CMD_PRI_LOW, priv->token, prime_mac.addr_bytes); @@ -1988,13 +2369,50 @@ populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv, } /* prime_mac the final MAC address */ - memcpy(mac_entry, &prime_mac, sizeof(struct ether_addr)); + memcpy(mac_entry, &prime_mac, sizeof(struct rte_ether_addr)); return 0; cleanup: return -1; } +static int +check_devargs_handler(__rte_unused const char *key, const char *value, + __rte_unused void *opaque) +{ + if (strcmp(value, "1")) + return -1; + + return 0; +} + +static int +dpaa2_get_devargs(struct rte_devargs *devargs, const char *key) +{ + struct rte_kvargs *kvlist; + + if (!devargs) + return 0; + + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (!kvlist) + return 0; + + if (!rte_kvargs_count(kvlist, key)) { + rte_kvargs_free(kvlist); + return 0; + } + + if (rte_kvargs_process(kvlist, key, + check_devargs_handler, NULL) < 0) { + rte_kvargs_free(kvlist); + return 0; + } + rte_kvargs_free(kvlist); + + return 1; +} + static int dpaa2_dev_init(struct rte_eth_dev *eth_dev) { @@ -2004,17 +2422,31 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) struct dpni_attr attr; struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; struct dpni_buffer_layout layout; - int ret, hw_id; + int ret, hw_id, i; PMD_INIT_FUNC_TRACE(); + dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0); + if (!dpni_dev) { + DPAA2_PMD_ERR("Memory allocation failed for dpni device"); + return -1; + } + dpni_dev->regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX); + eth_dev->process_private = (void *)dpni_dev; + /* For secondary processes, the primary has done all the work */ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { /* In case of secondary, only burst and ops API need to be * plugged. */ eth_dev->dev_ops = &dpaa2_ethdev_ops; - eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE)) + eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx; + else if (dpaa2_get_devargs(dev->devargs, + DRIVER_NO_PREFETCH_MODE)) + eth_dev->rx_pkt_burst = dpaa2_dev_rx; + else + eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; eth_dev->tx_pkt_burst = dpaa2_dev_tx; return 0; } @@ -2022,14 +2454,6 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device); hw_id = dpaa2_dev->object_id; - - dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0); - if (!dpni_dev) { - DPAA2_PMD_ERR("Memory allocation failed for dpni device"); - return -1; - } - - dpni_dev->regs = rte_mcp_ptr_list[0]; ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token); if (ret) { DPAA2_PMD_ERR( @@ -2056,19 +2480,28 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) } priv->num_rx_tc = attr.num_rx_tcs; + priv->qos_entries = attr.qos_entries; + priv->fs_entries = attr.fs_entries; + priv->dist_queues = attr.num_queues; - /* Resetting the "num_rx_queues" to equal number of queues in first TC - * as only one TC is supported on Rx Side. Once Multiple TCs will be - * in use for Rx processing then this will be changed or removed. - */ - priv->nb_rx_queues = attr.num_queues; + /* only if the custom CG is enabled */ + if (attr.options & DPNI_OPT_CUSTOM_CG) + priv->max_cgs = attr.num_cgs; + else + priv->max_cgs = 0; + + for (i = 0; i < priv->max_cgs; i++) + priv->cgid_in_use[i] = 0; + + for (i = 0; i < attr.num_rx_tcs; i++) + priv->nb_rx_queues += attr.num_queues; /* Using number of TX queues as number of TX TCs */ priv->nb_tx_queues = attr.num_tx_tcs; - DPAA2_PMD_DEBUG("RX-TC= %d, nb_rx_queues= %d, nb_tx_queues=%d", + DPAA2_PMD_DEBUG("RX-TC= %d, rx_queues= %d, tx_queues=%d, max_cgs=%d", priv->num_rx_tc, priv->nb_rx_queues, - priv->nb_tx_queues); + priv->nb_tx_queues, priv->max_cgs); priv->hw = dpni_dev; priv->hw_id = hw_id; @@ -2076,6 +2509,11 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) priv->max_mac_filters = attr.mac_filter_entries; priv->max_vlan_filters = attr.vlan_filter_entries; priv->flags = 0; +#if defined(RTE_LIBRTE_IEEE1588) + priv->tx_conf_en = 1; +#else + priv->tx_conf_en = 0; +#endif /* Allocate memory for hardware structure for queues */ ret = dpaa2_alloc_rx_tx_queues(eth_dev); @@ -2089,11 +2527,11 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) * can add MAC entries when rte_eth_dev_mac_addr_add is called. */ eth_dev->data->mac_addrs = rte_zmalloc("dpni", - ETHER_ADDR_LEN * attr.mac_filter_entries, 0); + RTE_ETHER_ADDR_LEN * attr.mac_filter_entries, 0); if (eth_dev->data->mac_addrs == NULL) { DPAA2_PMD_ERR( "Failed to allocate %d bytes needed to store MAC addresses", - ETHER_ADDR_LEN * attr.mac_filter_entries); + RTE_ETHER_ADDR_LEN * attr.mac_filter_entries); ret = -ENOMEM; goto init_err; } @@ -2108,7 +2546,13 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) /* ... tx buffer layout ... */ memset(&layout, 0, sizeof(struct dpni_buffer_layout)); - layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; + if (priv->tx_conf_en) { + layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | + DPNI_BUF_LAYOUT_OPT_TIMESTAMP; + layout.pass_timestamp = true; + } else { + layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; + } layout.pass_frame_status = 1; ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX, &layout); @@ -2119,7 +2563,13 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) /* ... tx-conf and error buffer layout ... */ memset(&layout, 0, sizeof(struct dpni_buffer_layout)); - layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; + if (priv->tx_conf_en) { + layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | + DPNI_BUF_LAYOUT_OPT_TIMESTAMP; + layout.pass_timestamp = true; + } else { + layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; + } layout.pass_frame_status = 1; ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX_CONFIRM, &layout); @@ -2131,9 +2581,86 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) eth_dev->dev_ops = &dpaa2_ethdev_ops; - eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE)) { + eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx; + DPAA2_PMD_INFO("Loopback mode"); + } else if (dpaa2_get_devargs(dev->devargs, DRIVER_NO_PREFETCH_MODE)) { + eth_dev->rx_pkt_burst = dpaa2_dev_rx; + DPAA2_PMD_INFO("No Prefetch mode"); + } else { + eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + } eth_dev->tx_pkt_burst = dpaa2_dev_tx; + /*Init fields w.r.t. classficaition*/ + memset(&priv->extract.qos_key_extract, 0, + sizeof(struct dpaa2_key_extract)); + priv->extract.qos_extract_param = (size_t)rte_malloc(NULL, 256, 64); + if (!priv->extract.qos_extract_param) { + DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow " + " classificaiton ", ret); + goto init_err; + } + priv->extract.qos_key_extract.key_info.ipv4_src_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.qos_key_extract.key_info.ipv4_dst_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.qos_key_extract.key_info.ipv6_src_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.qos_key_extract.key_info.ipv6_dst_offset = + IP_ADDRESS_OFFSET_INVALID; + + for (i = 0; i < MAX_TCS; i++) { + memset(&priv->extract.tc_key_extract[i], 0, + sizeof(struct dpaa2_key_extract)); + priv->extract.tc_extract_param[i] = + (size_t)rte_malloc(NULL, 256, 64); + if (!priv->extract.tc_extract_param[i]) { + DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow classificaiton", + ret); + goto init_err; + } + priv->extract.tc_key_extract[i].key_info.ipv4_src_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.tc_key_extract[i].key_info.ipv4_dst_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.tc_key_extract[i].key_info.ipv6_src_offset = + IP_ADDRESS_OFFSET_INVALID; + priv->extract.tc_key_extract[i].key_info.ipv6_dst_offset = + IP_ADDRESS_OFFSET_INVALID; + } + + ret = dpni_set_max_frame_length(dpni_dev, CMD_PRI_LOW, priv->token, + RTE_ETHER_MAX_LEN - RTE_ETHER_CRC_LEN + + VLAN_TAG_SIZE); + if (ret) { + DPAA2_PMD_ERR("Unable to set mtu. check config"); + goto init_err; + } + + /*TODO To enable soft parser support DPAA2 driver needs to integrate + * with external entity to receive byte code for software sequence + * and same will be offload to the H/W using MC interface. + * Currently it is assumed that DPAA2 driver has byte code by some + * mean and same if offloaded to H/W. + */ + if (getenv("DPAA2_ENABLE_SOFT_PARSER")) { + WRIOP_SS_INITIALIZER(priv); + ret = dpaa2_eth_load_wriop_soft_parser(priv, DPNI_SS_INGRESS); + if (ret < 0) { + DPAA2_PMD_ERR(" Error(%d) in loading softparser\n", + ret); + return ret; + } + + ret = dpaa2_eth_enable_wriop_soft_parser(priv, + DPNI_SS_INGRESS); + if (ret < 0) { + DPAA2_PMD_ERR(" Error(%d) in enabling softparser\n", + ret); + return ret; + } + } RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name); return 0; init_err: @@ -2145,8 +2672,8 @@ static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) { struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; - struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; - int ret; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)eth_dev->process_private; + int i, ret; PMD_INIT_FUNC_TRACE(); @@ -2172,8 +2699,15 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) /* Free the allocated memory for ethernet private data and dpni*/ priv->hw = NULL; + eth_dev->process_private = NULL; rte_free(dpni); + for (i = 0; i < MAX_TCS; i++) + rte_free((void *)(size_t)priv->extract.tc_extract_param[i]); + + if (priv->extract.qos_extract_param) + rte_free((void *)(size_t)priv->extract.qos_extract_param); + eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; @@ -2187,26 +2721,42 @@ rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv, struct rte_dpaa2_device *dpaa2_dev) { struct rte_eth_dev *eth_dev; + struct dpaa2_dev_priv *dev_priv; int diag; + if ((DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE) > + RTE_PKTMBUF_HEADROOM) { + DPAA2_PMD_ERR( + "RTE_PKTMBUF_HEADROOM(%d) shall be > DPAA2 Annotation req(%d)", + RTE_PKTMBUF_HEADROOM, + DPAA2_MBUF_HW_ANNOTATION + DPAA2_FD_PTA_SIZE); + + return -1; + } + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name); if (!eth_dev) return -ENODEV; - eth_dev->data->dev_private = rte_zmalloc( - "ethdev private structure", - sizeof(struct dpaa2_dev_priv), - RTE_CACHE_LINE_SIZE); - if (eth_dev->data->dev_private == NULL) { + dev_priv = rte_zmalloc("ethdev private structure", + sizeof(struct dpaa2_dev_priv), + RTE_CACHE_LINE_SIZE); + if (dev_priv == NULL) { DPAA2_PMD_CRIT( "Unable to allocate memory for private data"); rte_eth_dev_release_port(eth_dev); return -ENOMEM; } + eth_dev->data->dev_private = (void *)dev_priv; + /* Store a pointer to eth_dev in dev_private */ + dev_priv->eth_dev = eth_dev; + dev_priv->tx_conf_en = 0; } else { eth_dev = rte_eth_dev_attach_secondary(dpaa2_dev->device.name); - if (!eth_dev) + if (!eth_dev) { + DPAA2_PMD_DEBUG("returning enodev"); return -ENODEV; + } } eth_dev->device = &dpaa2_dev->device; @@ -2249,10 +2799,7 @@ static struct rte_dpaa2_driver rte_dpaa2_pmd = { }; RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd); - -RTE_INIT(dpaa2_pmd_init_log) -{ - dpaa2_logtype_pmd = rte_log_register("pmd.net.dpaa2"); - if (dpaa2_logtype_pmd >= 0) - rte_log_set_level(dpaa2_logtype_pmd, RTE_LOG_NOTICE); -} +RTE_PMD_REGISTER_PARAM_STRING(net_dpaa2, + DRIVER_LOOPBACK_MODE "= " + DRIVER_NO_PREFETCH_MODE "="); +RTE_LOG_REGISTER(dpaa2_logtype_pmd, pmd.net.dpaa2, NOTICE);