1c147eae0SHemant Agrawal /*- 2c147eae0SHemant Agrawal * BSD LICENSE 3c147eae0SHemant Agrawal * 4c147eae0SHemant Agrawal * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. 5fcee050aSShreyansh Jain * Copyright 2016 NXP. 6c147eae0SHemant Agrawal * 7c147eae0SHemant Agrawal * Redistribution and use in source and binary forms, with or without 8c147eae0SHemant Agrawal * modification, are permitted provided that the following conditions 9c147eae0SHemant Agrawal * are met: 10c147eae0SHemant Agrawal * 11c147eae0SHemant Agrawal * * Redistributions of source code must retain the above copyright 12c147eae0SHemant Agrawal * notice, this list of conditions and the following disclaimer. 13c147eae0SHemant Agrawal * * Redistributions in binary form must reproduce the above copyright 14c147eae0SHemant Agrawal * notice, this list of conditions and the following disclaimer in 15c147eae0SHemant Agrawal * the documentation and/or other materials provided with the 16c147eae0SHemant Agrawal * distribution. 17c147eae0SHemant Agrawal * * Neither the name of Freescale Semiconductor, Inc nor the names of its 18c147eae0SHemant Agrawal * contributors may be used to endorse or promote products derived 19c147eae0SHemant Agrawal * from this software without specific prior written permission. 20c147eae0SHemant Agrawal * 21c147eae0SHemant Agrawal * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22c147eae0SHemant Agrawal * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23c147eae0SHemant Agrawal * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24c147eae0SHemant Agrawal * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25c147eae0SHemant Agrawal * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26c147eae0SHemant Agrawal * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27c147eae0SHemant Agrawal * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28c147eae0SHemant Agrawal * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29c147eae0SHemant Agrawal * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30c147eae0SHemant Agrawal * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31c147eae0SHemant Agrawal * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32c147eae0SHemant Agrawal */ 33c147eae0SHemant Agrawal 34c147eae0SHemant Agrawal #include <time.h> 35c147eae0SHemant Agrawal #include <net/if.h> 36c147eae0SHemant Agrawal 37c147eae0SHemant Agrawal #include <rte_mbuf.h> 38c147eae0SHemant Agrawal #include <rte_ethdev.h> 39c147eae0SHemant Agrawal #include <rte_malloc.h> 40c147eae0SHemant Agrawal #include <rte_memcpy.h> 41c147eae0SHemant Agrawal #include <rte_string_fns.h> 42c147eae0SHemant Agrawal #include <rte_cycles.h> 43c147eae0SHemant Agrawal #include <rte_kvargs.h> 44c147eae0SHemant Agrawal #include <rte_dev.h> 45c147eae0SHemant Agrawal #include <rte_fslmc.h> 46c147eae0SHemant Agrawal 47d401ead1SHemant Agrawal #include <fslmc_logs.h> 48c147eae0SHemant Agrawal #include <fslmc_vfio.h> 493e5a335dSHemant Agrawal #include <dpaa2_hw_pvt.h> 50bee61d86SHemant Agrawal #include <dpaa2_hw_mempool.h> 513cf50ff5SHemant Agrawal #include <dpaa2_hw_dpio.h> 52748eccb9SHemant Agrawal #include <mc/fsl_dpmng.h> 53c147eae0SHemant Agrawal #include "dpaa2_ethdev.h" 54c147eae0SHemant Agrawal 55c147eae0SHemant Agrawal static struct rte_dpaa2_driver rte_dpaa2_pmd; 56d4984046SHemant Agrawal static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev); 57a1f3a12cSHemant Agrawal static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev); 58a1f3a12cSHemant Agrawal static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev); 59e1640849SHemant Agrawal static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 60c147eae0SHemant Agrawal 61c56c86ffSHemant Agrawal /** 62c56c86ffSHemant Agrawal * Atomically reads the link status information from global 63c56c86ffSHemant Agrawal * structure rte_eth_dev. 64c56c86ffSHemant Agrawal * 65c56c86ffSHemant Agrawal * @param dev 66c56c86ffSHemant Agrawal * - Pointer to the structure rte_eth_dev to read from. 67c56c86ffSHemant Agrawal * - Pointer to the buffer to be saved with the link status. 68c56c86ffSHemant Agrawal * 69c56c86ffSHemant Agrawal * @return 70c56c86ffSHemant Agrawal * - On success, zero. 71c56c86ffSHemant Agrawal * - On failure, negative value. 72c56c86ffSHemant Agrawal */ 73c56c86ffSHemant Agrawal static inline int 74c56c86ffSHemant Agrawal dpaa2_dev_atomic_read_link_status(struct rte_eth_dev *dev, 75c56c86ffSHemant Agrawal struct rte_eth_link *link) 76c56c86ffSHemant Agrawal { 77c56c86ffSHemant Agrawal struct rte_eth_link *dst = link; 78c56c86ffSHemant Agrawal struct rte_eth_link *src = &dev->data->dev_link; 79c56c86ffSHemant Agrawal 80c56c86ffSHemant Agrawal if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 81c56c86ffSHemant Agrawal *(uint64_t *)src) == 0) 82c56c86ffSHemant Agrawal return -1; 83c56c86ffSHemant Agrawal 84c56c86ffSHemant Agrawal return 0; 85c56c86ffSHemant Agrawal } 86c56c86ffSHemant Agrawal 87c56c86ffSHemant Agrawal /** 88c56c86ffSHemant Agrawal * Atomically writes the link status information into global 89c56c86ffSHemant Agrawal * structure rte_eth_dev. 90c56c86ffSHemant Agrawal * 91c56c86ffSHemant Agrawal * @param dev 92c56c86ffSHemant Agrawal * - Pointer to the structure rte_eth_dev to read from. 93c56c86ffSHemant Agrawal * - Pointer to the buffer to be saved with the link status. 94c56c86ffSHemant Agrawal * 95c56c86ffSHemant Agrawal * @return 96c56c86ffSHemant Agrawal * - On success, zero. 97c56c86ffSHemant Agrawal * - On failure, negative value. 98c56c86ffSHemant Agrawal */ 99c56c86ffSHemant Agrawal static inline int 100c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(struct rte_eth_dev *dev, 101c56c86ffSHemant Agrawal struct rte_eth_link *link) 102c56c86ffSHemant Agrawal { 103c56c86ffSHemant Agrawal struct rte_eth_link *dst = &dev->data->dev_link; 104c56c86ffSHemant Agrawal struct rte_eth_link *src = link; 105c56c86ffSHemant Agrawal 106c56c86ffSHemant Agrawal if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 107c56c86ffSHemant Agrawal *(uint64_t *)src) == 0) 108c56c86ffSHemant Agrawal return -1; 109c56c86ffSHemant Agrawal 110c56c86ffSHemant Agrawal return 0; 111c56c86ffSHemant Agrawal } 112c56c86ffSHemant Agrawal 1133ce294f2SHemant Agrawal static int 1143ce294f2SHemant Agrawal dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 1153ce294f2SHemant Agrawal { 1163ce294f2SHemant Agrawal int ret; 1173ce294f2SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1183ce294f2SHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 1193ce294f2SHemant Agrawal 1203ce294f2SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1213ce294f2SHemant Agrawal 1223ce294f2SHemant Agrawal if (dpni == NULL) { 123645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 1243ce294f2SHemant Agrawal return -1; 1253ce294f2SHemant Agrawal } 1263ce294f2SHemant Agrawal 1273ce294f2SHemant Agrawal if (on) 1283ce294f2SHemant Agrawal ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW, 1293ce294f2SHemant Agrawal priv->token, vlan_id); 1303ce294f2SHemant Agrawal else 1313ce294f2SHemant Agrawal ret = dpni_remove_vlan_id(dpni, CMD_PRI_LOW, 1323ce294f2SHemant Agrawal priv->token, vlan_id); 1333ce294f2SHemant Agrawal 1343ce294f2SHemant Agrawal if (ret < 0) 1353ce294f2SHemant Agrawal PMD_DRV_LOG(ERR, "ret = %d Unable to add/rem vlan %d hwid =%d", 1363ce294f2SHemant Agrawal ret, vlan_id, priv->hw_id); 1373ce294f2SHemant Agrawal 1383ce294f2SHemant Agrawal return ret; 1393ce294f2SHemant Agrawal } 1403ce294f2SHemant Agrawal 1413ce294f2SHemant Agrawal static void 1423ce294f2SHemant Agrawal dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) 1433ce294f2SHemant Agrawal { 1443ce294f2SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1453ce294f2SHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 1463ce294f2SHemant Agrawal int ret; 1473ce294f2SHemant Agrawal 1483ce294f2SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1493ce294f2SHemant Agrawal 1503ce294f2SHemant Agrawal if (mask & ETH_VLAN_FILTER_MASK) { 1513ce294f2SHemant Agrawal if (dev->data->dev_conf.rxmode.hw_vlan_filter) 1523ce294f2SHemant Agrawal ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW, 1533ce294f2SHemant Agrawal priv->token, true); 1543ce294f2SHemant Agrawal else 1553ce294f2SHemant Agrawal ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW, 1563ce294f2SHemant Agrawal priv->token, false); 1573ce294f2SHemant Agrawal if (ret < 0) 158645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to set vlan filter = %d\n", 1593ce294f2SHemant Agrawal ret); 1603ce294f2SHemant Agrawal } 1613ce294f2SHemant Agrawal } 1623ce294f2SHemant Agrawal 163748eccb9SHemant Agrawal static int 164748eccb9SHemant Agrawal dpaa2_fw_version_get(struct rte_eth_dev *dev, 165748eccb9SHemant Agrawal char *fw_version, 166748eccb9SHemant Agrawal size_t fw_size) 167748eccb9SHemant Agrawal { 168748eccb9SHemant Agrawal int ret; 169748eccb9SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 170748eccb9SHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 171748eccb9SHemant Agrawal struct mc_soc_version mc_plat_info = {0}; 172748eccb9SHemant Agrawal struct mc_version mc_ver_info = {0}; 173748eccb9SHemant Agrawal 174748eccb9SHemant Agrawal PMD_INIT_FUNC_TRACE(); 175748eccb9SHemant Agrawal 176748eccb9SHemant Agrawal if (mc_get_soc_version(dpni, CMD_PRI_LOW, &mc_plat_info)) 177748eccb9SHemant Agrawal RTE_LOG(WARNING, PMD, "\tmc_get_soc_version failed\n"); 178748eccb9SHemant Agrawal 179748eccb9SHemant Agrawal if (mc_get_version(dpni, CMD_PRI_LOW, &mc_ver_info)) 180748eccb9SHemant Agrawal RTE_LOG(WARNING, PMD, "\tmc_get_version failed\n"); 181748eccb9SHemant Agrawal 182748eccb9SHemant Agrawal ret = snprintf(fw_version, fw_size, 183748eccb9SHemant Agrawal "%x-%d.%d.%d", 184748eccb9SHemant Agrawal mc_plat_info.svr, 185748eccb9SHemant Agrawal mc_ver_info.major, 186748eccb9SHemant Agrawal mc_ver_info.minor, 187748eccb9SHemant Agrawal mc_ver_info.revision); 188748eccb9SHemant Agrawal 189748eccb9SHemant Agrawal ret += 1; /* add the size of '\0' */ 190748eccb9SHemant Agrawal if (fw_size < (uint32_t)ret) 191748eccb9SHemant Agrawal return ret; 192748eccb9SHemant Agrawal else 193748eccb9SHemant Agrawal return 0; 194748eccb9SHemant Agrawal } 195748eccb9SHemant Agrawal 1963e5a335dSHemant Agrawal static void 1973e5a335dSHemant Agrawal dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 1983e5a335dSHemant Agrawal { 1993e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 2003e5a335dSHemant Agrawal 2013e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 2023e5a335dSHemant Agrawal 2033e5a335dSHemant Agrawal dev_info->if_index = priv->hw_id; 2043e5a335dSHemant Agrawal 20533fad432SHemant Agrawal dev_info->max_mac_addrs = priv->max_mac_filters; 206bee61d86SHemant Agrawal dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN; 207bee61d86SHemant Agrawal dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE; 2083e5a335dSHemant Agrawal dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues; 2093e5a335dSHemant Agrawal dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues; 210ef18dafeSHemant Agrawal dev_info->rx_offload_capa = 211ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_IPV4_CKSUM | 212ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_UDP_CKSUM | 213ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_TCP_CKSUM | 214ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; 215ef18dafeSHemant Agrawal dev_info->tx_offload_capa = 216ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_IPV4_CKSUM | 217ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_UDP_CKSUM | 218ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_TCP_CKSUM | 219ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_SCTP_CKSUM | 220ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM; 2213e5a335dSHemant Agrawal dev_info->speed_capa = ETH_LINK_SPEED_1G | 2223e5a335dSHemant Agrawal ETH_LINK_SPEED_2_5G | 2233e5a335dSHemant Agrawal ETH_LINK_SPEED_10G; 2243e5a335dSHemant Agrawal } 2253e5a335dSHemant Agrawal 2263e5a335dSHemant Agrawal static int 2273e5a335dSHemant Agrawal dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) 2283e5a335dSHemant Agrawal { 2293e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 2303e5a335dSHemant Agrawal uint16_t dist_idx; 2313e5a335dSHemant Agrawal uint32_t vq_id; 2323e5a335dSHemant Agrawal struct dpaa2_queue *mc_q, *mcq; 2333e5a335dSHemant Agrawal uint32_t tot_queues; 2343e5a335dSHemant Agrawal int i; 2353e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 2363e5a335dSHemant Agrawal 2373e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 2383e5a335dSHemant Agrawal 2393e5a335dSHemant Agrawal tot_queues = priv->nb_rx_queues + priv->nb_tx_queues; 2403e5a335dSHemant Agrawal mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues, 2413e5a335dSHemant Agrawal RTE_CACHE_LINE_SIZE); 2423e5a335dSHemant Agrawal if (!mc_q) { 2433e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "malloc failed for rx/tx queues\n"); 2443e5a335dSHemant Agrawal return -1; 2453e5a335dSHemant Agrawal } 2463e5a335dSHemant Agrawal 2473e5a335dSHemant Agrawal for (i = 0; i < priv->nb_rx_queues; i++) { 2483e5a335dSHemant Agrawal mc_q->dev = dev; 2493e5a335dSHemant Agrawal priv->rx_vq[i] = mc_q++; 2503e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 2513e5a335dSHemant Agrawal dpaa2_q->q_storage = rte_malloc("dq_storage", 2523e5a335dSHemant Agrawal sizeof(struct queue_storage_info_t), 2533e5a335dSHemant Agrawal RTE_CACHE_LINE_SIZE); 2543e5a335dSHemant Agrawal if (!dpaa2_q->q_storage) 2553e5a335dSHemant Agrawal goto fail; 2563e5a335dSHemant Agrawal 2573e5a335dSHemant Agrawal memset(dpaa2_q->q_storage, 0, 2583e5a335dSHemant Agrawal sizeof(struct queue_storage_info_t)); 2593cf50ff5SHemant Agrawal if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage)) 2603cf50ff5SHemant Agrawal goto fail; 2613e5a335dSHemant Agrawal } 2623e5a335dSHemant Agrawal 2633e5a335dSHemant Agrawal for (i = 0; i < priv->nb_tx_queues; i++) { 2643e5a335dSHemant Agrawal mc_q->dev = dev; 2657ae777d0SHemant Agrawal mc_q->flow_id = 0xffff; 2663e5a335dSHemant Agrawal priv->tx_vq[i] = mc_q++; 2677ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i]; 2687ae777d0SHemant Agrawal dpaa2_q->cscn = rte_malloc(NULL, 2697ae777d0SHemant Agrawal sizeof(struct qbman_result), 16); 2707ae777d0SHemant Agrawal if (!dpaa2_q->cscn) 2717ae777d0SHemant Agrawal goto fail_tx; 2723e5a335dSHemant Agrawal } 2733e5a335dSHemant Agrawal 2743e5a335dSHemant Agrawal vq_id = 0; 275599017a2SHemant Agrawal for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) { 2763e5a335dSHemant Agrawal mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id]; 2773e5a335dSHemant Agrawal mcq->tc_index = DPAA2_DEF_TC; 2783e5a335dSHemant Agrawal mcq->flow_id = dist_idx; 2793e5a335dSHemant Agrawal vq_id++; 2803e5a335dSHemant Agrawal } 2813e5a335dSHemant Agrawal 2823e5a335dSHemant Agrawal return 0; 2837ae777d0SHemant Agrawal fail_tx: 2847ae777d0SHemant Agrawal i -= 1; 2857ae777d0SHemant Agrawal while (i >= 0) { 2867ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i]; 2877ae777d0SHemant Agrawal rte_free(dpaa2_q->cscn); 2887ae777d0SHemant Agrawal priv->tx_vq[i--] = NULL; 2897ae777d0SHemant Agrawal } 2907ae777d0SHemant Agrawal i = priv->nb_rx_queues; 2913e5a335dSHemant Agrawal fail: 2923e5a335dSHemant Agrawal i -= 1; 2933e5a335dSHemant Agrawal mc_q = priv->rx_vq[0]; 2943e5a335dSHemant Agrawal while (i >= 0) { 2953e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 2963cf50ff5SHemant Agrawal dpaa2_free_dq_storage(dpaa2_q->q_storage); 2973e5a335dSHemant Agrawal rte_free(dpaa2_q->q_storage); 2983e5a335dSHemant Agrawal priv->rx_vq[i--] = NULL; 2993e5a335dSHemant Agrawal } 3003e5a335dSHemant Agrawal rte_free(mc_q); 3013e5a335dSHemant Agrawal return -1; 3023e5a335dSHemant Agrawal } 3033e5a335dSHemant Agrawal 3043e5a335dSHemant Agrawal static int 3053e5a335dSHemant Agrawal dpaa2_eth_dev_configure(struct rte_eth_dev *dev) 3063e5a335dSHemant Agrawal { 3073e5a335dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 3083e5a335dSHemant Agrawal struct rte_eth_conf *eth_conf = &data->dev_conf; 30989c2ea8fSHemant Agrawal int ret; 3103e5a335dSHemant Agrawal 3113e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 3123e5a335dSHemant Agrawal 313e1640849SHemant Agrawal if (eth_conf->rxmode.jumbo_frame == 1) { 314e1640849SHemant Agrawal if (eth_conf->rxmode.max_rx_pkt_len <= DPAA2_MAX_RX_PKT_LEN) { 315e1640849SHemant Agrawal ret = dpaa2_dev_mtu_set(dev, 316e1640849SHemant Agrawal eth_conf->rxmode.max_rx_pkt_len); 317e1640849SHemant Agrawal if (ret) { 318e1640849SHemant Agrawal PMD_INIT_LOG(ERR, 319e1640849SHemant Agrawal "unable to set mtu. check config\n"); 320e1640849SHemant Agrawal return ret; 321e1640849SHemant Agrawal } 322e1640849SHemant Agrawal } else { 323e1640849SHemant Agrawal return -1; 324e1640849SHemant Agrawal } 325e1640849SHemant Agrawal } 326e1640849SHemant Agrawal 3273e5a335dSHemant Agrawal /* Check for correct configuration */ 3283e5a335dSHemant Agrawal if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS && 3293e5a335dSHemant Agrawal data->nb_rx_queues > 1) { 3303e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Distribution is not enabled, " 3313e5a335dSHemant Agrawal "but Rx queues more than 1\n"); 3323e5a335dSHemant Agrawal return -1; 3333e5a335dSHemant Agrawal } 3343e5a335dSHemant Agrawal 33589c2ea8fSHemant Agrawal if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) { 33689c2ea8fSHemant Agrawal /* Return in case number of Rx queues is 1 */ 33789c2ea8fSHemant Agrawal if (data->nb_rx_queues == 1) 33889c2ea8fSHemant Agrawal return 0; 33989c2ea8fSHemant Agrawal ret = dpaa2_setup_flow_dist(dev, 34089c2ea8fSHemant Agrawal eth_conf->rx_adv_conf.rss_conf.rss_hf); 34189c2ea8fSHemant Agrawal if (ret) { 34289c2ea8fSHemant Agrawal PMD_INIT_LOG(ERR, "unable to set flow distribution." 34389c2ea8fSHemant Agrawal "please check queue config\n"); 34489c2ea8fSHemant Agrawal return ret; 34589c2ea8fSHemant Agrawal } 34689c2ea8fSHemant Agrawal } 3473e5a335dSHemant Agrawal return 0; 3483e5a335dSHemant Agrawal } 3493e5a335dSHemant Agrawal 3503e5a335dSHemant Agrawal /* Function to setup RX flow information. It contains traffic class ID, 3513e5a335dSHemant Agrawal * flow ID, destination configuration etc. 3523e5a335dSHemant Agrawal */ 3533e5a335dSHemant Agrawal static int 3543e5a335dSHemant Agrawal dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, 3553e5a335dSHemant Agrawal uint16_t rx_queue_id, 3563e5a335dSHemant Agrawal uint16_t nb_rx_desc __rte_unused, 3573e5a335dSHemant Agrawal unsigned int socket_id __rte_unused, 3583e5a335dSHemant Agrawal const struct rte_eth_rxconf *rx_conf __rte_unused, 3593e5a335dSHemant Agrawal struct rte_mempool *mb_pool) 3603e5a335dSHemant Agrawal { 3613e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 3623e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 36330db823eSHemant Agrawal struct mc_soc_version mc_plat_info = {0}; 3643e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 3653e5a335dSHemant Agrawal struct dpni_queue cfg; 3663e5a335dSHemant Agrawal uint8_t options = 0; 3673e5a335dSHemant Agrawal uint8_t flow_id; 368bee61d86SHemant Agrawal uint32_t bpid; 3693e5a335dSHemant Agrawal int ret; 3703e5a335dSHemant Agrawal 3713e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 3723e5a335dSHemant Agrawal 3733e5a335dSHemant Agrawal PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p", 3743e5a335dSHemant Agrawal dev, rx_queue_id, mb_pool, rx_conf); 3753e5a335dSHemant Agrawal 376bee61d86SHemant Agrawal if (!priv->bp_list || priv->bp_list->mp != mb_pool) { 377bee61d86SHemant Agrawal bpid = mempool_to_bpid(mb_pool); 378bee61d86SHemant Agrawal ret = dpaa2_attach_bp_list(priv, 379bee61d86SHemant Agrawal rte_dpaa2_bpid_info[bpid].bp_list); 380bee61d86SHemant Agrawal if (ret) 381bee61d86SHemant Agrawal return ret; 382bee61d86SHemant Agrawal } 3833e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id]; 3843e5a335dSHemant Agrawal dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */ 3853e5a335dSHemant Agrawal 386599017a2SHemant Agrawal /*Get the flow id from given VQ id*/ 387599017a2SHemant Agrawal flow_id = rx_queue_id % priv->nb_rx_queues; 3883e5a335dSHemant Agrawal memset(&cfg, 0, sizeof(struct dpni_queue)); 3893e5a335dSHemant Agrawal 3903e5a335dSHemant Agrawal options = options | DPNI_QUEUE_OPT_USER_CTX; 3913e5a335dSHemant Agrawal cfg.user_context = (uint64_t)(dpaa2_q); 3923e5a335dSHemant Agrawal 39337529eceSHemant Agrawal /*if ls2088 or rev2 device, enable the stashing */ 39430db823eSHemant Agrawal 39530db823eSHemant Agrawal if (mc_get_soc_version(dpni, CMD_PRI_LOW, &mc_plat_info)) 39630db823eSHemant Agrawal PMD_INIT_LOG(ERR, "\tmc_get_soc_version failed\n"); 39730db823eSHemant Agrawal 39830db823eSHemant Agrawal if ((mc_plat_info.svr & 0xffff0000) != SVR_LS2080A) { 39937529eceSHemant Agrawal options |= DPNI_QUEUE_OPT_FLC; 40037529eceSHemant Agrawal cfg.flc.stash_control = true; 40137529eceSHemant Agrawal cfg.flc.value &= 0xFFFFFFFFFFFFFFC0; 40237529eceSHemant Agrawal /* 00 00 00 - last 6 bit represent annotation, context stashing, 40337529eceSHemant Agrawal * data stashing setting 01 01 00 (0x14) to enable 4049464dbe9SHemant Agrawal * 1 line data, 1 line annotation 40537529eceSHemant Agrawal */ 40637529eceSHemant Agrawal cfg.flc.value |= 0x14; 40737529eceSHemant Agrawal } 4083e5a335dSHemant Agrawal ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX, 4093e5a335dSHemant Agrawal dpaa2_q->tc_index, flow_id, options, &cfg); 4103e5a335dSHemant Agrawal if (ret) { 4113e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the rx flow: = %d\n", ret); 4123e5a335dSHemant Agrawal return -1; 4133e5a335dSHemant Agrawal } 4143e5a335dSHemant Agrawal 41523d6a87eSHemant Agrawal if (!(priv->flags & DPAA2_RX_TAILDROP_OFF)) { 41623d6a87eSHemant Agrawal struct dpni_taildrop taildrop; 41723d6a87eSHemant Agrawal 41823d6a87eSHemant Agrawal taildrop.enable = 1; 41923d6a87eSHemant Agrawal /*enabling per rx queue congestion control */ 42023d6a87eSHemant Agrawal taildrop.threshold = CONG_THRESHOLD_RX_Q; 42123d6a87eSHemant Agrawal taildrop.units = DPNI_CONGESTION_UNIT_BYTES; 422*d47f0292SHemant Agrawal taildrop.oal = CONG_RX_OAL; 42323d6a87eSHemant Agrawal PMD_INIT_LOG(DEBUG, "Enabling Early Drop on queue = %d", 42423d6a87eSHemant Agrawal rx_queue_id); 42523d6a87eSHemant Agrawal ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, 42623d6a87eSHemant Agrawal DPNI_CP_QUEUE, DPNI_QUEUE_RX, 42723d6a87eSHemant Agrawal dpaa2_q->tc_index, flow_id, &taildrop); 42823d6a87eSHemant Agrawal if (ret) { 42923d6a87eSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the rx flow" 43023d6a87eSHemant Agrawal " err : = %d\n", ret); 43123d6a87eSHemant Agrawal return -1; 43223d6a87eSHemant Agrawal } 43323d6a87eSHemant Agrawal } 43423d6a87eSHemant Agrawal 4353e5a335dSHemant Agrawal dev->data->rx_queues[rx_queue_id] = dpaa2_q; 4363e5a335dSHemant Agrawal return 0; 4373e5a335dSHemant Agrawal } 4383e5a335dSHemant Agrawal 4393e5a335dSHemant Agrawal static int 4403e5a335dSHemant Agrawal dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, 4413e5a335dSHemant Agrawal uint16_t tx_queue_id, 4423e5a335dSHemant Agrawal uint16_t nb_tx_desc __rte_unused, 4433e5a335dSHemant Agrawal unsigned int socket_id __rte_unused, 4443e5a335dSHemant Agrawal const struct rte_eth_txconf *tx_conf __rte_unused) 4453e5a335dSHemant Agrawal { 4463e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 4473e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *) 4483e5a335dSHemant Agrawal priv->tx_vq[tx_queue_id]; 4493e5a335dSHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 4503e5a335dSHemant Agrawal struct dpni_queue tx_conf_cfg; 4513e5a335dSHemant Agrawal struct dpni_queue tx_flow_cfg; 4523e5a335dSHemant Agrawal uint8_t options = 0, flow_id; 4533e5a335dSHemant Agrawal uint32_t tc_id; 4543e5a335dSHemant Agrawal int ret; 4553e5a335dSHemant Agrawal 4563e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 4573e5a335dSHemant Agrawal 4583e5a335dSHemant Agrawal /* Return if queue already configured */ 4597ae777d0SHemant Agrawal if (dpaa2_q->flow_id != 0xffff) 4603e5a335dSHemant Agrawal return 0; 4613e5a335dSHemant Agrawal 4623e5a335dSHemant Agrawal memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue)); 4633e5a335dSHemant Agrawal memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue)); 4643e5a335dSHemant Agrawal 465ef18dafeSHemant Agrawal tc_id = tx_queue_id; 466ef18dafeSHemant Agrawal flow_id = 0; 4673e5a335dSHemant Agrawal 4683e5a335dSHemant Agrawal ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX, 4693e5a335dSHemant Agrawal tc_id, flow_id, options, &tx_flow_cfg); 4703e5a335dSHemant Agrawal if (ret) { 4713e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the tx flow: " 4723e5a335dSHemant Agrawal "tc_id=%d, flow =%d ErrorCode = %x\n", 4733e5a335dSHemant Agrawal tc_id, flow_id, -ret); 4743e5a335dSHemant Agrawal return -1; 4753e5a335dSHemant Agrawal } 4763e5a335dSHemant Agrawal 4773e5a335dSHemant Agrawal dpaa2_q->flow_id = flow_id; 4783e5a335dSHemant Agrawal 4793e5a335dSHemant Agrawal if (tx_queue_id == 0) { 4803e5a335dSHemant Agrawal /*Set tx-conf and error configuration*/ 4813e5a335dSHemant Agrawal ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW, 4823e5a335dSHemant Agrawal priv->token, 4833e5a335dSHemant Agrawal DPNI_CONF_DISABLE); 4843e5a335dSHemant Agrawal if (ret) { 4853e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in set tx conf mode settings" 4863e5a335dSHemant Agrawal " ErrorCode = %x", ret); 4873e5a335dSHemant Agrawal return -1; 4883e5a335dSHemant Agrawal } 4893e5a335dSHemant Agrawal } 4903e5a335dSHemant Agrawal dpaa2_q->tc_index = tc_id; 4913e5a335dSHemant Agrawal 492a0840963SHemant Agrawal if (!(priv->flags & DPAA2_TX_CGR_OFF)) { 4937ae777d0SHemant Agrawal struct dpni_congestion_notification_cfg cong_notif_cfg; 4947ae777d0SHemant Agrawal 49529dfa62fSHemant Agrawal cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES; 4967ae777d0SHemant Agrawal cong_notif_cfg.threshold_entry = CONG_ENTER_TX_THRESHOLD; 4977ae777d0SHemant Agrawal /* Notify that the queue is not congested when the data in 4987ae777d0SHemant Agrawal * the queue is below this thershold. 4997ae777d0SHemant Agrawal */ 5007ae777d0SHemant Agrawal cong_notif_cfg.threshold_exit = CONG_EXIT_TX_THRESHOLD; 5017ae777d0SHemant Agrawal cong_notif_cfg.message_ctx = 0; 5027ae777d0SHemant Agrawal cong_notif_cfg.message_iova = (uint64_t)dpaa2_q->cscn; 5037ae777d0SHemant Agrawal cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE; 5047ae777d0SHemant Agrawal cong_notif_cfg.notification_mode = 5057ae777d0SHemant Agrawal DPNI_CONG_OPT_WRITE_MEM_ON_ENTER | 5067ae777d0SHemant Agrawal DPNI_CONG_OPT_WRITE_MEM_ON_EXIT | 5077ae777d0SHemant Agrawal DPNI_CONG_OPT_COHERENT_WRITE; 5087ae777d0SHemant Agrawal 5097ae777d0SHemant Agrawal ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW, 5107ae777d0SHemant Agrawal priv->token, 5117ae777d0SHemant Agrawal DPNI_QUEUE_TX, 5127ae777d0SHemant Agrawal tc_id, 5137ae777d0SHemant Agrawal &cong_notif_cfg); 5147ae777d0SHemant Agrawal if (ret) { 5157ae777d0SHemant Agrawal PMD_INIT_LOG(ERR, 5167ae777d0SHemant Agrawal "Error in setting tx congestion notification: = %d", 5177ae777d0SHemant Agrawal -ret); 5187ae777d0SHemant Agrawal return -ret; 5197ae777d0SHemant Agrawal } 5207ae777d0SHemant Agrawal } 5213e5a335dSHemant Agrawal dev->data->tx_queues[tx_queue_id] = dpaa2_q; 5223e5a335dSHemant Agrawal return 0; 5233e5a335dSHemant Agrawal } 5243e5a335dSHemant Agrawal 5253e5a335dSHemant Agrawal static void 5263e5a335dSHemant Agrawal dpaa2_dev_rx_queue_release(void *q __rte_unused) 5273e5a335dSHemant Agrawal { 5283e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 5293e5a335dSHemant Agrawal } 5303e5a335dSHemant Agrawal 5313e5a335dSHemant Agrawal static void 5323e5a335dSHemant Agrawal dpaa2_dev_tx_queue_release(void *q __rte_unused) 5333e5a335dSHemant Agrawal { 5343e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 5353e5a335dSHemant Agrawal } 5363e5a335dSHemant Agrawal 537a5fc38d4SHemant Agrawal static const uint32_t * 538a5fc38d4SHemant Agrawal dpaa2_supported_ptypes_get(struct rte_eth_dev *dev) 539a5fc38d4SHemant Agrawal { 540a5fc38d4SHemant Agrawal static const uint32_t ptypes[] = { 541a5fc38d4SHemant Agrawal /*todo -= add more types */ 542a5fc38d4SHemant Agrawal RTE_PTYPE_L2_ETHER, 543a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV4, 544a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV4_EXT, 545a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV6, 546a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV6_EXT, 547a5fc38d4SHemant Agrawal RTE_PTYPE_L4_TCP, 548a5fc38d4SHemant Agrawal RTE_PTYPE_L4_UDP, 549a5fc38d4SHemant Agrawal RTE_PTYPE_L4_SCTP, 550a5fc38d4SHemant Agrawal RTE_PTYPE_L4_ICMP, 551a5fc38d4SHemant Agrawal RTE_PTYPE_UNKNOWN 552a5fc38d4SHemant Agrawal }; 553a5fc38d4SHemant Agrawal 5545c6942fdSHemant Agrawal if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx) 555a5fc38d4SHemant Agrawal return ptypes; 556a5fc38d4SHemant Agrawal return NULL; 557a5fc38d4SHemant Agrawal } 558a5fc38d4SHemant Agrawal 5593e5a335dSHemant Agrawal static int 5603e5a335dSHemant Agrawal dpaa2_dev_start(struct rte_eth_dev *dev) 5613e5a335dSHemant Agrawal { 5623e5a335dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 5633e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = data->dev_private; 5643e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 5653e5a335dSHemant Agrawal struct dpni_queue cfg; 566ef18dafeSHemant Agrawal struct dpni_error_cfg err_cfg; 5673e5a335dSHemant Agrawal uint16_t qdid; 5683e5a335dSHemant Agrawal struct dpni_queue_id qid; 5693e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 5703e5a335dSHemant Agrawal int ret, i; 5713e5a335dSHemant Agrawal 5723e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 5733e5a335dSHemant Agrawal 5743e5a335dSHemant Agrawal ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token); 5753e5a335dSHemant Agrawal if (ret) { 5763e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n", 5773e5a335dSHemant Agrawal ret, priv->hw_id); 5783e5a335dSHemant Agrawal return ret; 5793e5a335dSHemant Agrawal } 5803e5a335dSHemant Agrawal 581a1f3a12cSHemant Agrawal /* Power up the phy. Needed to make the link go Up */ 582a1f3a12cSHemant Agrawal dpaa2_dev_set_link_up(dev); 583a1f3a12cSHemant Agrawal 5843e5a335dSHemant Agrawal ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token, 5853e5a335dSHemant Agrawal DPNI_QUEUE_TX, &qdid); 5863e5a335dSHemant Agrawal if (ret) { 5873e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get qdid:ErrorCode = %d\n", ret); 5883e5a335dSHemant Agrawal return ret; 5893e5a335dSHemant Agrawal } 5903e5a335dSHemant Agrawal priv->qdid = qdid; 5913e5a335dSHemant Agrawal 5923e5a335dSHemant Agrawal for (i = 0; i < data->nb_rx_queues; i++) { 5933e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i]; 5943e5a335dSHemant Agrawal ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token, 5953e5a335dSHemant Agrawal DPNI_QUEUE_RX, dpaa2_q->tc_index, 5963e5a335dSHemant Agrawal dpaa2_q->flow_id, &cfg, &qid); 5973e5a335dSHemant Agrawal if (ret) { 5983e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get flow " 5993e5a335dSHemant Agrawal "information Error code = %d\n", ret); 6003e5a335dSHemant Agrawal return ret; 6013e5a335dSHemant Agrawal } 6023e5a335dSHemant Agrawal dpaa2_q->fqid = qid.fqid; 6033e5a335dSHemant Agrawal } 6043e5a335dSHemant Agrawal 605ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 606ef18dafeSHemant Agrawal DPNI_OFF_RX_L3_CSUM, true); 607ef18dafeSHemant Agrawal if (ret) { 608ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret); 609ef18dafeSHemant Agrawal return ret; 610ef18dafeSHemant Agrawal } 611ef18dafeSHemant Agrawal 612ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 613ef18dafeSHemant Agrawal DPNI_OFF_RX_L4_CSUM, true); 614ef18dafeSHemant Agrawal if (ret) { 615ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret); 616ef18dafeSHemant Agrawal return ret; 617ef18dafeSHemant Agrawal } 618ef18dafeSHemant Agrawal 619ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 620ef18dafeSHemant Agrawal DPNI_OFF_TX_L3_CSUM, true); 621ef18dafeSHemant Agrawal if (ret) { 622ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret); 623ef18dafeSHemant Agrawal return ret; 624ef18dafeSHemant Agrawal } 625ef18dafeSHemant Agrawal 626ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 627ef18dafeSHemant Agrawal DPNI_OFF_TX_L4_CSUM, true); 628ef18dafeSHemant Agrawal if (ret) { 629ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret); 630ef18dafeSHemant Agrawal return ret; 631ef18dafeSHemant Agrawal } 632ef18dafeSHemant Agrawal 633ef18dafeSHemant Agrawal /*checksum errors, send them to normal path and set it in annotation */ 634ef18dafeSHemant Agrawal err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE; 635ef18dafeSHemant Agrawal 636ef18dafeSHemant Agrawal err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE; 637ef18dafeSHemant Agrawal err_cfg.set_frame_annotation = true; 638ef18dafeSHemant Agrawal 639ef18dafeSHemant Agrawal ret = dpni_set_errors_behavior(dpni, CMD_PRI_LOW, 640ef18dafeSHemant Agrawal priv->token, &err_cfg); 641ef18dafeSHemant Agrawal if (ret) { 642ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to dpni_set_errors_behavior:" 643ef18dafeSHemant Agrawal "code = %d\n", ret); 644ef18dafeSHemant Agrawal return ret; 645ef18dafeSHemant Agrawal } 6463ce294f2SHemant Agrawal /* VLAN Offload Settings */ 6473ce294f2SHemant Agrawal if (priv->max_vlan_filters) 6483ce294f2SHemant Agrawal dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); 649ef18dafeSHemant Agrawal 6503e5a335dSHemant Agrawal return 0; 6513e5a335dSHemant Agrawal } 6523e5a335dSHemant Agrawal 6533e5a335dSHemant Agrawal /** 6543e5a335dSHemant Agrawal * This routine disables all traffic on the adapter by issuing a 6553e5a335dSHemant Agrawal * global reset on the MAC. 6563e5a335dSHemant Agrawal */ 6573e5a335dSHemant Agrawal static void 6583e5a335dSHemant Agrawal dpaa2_dev_stop(struct rte_eth_dev *dev) 6593e5a335dSHemant Agrawal { 6603e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 6613e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 6623e5a335dSHemant Agrawal int ret; 663c56c86ffSHemant Agrawal struct rte_eth_link link; 6643e5a335dSHemant Agrawal 6653e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 6663e5a335dSHemant Agrawal 667a1f3a12cSHemant Agrawal dpaa2_dev_set_link_down(dev); 668a1f3a12cSHemant Agrawal 6693e5a335dSHemant Agrawal ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token); 6703e5a335dSHemant Agrawal if (ret) { 6713e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure (ret %d) in disabling dpni %d dev\n", 6723e5a335dSHemant Agrawal ret, priv->hw_id); 6733e5a335dSHemant Agrawal return; 6743e5a335dSHemant Agrawal } 675c56c86ffSHemant Agrawal 676c56c86ffSHemant Agrawal /* clear the recorded link status */ 677c56c86ffSHemant Agrawal memset(&link, 0, sizeof(link)); 678c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 6793e5a335dSHemant Agrawal } 6803e5a335dSHemant Agrawal 6813e5a335dSHemant Agrawal static void 6823e5a335dSHemant Agrawal dpaa2_dev_close(struct rte_eth_dev *dev) 6833e5a335dSHemant Agrawal { 6847ae777d0SHemant Agrawal struct rte_eth_dev_data *data = dev->data; 6853e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 6863e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 6877ae777d0SHemant Agrawal int i, ret; 688a1f3a12cSHemant Agrawal struct rte_eth_link link; 6897ae777d0SHemant Agrawal struct dpaa2_queue *dpaa2_q; 6903e5a335dSHemant Agrawal 6913e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 6923e5a335dSHemant Agrawal 6937ae777d0SHemant Agrawal for (i = 0; i < data->nb_tx_queues; i++) { 6947ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)data->tx_queues[i]; 6957ae777d0SHemant Agrawal if (!dpaa2_q->cscn) { 6967ae777d0SHemant Agrawal rte_free(dpaa2_q->cscn); 6977ae777d0SHemant Agrawal dpaa2_q->cscn = NULL; 6987ae777d0SHemant Agrawal } 6997ae777d0SHemant Agrawal } 7007ae777d0SHemant Agrawal 7013e5a335dSHemant Agrawal /* Clean the device first */ 7023e5a335dSHemant Agrawal ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token); 7033e5a335dSHemant Agrawal if (ret) { 7043e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure cleaning dpni device with" 7053e5a335dSHemant Agrawal " error code %d\n", ret); 7063e5a335dSHemant Agrawal return; 7073e5a335dSHemant Agrawal } 708a1f3a12cSHemant Agrawal 709a1f3a12cSHemant Agrawal memset(&link, 0, sizeof(link)); 710a1f3a12cSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 7113e5a335dSHemant Agrawal } 7123e5a335dSHemant Agrawal 713c0e5c69aSHemant Agrawal static void 714c0e5c69aSHemant Agrawal dpaa2_dev_promiscuous_enable( 715c0e5c69aSHemant Agrawal struct rte_eth_dev *dev) 716c0e5c69aSHemant Agrawal { 717c0e5c69aSHemant Agrawal int ret; 718c0e5c69aSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 719c0e5c69aSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 720c0e5c69aSHemant Agrawal 721c0e5c69aSHemant Agrawal PMD_INIT_FUNC_TRACE(); 722c0e5c69aSHemant Agrawal 723c0e5c69aSHemant Agrawal if (dpni == NULL) { 724645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 725c0e5c69aSHemant Agrawal return; 726c0e5c69aSHemant Agrawal } 727c0e5c69aSHemant Agrawal 728c0e5c69aSHemant Agrawal ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 729c0e5c69aSHemant Agrawal if (ret < 0) 730645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable U promisc mode %d\n", ret); 7315d5aeeedSHemant Agrawal 7325d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 7335d5aeeedSHemant Agrawal if (ret < 0) 734645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable M promisc mode %d\n", ret); 735c0e5c69aSHemant Agrawal } 736c0e5c69aSHemant Agrawal 737c0e5c69aSHemant Agrawal static void 738c0e5c69aSHemant Agrawal dpaa2_dev_promiscuous_disable( 739c0e5c69aSHemant Agrawal struct rte_eth_dev *dev) 740c0e5c69aSHemant Agrawal { 741c0e5c69aSHemant Agrawal int ret; 742c0e5c69aSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 743c0e5c69aSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 744c0e5c69aSHemant Agrawal 745c0e5c69aSHemant Agrawal PMD_INIT_FUNC_TRACE(); 746c0e5c69aSHemant Agrawal 747c0e5c69aSHemant Agrawal if (dpni == NULL) { 748645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 749c0e5c69aSHemant Agrawal return; 750c0e5c69aSHemant Agrawal } 751c0e5c69aSHemant Agrawal 752c0e5c69aSHemant Agrawal ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); 753c0e5c69aSHemant Agrawal if (ret < 0) 754645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to disable U promisc mode %d\n", ret); 7555d5aeeedSHemant Agrawal 7565d5aeeedSHemant Agrawal if (dev->data->all_multicast == 0) { 7575d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, 7585d5aeeedSHemant Agrawal priv->token, false); 7595d5aeeedSHemant Agrawal if (ret < 0) 760645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, 761645bd25aSHemant Agrawal "Unable to disable M promisc mode %d\n", 7625d5aeeedSHemant Agrawal ret); 7635d5aeeedSHemant Agrawal } 7645d5aeeedSHemant Agrawal } 7655d5aeeedSHemant Agrawal 7665d5aeeedSHemant Agrawal static void 7675d5aeeedSHemant Agrawal dpaa2_dev_allmulticast_enable( 7685d5aeeedSHemant Agrawal struct rte_eth_dev *dev) 7695d5aeeedSHemant Agrawal { 7705d5aeeedSHemant Agrawal int ret; 7715d5aeeedSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 7725d5aeeedSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 7735d5aeeedSHemant Agrawal 7745d5aeeedSHemant Agrawal PMD_INIT_FUNC_TRACE(); 7755d5aeeedSHemant Agrawal 7765d5aeeedSHemant Agrawal if (dpni == NULL) { 777645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 7785d5aeeedSHemant Agrawal return; 7795d5aeeedSHemant Agrawal } 7805d5aeeedSHemant Agrawal 7815d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 7825d5aeeedSHemant Agrawal if (ret < 0) 783645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable multicast mode %d\n", ret); 7845d5aeeedSHemant Agrawal } 7855d5aeeedSHemant Agrawal 7865d5aeeedSHemant Agrawal static void 7875d5aeeedSHemant Agrawal dpaa2_dev_allmulticast_disable(struct rte_eth_dev *dev) 7885d5aeeedSHemant Agrawal { 7895d5aeeedSHemant Agrawal int ret; 7905d5aeeedSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 7915d5aeeedSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 7925d5aeeedSHemant Agrawal 7935d5aeeedSHemant Agrawal PMD_INIT_FUNC_TRACE(); 7945d5aeeedSHemant Agrawal 7955d5aeeedSHemant Agrawal if (dpni == NULL) { 796645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 7975d5aeeedSHemant Agrawal return; 7985d5aeeedSHemant Agrawal } 7995d5aeeedSHemant Agrawal 8005d5aeeedSHemant Agrawal /* must remain on for all promiscuous */ 8015d5aeeedSHemant Agrawal if (dev->data->promiscuous == 1) 8025d5aeeedSHemant Agrawal return; 8035d5aeeedSHemant Agrawal 8045d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); 8055d5aeeedSHemant Agrawal if (ret < 0) 806645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to disable multicast mode %d\n", ret); 807c0e5c69aSHemant Agrawal } 808e31d4d21SHemant Agrawal 809e31d4d21SHemant Agrawal static int 810e31d4d21SHemant Agrawal dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 811e31d4d21SHemant Agrawal { 812e31d4d21SHemant Agrawal int ret; 813e31d4d21SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 814e31d4d21SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 815e31d4d21SHemant Agrawal uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; 816e31d4d21SHemant Agrawal 817e31d4d21SHemant Agrawal PMD_INIT_FUNC_TRACE(); 818e31d4d21SHemant Agrawal 819e31d4d21SHemant Agrawal if (dpni == NULL) { 820645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 821e31d4d21SHemant Agrawal return -EINVAL; 822e31d4d21SHemant Agrawal } 823e31d4d21SHemant Agrawal 824e31d4d21SHemant Agrawal /* check that mtu is within the allowed range */ 825e31d4d21SHemant Agrawal if ((mtu < ETHER_MIN_MTU) || (frame_size > DPAA2_MAX_RX_PKT_LEN)) 826e31d4d21SHemant Agrawal return -EINVAL; 827e31d4d21SHemant Agrawal 828e1640849SHemant Agrawal if (frame_size > ETHER_MAX_LEN) 829e1640849SHemant Agrawal dev->data->dev_conf.rxmode.jumbo_frame = 1; 830e1640849SHemant Agrawal else 831e1640849SHemant Agrawal dev->data->dev_conf.rxmode.jumbo_frame = 0; 832e1640849SHemant Agrawal 833e31d4d21SHemant Agrawal /* Set the Max Rx frame length as 'mtu' + 834e31d4d21SHemant Agrawal * Maximum Ethernet header length 835e31d4d21SHemant Agrawal */ 836e31d4d21SHemant Agrawal ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token, 837e31d4d21SHemant Agrawal mtu + ETH_VLAN_HLEN); 838e31d4d21SHemant Agrawal if (ret) { 839e31d4d21SHemant Agrawal PMD_DRV_LOG(ERR, "setting the max frame length failed"); 840e31d4d21SHemant Agrawal return -1; 841e31d4d21SHemant Agrawal } 842e31d4d21SHemant Agrawal PMD_DRV_LOG(INFO, "MTU is configured %d for the device\n", mtu); 843e31d4d21SHemant Agrawal return 0; 844e31d4d21SHemant Agrawal } 845e31d4d21SHemant Agrawal 846b4d97b7dSHemant Agrawal static int 847b4d97b7dSHemant Agrawal dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev, 848b4d97b7dSHemant Agrawal struct ether_addr *addr, 849b4d97b7dSHemant Agrawal __rte_unused uint32_t index, 850b4d97b7dSHemant Agrawal __rte_unused uint32_t pool) 851b4d97b7dSHemant Agrawal { 852b4d97b7dSHemant Agrawal int ret; 853b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 854b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 855b4d97b7dSHemant Agrawal 856b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 857b4d97b7dSHemant Agrawal 858b4d97b7dSHemant Agrawal if (dpni == NULL) { 859645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 860b4d97b7dSHemant Agrawal return -1; 861b4d97b7dSHemant Agrawal } 862b4d97b7dSHemant Agrawal 863b4d97b7dSHemant Agrawal ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW, 864b4d97b7dSHemant Agrawal priv->token, addr->addr_bytes); 865b4d97b7dSHemant Agrawal if (ret) 866645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, 867645bd25aSHemant Agrawal "error: Adding the MAC ADDR failed: err = %d\n", ret); 868b4d97b7dSHemant Agrawal return 0; 869b4d97b7dSHemant Agrawal } 870b4d97b7dSHemant Agrawal 871b4d97b7dSHemant Agrawal static void 872b4d97b7dSHemant Agrawal dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev, 873b4d97b7dSHemant Agrawal uint32_t index) 874b4d97b7dSHemant Agrawal { 875b4d97b7dSHemant Agrawal int ret; 876b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 877b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 878b4d97b7dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 879b4d97b7dSHemant Agrawal struct ether_addr *macaddr; 880b4d97b7dSHemant Agrawal 881b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 882b4d97b7dSHemant Agrawal 883b4d97b7dSHemant Agrawal macaddr = &data->mac_addrs[index]; 884b4d97b7dSHemant Agrawal 885b4d97b7dSHemant Agrawal if (dpni == NULL) { 886645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 887b4d97b7dSHemant Agrawal return; 888b4d97b7dSHemant Agrawal } 889b4d97b7dSHemant Agrawal 890b4d97b7dSHemant Agrawal ret = dpni_remove_mac_addr(dpni, CMD_PRI_LOW, 891b4d97b7dSHemant Agrawal priv->token, macaddr->addr_bytes); 892b4d97b7dSHemant Agrawal if (ret) 893645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, 894645bd25aSHemant Agrawal "error: Removing the MAC ADDR failed: err = %d\n", ret); 895b4d97b7dSHemant Agrawal } 896b4d97b7dSHemant Agrawal 897b4d97b7dSHemant Agrawal static void 898b4d97b7dSHemant Agrawal dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev, 899b4d97b7dSHemant Agrawal struct ether_addr *addr) 900b4d97b7dSHemant Agrawal { 901b4d97b7dSHemant Agrawal int ret; 902b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 903b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 904b4d97b7dSHemant Agrawal 905b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 906b4d97b7dSHemant Agrawal 907b4d97b7dSHemant Agrawal if (dpni == NULL) { 908645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 909b4d97b7dSHemant Agrawal return; 910b4d97b7dSHemant Agrawal } 911b4d97b7dSHemant Agrawal 912b4d97b7dSHemant Agrawal ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW, 913b4d97b7dSHemant Agrawal priv->token, addr->addr_bytes); 914b4d97b7dSHemant Agrawal 915b4d97b7dSHemant Agrawal if (ret) 916645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, 917645bd25aSHemant Agrawal "error: Setting the MAC ADDR failed %d\n", ret); 918b4d97b7dSHemant Agrawal } 919b0aa5459SHemant Agrawal static 920b0aa5459SHemant Agrawal void dpaa2_dev_stats_get(struct rte_eth_dev *dev, 921b0aa5459SHemant Agrawal struct rte_eth_stats *stats) 922b0aa5459SHemant Agrawal { 923b0aa5459SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 924b0aa5459SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 925b0aa5459SHemant Agrawal int32_t retcode; 926b0aa5459SHemant Agrawal uint8_t page0 = 0, page1 = 1, page2 = 2; 927b0aa5459SHemant Agrawal union dpni_statistics value; 928b0aa5459SHemant Agrawal 929b0aa5459SHemant Agrawal memset(&value, 0, sizeof(union dpni_statistics)); 930b0aa5459SHemant Agrawal 931b0aa5459SHemant Agrawal PMD_INIT_FUNC_TRACE(); 932b0aa5459SHemant Agrawal 933b0aa5459SHemant Agrawal if (!dpni) { 934645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 935b0aa5459SHemant Agrawal return; 936b0aa5459SHemant Agrawal } 937b0aa5459SHemant Agrawal 938b0aa5459SHemant Agrawal if (!stats) { 939645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "stats is NULL\n"); 940b0aa5459SHemant Agrawal return; 941b0aa5459SHemant Agrawal } 942b0aa5459SHemant Agrawal 943b0aa5459SHemant Agrawal /*Get Counters from page_0*/ 944b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 94516bbc98aSShreyansh Jain page0, 0, &value); 946b0aa5459SHemant Agrawal if (retcode) 947b0aa5459SHemant Agrawal goto err; 948b0aa5459SHemant Agrawal 949b0aa5459SHemant Agrawal stats->ipackets = value.page_0.ingress_all_frames; 950b0aa5459SHemant Agrawal stats->ibytes = value.page_0.ingress_all_bytes; 951b0aa5459SHemant Agrawal 952b0aa5459SHemant Agrawal /*Get Counters from page_1*/ 953b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 95416bbc98aSShreyansh Jain page1, 0, &value); 955b0aa5459SHemant Agrawal if (retcode) 956b0aa5459SHemant Agrawal goto err; 957b0aa5459SHemant Agrawal 958b0aa5459SHemant Agrawal stats->opackets = value.page_1.egress_all_frames; 959b0aa5459SHemant Agrawal stats->obytes = value.page_1.egress_all_bytes; 960b0aa5459SHemant Agrawal 961b0aa5459SHemant Agrawal /*Get Counters from page_2*/ 962b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 96316bbc98aSShreyansh Jain page2, 0, &value); 964b0aa5459SHemant Agrawal if (retcode) 965b0aa5459SHemant Agrawal goto err; 966b0aa5459SHemant Agrawal 967b4d97b7dSHemant Agrawal /* Ingress drop frame count due to configured rules */ 968b4d97b7dSHemant Agrawal stats->ierrors = value.page_2.ingress_filtered_frames; 969b4d97b7dSHemant Agrawal /* Ingress drop frame count due to error */ 970b4d97b7dSHemant Agrawal stats->ierrors += value.page_2.ingress_discarded_frames; 971b4d97b7dSHemant Agrawal 972b0aa5459SHemant Agrawal stats->oerrors = value.page_2.egress_discarded_frames; 973b0aa5459SHemant Agrawal stats->imissed = value.page_2.ingress_nobuffer_discards; 974b0aa5459SHemant Agrawal 975b0aa5459SHemant Agrawal return; 976b0aa5459SHemant Agrawal 977b0aa5459SHemant Agrawal err: 978b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode); 979b0aa5459SHemant Agrawal return; 980b0aa5459SHemant Agrawal }; 981b0aa5459SHemant Agrawal 982b0aa5459SHemant Agrawal static 983b0aa5459SHemant Agrawal void dpaa2_dev_stats_reset(struct rte_eth_dev *dev) 984b0aa5459SHemant Agrawal { 985b0aa5459SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 986b0aa5459SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 987b0aa5459SHemant Agrawal int32_t retcode; 988b0aa5459SHemant Agrawal 989b0aa5459SHemant Agrawal PMD_INIT_FUNC_TRACE(); 990b0aa5459SHemant Agrawal 991b0aa5459SHemant Agrawal if (dpni == NULL) { 992645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 993b0aa5459SHemant Agrawal return; 994b0aa5459SHemant Agrawal } 995b0aa5459SHemant Agrawal 996b0aa5459SHemant Agrawal retcode = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token); 997b0aa5459SHemant Agrawal if (retcode) 998b0aa5459SHemant Agrawal goto error; 999b0aa5459SHemant Agrawal 1000b0aa5459SHemant Agrawal return; 1001b0aa5459SHemant Agrawal 1002b0aa5459SHemant Agrawal error: 1003b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode); 1004b0aa5459SHemant Agrawal return; 1005b0aa5459SHemant Agrawal }; 1006b0aa5459SHemant Agrawal 1007c56c86ffSHemant Agrawal /* return 0 means link status changed, -1 means not changed */ 1008c56c86ffSHemant Agrawal static int 1009c56c86ffSHemant Agrawal dpaa2_dev_link_update(struct rte_eth_dev *dev, 1010c56c86ffSHemant Agrawal int wait_to_complete __rte_unused) 1011c56c86ffSHemant Agrawal { 1012c56c86ffSHemant Agrawal int ret; 1013c56c86ffSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1014c56c86ffSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 1015c56c86ffSHemant Agrawal struct rte_eth_link link, old; 1016c56c86ffSHemant Agrawal struct dpni_link_state state = {0}; 1017c56c86ffSHemant Agrawal 1018c56c86ffSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1019c56c86ffSHemant Agrawal 1020c56c86ffSHemant Agrawal if (dpni == NULL) { 1021645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 1022c56c86ffSHemant Agrawal return 0; 1023c56c86ffSHemant Agrawal } 1024c56c86ffSHemant Agrawal memset(&old, 0, sizeof(old)); 1025c56c86ffSHemant Agrawal dpaa2_dev_atomic_read_link_status(dev, &old); 1026c56c86ffSHemant Agrawal 1027c56c86ffSHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 1028c56c86ffSHemant Agrawal if (ret < 0) { 1029645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret); 1030c56c86ffSHemant Agrawal return -1; 1031c56c86ffSHemant Agrawal } 1032c56c86ffSHemant Agrawal 1033c56c86ffSHemant Agrawal if ((old.link_status == state.up) && (old.link_speed == state.rate)) { 1034c56c86ffSHemant Agrawal RTE_LOG(DEBUG, PMD, "No change in status\n"); 1035c56c86ffSHemant Agrawal return -1; 1036c56c86ffSHemant Agrawal } 1037c56c86ffSHemant Agrawal 1038c56c86ffSHemant Agrawal memset(&link, 0, sizeof(struct rte_eth_link)); 1039c56c86ffSHemant Agrawal link.link_status = state.up; 1040c56c86ffSHemant Agrawal link.link_speed = state.rate; 1041c56c86ffSHemant Agrawal 1042c56c86ffSHemant Agrawal if (state.options & DPNI_LINK_OPT_HALF_DUPLEX) 1043c56c86ffSHemant Agrawal link.link_duplex = ETH_LINK_HALF_DUPLEX; 1044c56c86ffSHemant Agrawal else 1045c56c86ffSHemant Agrawal link.link_duplex = ETH_LINK_FULL_DUPLEX; 1046c56c86ffSHemant Agrawal 1047c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 1048c56c86ffSHemant Agrawal 1049c56c86ffSHemant Agrawal if (link.link_status) 1050c56c86ffSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id); 1051c56c86ffSHemant Agrawal else 1052c56c86ffSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link is Down\n", dev->data->port_id); 1053c56c86ffSHemant Agrawal return 0; 1054c56c86ffSHemant Agrawal } 1055c56c86ffSHemant Agrawal 1056a1f3a12cSHemant Agrawal /** 1057a1f3a12cSHemant Agrawal * Toggle the DPNI to enable, if not already enabled. 1058a1f3a12cSHemant Agrawal * This is not strictly PHY up/down - it is more of logical toggling. 1059a1f3a12cSHemant Agrawal */ 1060a1f3a12cSHemant Agrawal static int 1061a1f3a12cSHemant Agrawal dpaa2_dev_set_link_up(struct rte_eth_dev *dev) 1062a1f3a12cSHemant Agrawal { 1063a1f3a12cSHemant Agrawal int ret = -EINVAL; 1064a1f3a12cSHemant Agrawal struct dpaa2_dev_priv *priv; 1065a1f3a12cSHemant Agrawal struct fsl_mc_io *dpni; 1066a1f3a12cSHemant Agrawal int en = 0; 1067a1f3a12cSHemant Agrawal 1068a1f3a12cSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1069a1f3a12cSHemant Agrawal 1070a1f3a12cSHemant Agrawal priv = dev->data->dev_private; 1071a1f3a12cSHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1072a1f3a12cSHemant Agrawal 1073a1f3a12cSHemant Agrawal if (dpni == NULL) { 1074645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "DPNI is NULL\n"); 1075a1f3a12cSHemant Agrawal return ret; 1076a1f3a12cSHemant Agrawal } 1077a1f3a12cSHemant Agrawal 1078a1f3a12cSHemant Agrawal /* Check if DPNI is currently enabled */ 1079a1f3a12cSHemant Agrawal ret = dpni_is_enabled(dpni, CMD_PRI_LOW, priv->token, &en); 1080a1f3a12cSHemant Agrawal if (ret) { 1081a1f3a12cSHemant Agrawal /* Unable to obtain dpni status; Not continuing */ 1082a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret); 1083a1f3a12cSHemant Agrawal return -EINVAL; 1084a1f3a12cSHemant Agrawal } 1085a1f3a12cSHemant Agrawal 1086a1f3a12cSHemant Agrawal /* Enable link if not already enabled */ 1087a1f3a12cSHemant Agrawal if (!en) { 1088a1f3a12cSHemant Agrawal ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token); 1089a1f3a12cSHemant Agrawal if (ret) { 1090a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret); 1091a1f3a12cSHemant Agrawal return -EINVAL; 1092a1f3a12cSHemant Agrawal } 1093a1f3a12cSHemant Agrawal } 1094a1f3a12cSHemant Agrawal /* changing tx burst function to start enqueues */ 1095a1f3a12cSHemant Agrawal dev->tx_pkt_burst = dpaa2_dev_tx; 1096a1f3a12cSHemant Agrawal dev->data->dev_link.link_status = 1; 1097a1f3a12cSHemant Agrawal 1098a1f3a12cSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link UP successful", dev->data->port_id); 1099a1f3a12cSHemant Agrawal return ret; 1100a1f3a12cSHemant Agrawal } 1101a1f3a12cSHemant Agrawal 1102a1f3a12cSHemant Agrawal /** 1103a1f3a12cSHemant Agrawal * Toggle the DPNI to disable, if not already disabled. 1104a1f3a12cSHemant Agrawal * This is not strictly PHY up/down - it is more of logical toggling. 1105a1f3a12cSHemant Agrawal */ 1106a1f3a12cSHemant Agrawal static int 1107a1f3a12cSHemant Agrawal dpaa2_dev_set_link_down(struct rte_eth_dev *dev) 1108a1f3a12cSHemant Agrawal { 1109a1f3a12cSHemant Agrawal int ret = -EINVAL; 1110a1f3a12cSHemant Agrawal struct dpaa2_dev_priv *priv; 1111a1f3a12cSHemant Agrawal struct fsl_mc_io *dpni; 1112a1f3a12cSHemant Agrawal int dpni_enabled = 0; 1113a1f3a12cSHemant Agrawal int retries = 10; 1114a1f3a12cSHemant Agrawal 1115a1f3a12cSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1116a1f3a12cSHemant Agrawal 1117a1f3a12cSHemant Agrawal priv = dev->data->dev_private; 1118a1f3a12cSHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1119a1f3a12cSHemant Agrawal 1120a1f3a12cSHemant Agrawal if (dpni == NULL) { 1121645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Device has not yet been configured\n"); 1122a1f3a12cSHemant Agrawal return ret; 1123a1f3a12cSHemant Agrawal } 1124a1f3a12cSHemant Agrawal 1125a1f3a12cSHemant Agrawal /*changing tx burst function to avoid any more enqueues */ 1126a1f3a12cSHemant Agrawal dev->tx_pkt_burst = dummy_dev_tx; 1127a1f3a12cSHemant Agrawal 1128a1f3a12cSHemant Agrawal /* Loop while dpni_disable() attempts to drain the egress FQs 1129a1f3a12cSHemant Agrawal * and confirm them back to us. 1130a1f3a12cSHemant Agrawal */ 1131a1f3a12cSHemant Agrawal do { 1132a1f3a12cSHemant Agrawal ret = dpni_disable(dpni, 0, priv->token); 1133a1f3a12cSHemant Agrawal if (ret) { 1134a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "dpni disable failed (%d)", ret); 1135a1f3a12cSHemant Agrawal return ret; 1136a1f3a12cSHemant Agrawal } 1137a1f3a12cSHemant Agrawal ret = dpni_is_enabled(dpni, 0, priv->token, &dpni_enabled); 1138a1f3a12cSHemant Agrawal if (ret) { 1139a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "dpni_is_enabled failed (%d)", ret); 1140a1f3a12cSHemant Agrawal return ret; 1141a1f3a12cSHemant Agrawal } 1142a1f3a12cSHemant Agrawal if (dpni_enabled) 1143a1f3a12cSHemant Agrawal /* Allow the MC some slack */ 1144a1f3a12cSHemant Agrawal rte_delay_us(100 * 1000); 1145a1f3a12cSHemant Agrawal } while (dpni_enabled && --retries); 1146a1f3a12cSHemant Agrawal 1147a1f3a12cSHemant Agrawal if (!retries) { 1148a1f3a12cSHemant Agrawal PMD_DRV_LOG(WARNING, "Retry count exceeded disabling DPNI\n"); 1149a1f3a12cSHemant Agrawal /* todo- we may have to manually cleanup queues. 1150a1f3a12cSHemant Agrawal */ 1151a1f3a12cSHemant Agrawal } else { 1152a1f3a12cSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link DOWN successful", 1153a1f3a12cSHemant Agrawal dev->data->port_id); 1154a1f3a12cSHemant Agrawal } 1155a1f3a12cSHemant Agrawal 1156a1f3a12cSHemant Agrawal dev->data->dev_link.link_status = 0; 1157a1f3a12cSHemant Agrawal 1158a1f3a12cSHemant Agrawal return ret; 1159a1f3a12cSHemant Agrawal } 1160a1f3a12cSHemant Agrawal 1161977d0006SHemant Agrawal static int 1162977d0006SHemant Agrawal dpaa2_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1163977d0006SHemant Agrawal { 1164977d0006SHemant Agrawal int ret = -EINVAL; 1165977d0006SHemant Agrawal struct dpaa2_dev_priv *priv; 1166977d0006SHemant Agrawal struct fsl_mc_io *dpni; 1167977d0006SHemant Agrawal struct dpni_link_state state = {0}; 1168977d0006SHemant Agrawal 1169977d0006SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1170977d0006SHemant Agrawal 1171977d0006SHemant Agrawal priv = dev->data->dev_private; 1172977d0006SHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1173977d0006SHemant Agrawal 1174977d0006SHemant Agrawal if (dpni == NULL || fc_conf == NULL) { 1175645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "device not configured\n"); 1176977d0006SHemant Agrawal return ret; 1177977d0006SHemant Agrawal } 1178977d0006SHemant Agrawal 1179977d0006SHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 1180977d0006SHemant Agrawal if (ret) { 1181645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret); 1182977d0006SHemant Agrawal return ret; 1183977d0006SHemant Agrawal } 1184977d0006SHemant Agrawal 1185977d0006SHemant Agrawal memset(fc_conf, 0, sizeof(struct rte_eth_fc_conf)); 1186977d0006SHemant Agrawal if (state.options & DPNI_LINK_OPT_PAUSE) { 1187977d0006SHemant Agrawal /* DPNI_LINK_OPT_PAUSE set 1188977d0006SHemant Agrawal * if ASYM_PAUSE not set, 1189977d0006SHemant Agrawal * RX Side flow control (handle received Pause frame) 1190977d0006SHemant Agrawal * TX side flow control (send Pause frame) 1191977d0006SHemant Agrawal * if ASYM_PAUSE set, 1192977d0006SHemant Agrawal * RX Side flow control (handle received Pause frame) 1193977d0006SHemant Agrawal * No TX side flow control (send Pause frame disabled) 1194977d0006SHemant Agrawal */ 1195977d0006SHemant Agrawal if (!(state.options & DPNI_LINK_OPT_ASYM_PAUSE)) 1196977d0006SHemant Agrawal fc_conf->mode = RTE_FC_FULL; 1197977d0006SHemant Agrawal else 1198977d0006SHemant Agrawal fc_conf->mode = RTE_FC_RX_PAUSE; 1199977d0006SHemant Agrawal } else { 1200977d0006SHemant Agrawal /* DPNI_LINK_OPT_PAUSE not set 1201977d0006SHemant Agrawal * if ASYM_PAUSE set, 1202977d0006SHemant Agrawal * TX side flow control (send Pause frame) 1203977d0006SHemant Agrawal * No RX side flow control (No action on pause frame rx) 1204977d0006SHemant Agrawal * if ASYM_PAUSE not set, 1205977d0006SHemant Agrawal * Flow control disabled 1206977d0006SHemant Agrawal */ 1207977d0006SHemant Agrawal if (state.options & DPNI_LINK_OPT_ASYM_PAUSE) 1208977d0006SHemant Agrawal fc_conf->mode = RTE_FC_TX_PAUSE; 1209977d0006SHemant Agrawal else 1210977d0006SHemant Agrawal fc_conf->mode = RTE_FC_NONE; 1211977d0006SHemant Agrawal } 1212977d0006SHemant Agrawal 1213977d0006SHemant Agrawal return ret; 1214977d0006SHemant Agrawal } 1215977d0006SHemant Agrawal 1216977d0006SHemant Agrawal static int 1217977d0006SHemant Agrawal dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1218977d0006SHemant Agrawal { 1219977d0006SHemant Agrawal int ret = -EINVAL; 1220977d0006SHemant Agrawal struct dpaa2_dev_priv *priv; 1221977d0006SHemant Agrawal struct fsl_mc_io *dpni; 1222977d0006SHemant Agrawal struct dpni_link_state state = {0}; 1223977d0006SHemant Agrawal struct dpni_link_cfg cfg = {0}; 1224977d0006SHemant Agrawal 1225977d0006SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1226977d0006SHemant Agrawal 1227977d0006SHemant Agrawal priv = dev->data->dev_private; 1228977d0006SHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1229977d0006SHemant Agrawal 1230977d0006SHemant Agrawal if (dpni == NULL) { 1231645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL\n"); 1232977d0006SHemant Agrawal return ret; 1233977d0006SHemant Agrawal } 1234977d0006SHemant Agrawal 1235977d0006SHemant Agrawal /* It is necessary to obtain the current state before setting fc_conf 1236977d0006SHemant Agrawal * as MC would return error in case rate, autoneg or duplex values are 1237977d0006SHemant Agrawal * different. 1238977d0006SHemant Agrawal */ 1239977d0006SHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 1240977d0006SHemant Agrawal if (ret) { 1241645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to get link state (err=%d)\n", ret); 1242977d0006SHemant Agrawal return -1; 1243977d0006SHemant Agrawal } 1244977d0006SHemant Agrawal 1245977d0006SHemant Agrawal /* Disable link before setting configuration */ 1246977d0006SHemant Agrawal dpaa2_dev_set_link_down(dev); 1247977d0006SHemant Agrawal 1248977d0006SHemant Agrawal /* Based on fc_conf, update cfg */ 1249977d0006SHemant Agrawal cfg.rate = state.rate; 1250977d0006SHemant Agrawal cfg.options = state.options; 1251977d0006SHemant Agrawal 1252977d0006SHemant Agrawal /* update cfg with fc_conf */ 1253977d0006SHemant Agrawal switch (fc_conf->mode) { 1254977d0006SHemant Agrawal case RTE_FC_FULL: 1255977d0006SHemant Agrawal /* Full flow control; 1256977d0006SHemant Agrawal * OPT_PAUSE set, ASYM_PAUSE not set 1257977d0006SHemant Agrawal */ 1258977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_PAUSE; 1259977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE; 1260f090a4c3SHemant Agrawal break; 1261977d0006SHemant Agrawal case RTE_FC_TX_PAUSE: 1262977d0006SHemant Agrawal /* Enable RX flow control 1263977d0006SHemant Agrawal * OPT_PAUSE not set; 1264977d0006SHemant Agrawal * ASYM_PAUSE set; 1265977d0006SHemant Agrawal */ 1266977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE; 1267977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_PAUSE; 1268977d0006SHemant Agrawal break; 1269977d0006SHemant Agrawal case RTE_FC_RX_PAUSE: 1270977d0006SHemant Agrawal /* Enable TX Flow control 1271977d0006SHemant Agrawal * OPT_PAUSE set 1272977d0006SHemant Agrawal * ASYM_PAUSE set 1273977d0006SHemant Agrawal */ 1274977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_PAUSE; 1275977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE; 1276977d0006SHemant Agrawal break; 1277977d0006SHemant Agrawal case RTE_FC_NONE: 1278977d0006SHemant Agrawal /* Disable Flow control 1279977d0006SHemant Agrawal * OPT_PAUSE not set 1280977d0006SHemant Agrawal * ASYM_PAUSE not set 1281977d0006SHemant Agrawal */ 1282977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_PAUSE; 1283977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE; 1284977d0006SHemant Agrawal break; 1285977d0006SHemant Agrawal default: 1286645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, "Incorrect Flow control flag (%d)\n", 1287977d0006SHemant Agrawal fc_conf->mode); 1288977d0006SHemant Agrawal return -1; 1289977d0006SHemant Agrawal } 1290977d0006SHemant Agrawal 1291977d0006SHemant Agrawal ret = dpni_set_link_cfg(dpni, CMD_PRI_LOW, priv->token, &cfg); 1292977d0006SHemant Agrawal if (ret) 1293645bd25aSHemant Agrawal RTE_LOG(ERR, PMD, 1294645bd25aSHemant Agrawal "Unable to set Link configuration (err=%d)\n", 1295977d0006SHemant Agrawal ret); 1296977d0006SHemant Agrawal 1297977d0006SHemant Agrawal /* Enable link */ 1298977d0006SHemant Agrawal dpaa2_dev_set_link_up(dev); 1299977d0006SHemant Agrawal 1300977d0006SHemant Agrawal return ret; 1301977d0006SHemant Agrawal } 1302977d0006SHemant Agrawal 13033e5a335dSHemant Agrawal static struct eth_dev_ops dpaa2_ethdev_ops = { 13043e5a335dSHemant Agrawal .dev_configure = dpaa2_eth_dev_configure, 13053e5a335dSHemant Agrawal .dev_start = dpaa2_dev_start, 13063e5a335dSHemant Agrawal .dev_stop = dpaa2_dev_stop, 13073e5a335dSHemant Agrawal .dev_close = dpaa2_dev_close, 1308c0e5c69aSHemant Agrawal .promiscuous_enable = dpaa2_dev_promiscuous_enable, 1309c0e5c69aSHemant Agrawal .promiscuous_disable = dpaa2_dev_promiscuous_disable, 13105d5aeeedSHemant Agrawal .allmulticast_enable = dpaa2_dev_allmulticast_enable, 13115d5aeeedSHemant Agrawal .allmulticast_disable = dpaa2_dev_allmulticast_disable, 1312a1f3a12cSHemant Agrawal .dev_set_link_up = dpaa2_dev_set_link_up, 1313a1f3a12cSHemant Agrawal .dev_set_link_down = dpaa2_dev_set_link_down, 1314c56c86ffSHemant Agrawal .link_update = dpaa2_dev_link_update, 1315b0aa5459SHemant Agrawal .stats_get = dpaa2_dev_stats_get, 1316b0aa5459SHemant Agrawal .stats_reset = dpaa2_dev_stats_reset, 1317748eccb9SHemant Agrawal .fw_version_get = dpaa2_fw_version_get, 13183e5a335dSHemant Agrawal .dev_infos_get = dpaa2_dev_info_get, 1319a5fc38d4SHemant Agrawal .dev_supported_ptypes_get = dpaa2_supported_ptypes_get, 1320e31d4d21SHemant Agrawal .mtu_set = dpaa2_dev_mtu_set, 13213ce294f2SHemant Agrawal .vlan_filter_set = dpaa2_vlan_filter_set, 13223ce294f2SHemant Agrawal .vlan_offload_set = dpaa2_vlan_offload_set, 13233e5a335dSHemant Agrawal .rx_queue_setup = dpaa2_dev_rx_queue_setup, 13243e5a335dSHemant Agrawal .rx_queue_release = dpaa2_dev_rx_queue_release, 13253e5a335dSHemant Agrawal .tx_queue_setup = dpaa2_dev_tx_queue_setup, 13263e5a335dSHemant Agrawal .tx_queue_release = dpaa2_dev_tx_queue_release, 1327977d0006SHemant Agrawal .flow_ctrl_get = dpaa2_flow_ctrl_get, 1328977d0006SHemant Agrawal .flow_ctrl_set = dpaa2_flow_ctrl_set, 1329b4d97b7dSHemant Agrawal .mac_addr_add = dpaa2_dev_add_mac_addr, 1330b4d97b7dSHemant Agrawal .mac_addr_remove = dpaa2_dev_remove_mac_addr, 1331b4d97b7dSHemant Agrawal .mac_addr_set = dpaa2_dev_set_mac_addr, 13323e5a335dSHemant Agrawal }; 13333e5a335dSHemant Agrawal 1334c147eae0SHemant Agrawal static int 1335c147eae0SHemant Agrawal dpaa2_dev_init(struct rte_eth_dev *eth_dev) 1336c147eae0SHemant Agrawal { 13373e5a335dSHemant Agrawal struct rte_device *dev = eth_dev->device; 13383e5a335dSHemant Agrawal struct rte_dpaa2_device *dpaa2_dev; 13393e5a335dSHemant Agrawal struct fsl_mc_io *dpni_dev; 13403e5a335dSHemant Agrawal struct dpni_attr attr; 13413e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; 1342bee61d86SHemant Agrawal struct dpni_buffer_layout layout; 1343599017a2SHemant Agrawal int ret, hw_id; 13443e5a335dSHemant Agrawal 1345d401ead1SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1346d401ead1SHemant Agrawal 1347c147eae0SHemant Agrawal /* For secondary processes, the primary has done all the work */ 1348c147eae0SHemant Agrawal if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1349c147eae0SHemant Agrawal return 0; 1350c147eae0SHemant Agrawal 13513e5a335dSHemant Agrawal dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device); 13523e5a335dSHemant Agrawal 13533e5a335dSHemant Agrawal hw_id = dpaa2_dev->object_id; 13543e5a335dSHemant Agrawal 1355d4984046SHemant Agrawal dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0); 13563e5a335dSHemant Agrawal if (!dpni_dev) { 13573e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "malloc failed for dpni device\n"); 13583e5a335dSHemant Agrawal return -1; 13593e5a335dSHemant Agrawal } 13603e5a335dSHemant Agrawal 13613e5a335dSHemant Agrawal dpni_dev->regs = rte_mcp_ptr_list[0]; 13623e5a335dSHemant Agrawal ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token); 13633e5a335dSHemant Agrawal if (ret) { 1364d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1365d4984046SHemant Agrawal "Failure in opening dpni@%d with err code %d\n", 1366d4984046SHemant Agrawal hw_id, ret); 1367d4984046SHemant Agrawal rte_free(dpni_dev); 13683e5a335dSHemant Agrawal return -1; 13693e5a335dSHemant Agrawal } 13703e5a335dSHemant Agrawal 13713e5a335dSHemant Agrawal /* Clean the device first */ 13723e5a335dSHemant Agrawal ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token); 13733e5a335dSHemant Agrawal if (ret) { 1374d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1375d4984046SHemant Agrawal "Failure cleaning dpni@%d with err code %d\n", 1376d4984046SHemant Agrawal hw_id, ret); 1377d4984046SHemant Agrawal goto init_err; 13783e5a335dSHemant Agrawal } 13793e5a335dSHemant Agrawal 13803e5a335dSHemant Agrawal ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr); 13813e5a335dSHemant Agrawal if (ret) { 1382d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1383d4984046SHemant Agrawal "Failure in get dpni@%d attribute, err code %d\n", 1384d4984046SHemant Agrawal hw_id, ret); 1385d4984046SHemant Agrawal goto init_err; 13863e5a335dSHemant Agrawal } 13873e5a335dSHemant Agrawal 138816bbc98aSShreyansh Jain priv->num_rx_tc = attr.num_rx_tcs; 138989c2ea8fSHemant Agrawal 139016bbc98aSShreyansh Jain /* Resetting the "num_rx_queues" to equal number of queues in first TC 1391599017a2SHemant Agrawal * as only one TC is supported on Rx Side. Once Multiple TCs will be 1392599017a2SHemant Agrawal * in use for Rx processing then this will be changed or removed. 139389c2ea8fSHemant Agrawal */ 1394599017a2SHemant Agrawal priv->nb_rx_queues = attr.num_queues; 139589c2ea8fSHemant Agrawal 139616bbc98aSShreyansh Jain /* Using number of TX queues as number of TX TCs */ 139716bbc98aSShreyansh Jain priv->nb_tx_queues = attr.num_tx_tcs; 1398ef18dafeSHemant Agrawal 139916bbc98aSShreyansh Jain PMD_DRV_LOG(DEBUG, "RX-TC= %d, nb_rx_queues= %d, nb_tx_queues=%d", 140016bbc98aSShreyansh Jain priv->num_tc, priv->nb_rx_queues, priv->nb_tx_queues); 14013e5a335dSHemant Agrawal 14023e5a335dSHemant Agrawal priv->hw = dpni_dev; 14033e5a335dSHemant Agrawal priv->hw_id = hw_id; 140433fad432SHemant Agrawal priv->options = attr.options; 140533fad432SHemant Agrawal priv->max_mac_filters = attr.mac_filter_entries; 140633fad432SHemant Agrawal priv->max_vlan_filters = attr.vlan_filter_entries; 14073e5a335dSHemant Agrawal priv->flags = 0; 14083e5a335dSHemant Agrawal 14093e5a335dSHemant Agrawal /* Allocate memory for hardware structure for queues */ 14103e5a335dSHemant Agrawal ret = dpaa2_alloc_rx_tx_queues(eth_dev); 14113e5a335dSHemant Agrawal if (ret) { 14123e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "dpaa2_alloc_rx_tx_queuesFailed\n"); 1413d4984046SHemant Agrawal goto init_err; 14143e5a335dSHemant Agrawal } 14153e5a335dSHemant Agrawal 141633fad432SHemant Agrawal /* Allocate memory for storing MAC addresses */ 141733fad432SHemant Agrawal eth_dev->data->mac_addrs = rte_zmalloc("dpni", 141833fad432SHemant Agrawal ETHER_ADDR_LEN * attr.mac_filter_entries, 0); 141933fad432SHemant Agrawal if (eth_dev->data->mac_addrs == NULL) { 1420d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1421d4984046SHemant Agrawal "Failed to allocate %d bytes needed to store MAC addresses", 142233fad432SHemant Agrawal ETHER_ADDR_LEN * attr.mac_filter_entries); 1423d4984046SHemant Agrawal ret = -ENOMEM; 1424d4984046SHemant Agrawal goto init_err; 142533fad432SHemant Agrawal } 142633fad432SHemant Agrawal 142733fad432SHemant Agrawal ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW, 142833fad432SHemant Agrawal priv->token, 142933fad432SHemant Agrawal (uint8_t *)(eth_dev->data->mac_addrs[0].addr_bytes)); 143033fad432SHemant Agrawal if (ret) { 1431d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "DPNI get mac address failed:Err Code = %d\n", 1432d4984046SHemant Agrawal ret); 1433d4984046SHemant Agrawal goto init_err; 143433fad432SHemant Agrawal } 143533fad432SHemant Agrawal 1436bee61d86SHemant Agrawal /* ... tx buffer layout ... */ 1437bee61d86SHemant Agrawal memset(&layout, 0, sizeof(struct dpni_buffer_layout)); 1438bee61d86SHemant Agrawal layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; 1439bee61d86SHemant Agrawal layout.pass_frame_status = 1; 1440bee61d86SHemant Agrawal ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, 1441bee61d86SHemant Agrawal DPNI_QUEUE_TX, &layout); 1442bee61d86SHemant Agrawal if (ret) { 1443d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "Error (%d) in setting tx buffer layout", 1444d4984046SHemant Agrawal ret); 1445d4984046SHemant Agrawal goto init_err; 1446bee61d86SHemant Agrawal } 1447bee61d86SHemant Agrawal 1448bee61d86SHemant Agrawal /* ... tx-conf and error buffer layout ... */ 1449bee61d86SHemant Agrawal memset(&layout, 0, sizeof(struct dpni_buffer_layout)); 1450bee61d86SHemant Agrawal layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; 1451bee61d86SHemant Agrawal layout.pass_frame_status = 1; 1452bee61d86SHemant Agrawal ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, 1453bee61d86SHemant Agrawal DPNI_QUEUE_TX_CONFIRM, &layout); 1454bee61d86SHemant Agrawal if (ret) { 1455d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "Error (%d) in setting tx-conf buffer layout", 1456d4984046SHemant Agrawal ret); 1457d4984046SHemant Agrawal goto init_err; 1458bee61d86SHemant Agrawal } 1459bee61d86SHemant Agrawal 14603e5a335dSHemant Agrawal eth_dev->dev_ops = &dpaa2_ethdev_ops; 1461c147eae0SHemant Agrawal 14625c6942fdSHemant Agrawal eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; 1463cd9935ceSHemant Agrawal eth_dev->tx_pkt_burst = dpaa2_dev_tx; 14641261cd68SHemant Agrawal rte_fslmc_vfio_dmamap(); 14651261cd68SHemant Agrawal 1466c147eae0SHemant Agrawal return 0; 1467d4984046SHemant Agrawal init_err: 1468d4984046SHemant Agrawal dpaa2_dev_uninit(eth_dev); 1469d4984046SHemant Agrawal return ret; 1470c147eae0SHemant Agrawal } 1471c147eae0SHemant Agrawal 1472c147eae0SHemant Agrawal static int 14733e5a335dSHemant Agrawal dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) 1474c147eae0SHemant Agrawal { 14753e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; 14763e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 14773e5a335dSHemant Agrawal int i, ret; 14783e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 14793e5a335dSHemant Agrawal 1480d401ead1SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1481d401ead1SHemant Agrawal 1482c147eae0SHemant Agrawal if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1483e729ec76SHemant Agrawal return 0; 1484c147eae0SHemant Agrawal 14853e5a335dSHemant Agrawal if (!dpni) { 14863e5a335dSHemant Agrawal PMD_INIT_LOG(WARNING, "Already closed or not started"); 14873e5a335dSHemant Agrawal return -1; 14883e5a335dSHemant Agrawal } 14893e5a335dSHemant Agrawal 14903e5a335dSHemant Agrawal dpaa2_dev_close(eth_dev); 14913e5a335dSHemant Agrawal 14923e5a335dSHemant Agrawal if (priv->rx_vq[0]) { 14933e5a335dSHemant Agrawal /* cleaning up queue storage */ 14943e5a335dSHemant Agrawal for (i = 0; i < priv->nb_rx_queues; i++) { 14953e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 14963e5a335dSHemant Agrawal if (dpaa2_q->q_storage) 14973e5a335dSHemant Agrawal rte_free(dpaa2_q->q_storage); 14983e5a335dSHemant Agrawal } 14993e5a335dSHemant Agrawal /*free the all queue memory */ 15003e5a335dSHemant Agrawal rte_free(priv->rx_vq[0]); 15013e5a335dSHemant Agrawal priv->rx_vq[0] = NULL; 15023e5a335dSHemant Agrawal } 15033e5a335dSHemant Agrawal 1504d4984046SHemant Agrawal /* free memory for storing MAC addresses */ 150533fad432SHemant Agrawal if (eth_dev->data->mac_addrs) { 150633fad432SHemant Agrawal rte_free(eth_dev->data->mac_addrs); 150733fad432SHemant Agrawal eth_dev->data->mac_addrs = NULL; 150833fad432SHemant Agrawal } 15093e5a335dSHemant Agrawal 15103e5a335dSHemant Agrawal /* Close the device at underlying layer*/ 15113e5a335dSHemant Agrawal ret = dpni_close(dpni, CMD_PRI_LOW, priv->token); 15123e5a335dSHemant Agrawal if (ret) { 1513d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1514d4984046SHemant Agrawal "Failure closing dpni device with err code %d\n", 1515d4984046SHemant Agrawal ret); 15163e5a335dSHemant Agrawal } 15173e5a335dSHemant Agrawal 15183e5a335dSHemant Agrawal /* Free the allocated memory for ethernet private data and dpni*/ 15193e5a335dSHemant Agrawal priv->hw = NULL; 1520d4984046SHemant Agrawal rte_free(dpni); 15213e5a335dSHemant Agrawal 15223e5a335dSHemant Agrawal eth_dev->dev_ops = NULL; 1523cd9935ceSHemant Agrawal eth_dev->rx_pkt_burst = NULL; 1524cd9935ceSHemant Agrawal eth_dev->tx_pkt_burst = NULL; 15253e5a335dSHemant Agrawal 1526c147eae0SHemant Agrawal return 0; 1527c147eae0SHemant Agrawal } 1528c147eae0SHemant Agrawal 1529c147eae0SHemant Agrawal static int 153055fd2703SHemant Agrawal rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv, 1531c147eae0SHemant Agrawal struct rte_dpaa2_device *dpaa2_dev) 1532c147eae0SHemant Agrawal { 1533c147eae0SHemant Agrawal struct rte_eth_dev *eth_dev; 1534c147eae0SHemant Agrawal int diag; 1535c147eae0SHemant Agrawal 1536c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1537e729ec76SHemant Agrawal eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name); 1538e729ec76SHemant Agrawal if (!eth_dev) 1539e729ec76SHemant Agrawal return -ENODEV; 1540c147eae0SHemant Agrawal eth_dev->data->dev_private = rte_zmalloc( 1541c147eae0SHemant Agrawal "ethdev private structure", 1542c147eae0SHemant Agrawal sizeof(struct dpaa2_dev_priv), 1543c147eae0SHemant Agrawal RTE_CACHE_LINE_SIZE); 1544c147eae0SHemant Agrawal if (eth_dev->data->dev_private == NULL) { 1545d401ead1SHemant Agrawal PMD_INIT_LOG(CRIT, "Cannot allocate memzone for" 1546c147eae0SHemant Agrawal " private port data\n"); 1547c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1548c147eae0SHemant Agrawal return -ENOMEM; 1549c147eae0SHemant Agrawal } 1550e729ec76SHemant Agrawal } else { 1551e729ec76SHemant Agrawal eth_dev = rte_eth_dev_attach_secondary(dpaa2_dev->device.name); 1552e729ec76SHemant Agrawal if (!eth_dev) 1553e729ec76SHemant Agrawal return -ENODEV; 1554c147eae0SHemant Agrawal } 1555e729ec76SHemant Agrawal 1556c147eae0SHemant Agrawal eth_dev->device = &dpaa2_dev->device; 155755fd2703SHemant Agrawal eth_dev->device->driver = &dpaa2_drv->driver; 155855fd2703SHemant Agrawal 1559c147eae0SHemant Agrawal dpaa2_dev->eth_dev = eth_dev; 1560c147eae0SHemant Agrawal eth_dev->data->rx_mbuf_alloc_failed = 0; 1561c147eae0SHemant Agrawal 1562c147eae0SHemant Agrawal /* Invoke PMD device initialization function */ 1563c147eae0SHemant Agrawal diag = dpaa2_dev_init(eth_dev); 1564c147eae0SHemant Agrawal if (diag == 0) 1565c147eae0SHemant Agrawal return 0; 1566c147eae0SHemant Agrawal 1567c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) 1568c147eae0SHemant Agrawal rte_free(eth_dev->data->dev_private); 1569c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1570c147eae0SHemant Agrawal return diag; 1571c147eae0SHemant Agrawal } 1572c147eae0SHemant Agrawal 1573c147eae0SHemant Agrawal static int 1574c147eae0SHemant Agrawal rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev) 1575c147eae0SHemant Agrawal { 1576c147eae0SHemant Agrawal struct rte_eth_dev *eth_dev; 1577c147eae0SHemant Agrawal 1578c147eae0SHemant Agrawal eth_dev = dpaa2_dev->eth_dev; 1579c147eae0SHemant Agrawal dpaa2_dev_uninit(eth_dev); 1580c147eae0SHemant Agrawal 1581c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) 1582c147eae0SHemant Agrawal rte_free(eth_dev->data->dev_private); 1583c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1584c147eae0SHemant Agrawal 1585c147eae0SHemant Agrawal return 0; 1586c147eae0SHemant Agrawal } 1587c147eae0SHemant Agrawal 1588c147eae0SHemant Agrawal static struct rte_dpaa2_driver rte_dpaa2_pmd = { 1589bad555dfSShreyansh Jain .drv_type = DPAA2_ETH, 1590c147eae0SHemant Agrawal .probe = rte_dpaa2_probe, 1591c147eae0SHemant Agrawal .remove = rte_dpaa2_remove, 1592c147eae0SHemant Agrawal }; 1593c147eae0SHemant Agrawal 1594c147eae0SHemant Agrawal RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd); 1595