1c147eae0SHemant Agrawal /*- 2c147eae0SHemant Agrawal * BSD LICENSE 3c147eae0SHemant Agrawal * 4c147eae0SHemant Agrawal * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. 5c147eae0SHemant Agrawal * Copyright (c) 2016 NXP. All rights reserved. 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_ethdev.h> 46c147eae0SHemant Agrawal #include <rte_fslmc.h> 47c147eae0SHemant Agrawal 48d401ead1SHemant Agrawal #include <fslmc_logs.h> 49c147eae0SHemant Agrawal #include <fslmc_vfio.h> 503e5a335dSHemant Agrawal #include <dpaa2_hw_pvt.h> 51bee61d86SHemant Agrawal #include <dpaa2_hw_mempool.h> 523cf50ff5SHemant Agrawal #include <dpaa2_hw_dpio.h> 533e5a335dSHemant Agrawal 54c147eae0SHemant Agrawal #include "dpaa2_ethdev.h" 55c147eae0SHemant Agrawal 56c147eae0SHemant Agrawal static struct rte_dpaa2_driver rte_dpaa2_pmd; 57d4984046SHemant Agrawal static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev); 58a1f3a12cSHemant Agrawal static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev); 59a1f3a12cSHemant Agrawal static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev); 60*e1640849SHemant Agrawal static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 61c147eae0SHemant Agrawal 62c56c86ffSHemant Agrawal /** 63c56c86ffSHemant Agrawal * Atomically reads the link status information from global 64c56c86ffSHemant Agrawal * structure rte_eth_dev. 65c56c86ffSHemant Agrawal * 66c56c86ffSHemant Agrawal * @param dev 67c56c86ffSHemant Agrawal * - Pointer to the structure rte_eth_dev to read from. 68c56c86ffSHemant Agrawal * - Pointer to the buffer to be saved with the link status. 69c56c86ffSHemant Agrawal * 70c56c86ffSHemant Agrawal * @return 71c56c86ffSHemant Agrawal * - On success, zero. 72c56c86ffSHemant Agrawal * - On failure, negative value. 73c56c86ffSHemant Agrawal */ 74c56c86ffSHemant Agrawal static inline int 75c56c86ffSHemant Agrawal dpaa2_dev_atomic_read_link_status(struct rte_eth_dev *dev, 76c56c86ffSHemant Agrawal struct rte_eth_link *link) 77c56c86ffSHemant Agrawal { 78c56c86ffSHemant Agrawal struct rte_eth_link *dst = link; 79c56c86ffSHemant Agrawal struct rte_eth_link *src = &dev->data->dev_link; 80c56c86ffSHemant Agrawal 81c56c86ffSHemant Agrawal if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 82c56c86ffSHemant Agrawal *(uint64_t *)src) == 0) 83c56c86ffSHemant Agrawal return -1; 84c56c86ffSHemant Agrawal 85c56c86ffSHemant Agrawal return 0; 86c56c86ffSHemant Agrawal } 87c56c86ffSHemant Agrawal 88c56c86ffSHemant Agrawal /** 89c56c86ffSHemant Agrawal * Atomically writes the link status information into global 90c56c86ffSHemant Agrawal * structure rte_eth_dev. 91c56c86ffSHemant Agrawal * 92c56c86ffSHemant Agrawal * @param dev 93c56c86ffSHemant Agrawal * - Pointer to the structure rte_eth_dev to read from. 94c56c86ffSHemant Agrawal * - Pointer to the buffer to be saved with the link status. 95c56c86ffSHemant Agrawal * 96c56c86ffSHemant Agrawal * @return 97c56c86ffSHemant Agrawal * - On success, zero. 98c56c86ffSHemant Agrawal * - On failure, negative value. 99c56c86ffSHemant Agrawal */ 100c56c86ffSHemant Agrawal static inline int 101c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(struct rte_eth_dev *dev, 102c56c86ffSHemant Agrawal struct rte_eth_link *link) 103c56c86ffSHemant Agrawal { 104c56c86ffSHemant Agrawal struct rte_eth_link *dst = &dev->data->dev_link; 105c56c86ffSHemant Agrawal struct rte_eth_link *src = link; 106c56c86ffSHemant Agrawal 107c56c86ffSHemant Agrawal if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 108c56c86ffSHemant Agrawal *(uint64_t *)src) == 0) 109c56c86ffSHemant Agrawal return -1; 110c56c86ffSHemant Agrawal 111c56c86ffSHemant Agrawal return 0; 112c56c86ffSHemant Agrawal } 113c56c86ffSHemant Agrawal 1143ce294f2SHemant Agrawal static int 1153ce294f2SHemant Agrawal dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 1163ce294f2SHemant Agrawal { 1173ce294f2SHemant Agrawal int ret; 1183ce294f2SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1193ce294f2SHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 1203ce294f2SHemant Agrawal 1213ce294f2SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1223ce294f2SHemant Agrawal 1233ce294f2SHemant Agrawal if (dpni == NULL) { 1243ce294f2SHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 1253ce294f2SHemant Agrawal return -1; 1263ce294f2SHemant Agrawal } 1273ce294f2SHemant Agrawal 1283ce294f2SHemant Agrawal if (on) 1293ce294f2SHemant Agrawal ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW, 1303ce294f2SHemant Agrawal priv->token, vlan_id); 1313ce294f2SHemant Agrawal else 1323ce294f2SHemant Agrawal ret = dpni_remove_vlan_id(dpni, CMD_PRI_LOW, 1333ce294f2SHemant Agrawal priv->token, vlan_id); 1343ce294f2SHemant Agrawal 1353ce294f2SHemant Agrawal if (ret < 0) 1363ce294f2SHemant Agrawal PMD_DRV_LOG(ERR, "ret = %d Unable to add/rem vlan %d hwid =%d", 1373ce294f2SHemant Agrawal ret, vlan_id, priv->hw_id); 1383ce294f2SHemant Agrawal 1393ce294f2SHemant Agrawal return ret; 1403ce294f2SHemant Agrawal } 1413ce294f2SHemant Agrawal 1423ce294f2SHemant Agrawal static void 1433ce294f2SHemant Agrawal dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) 1443ce294f2SHemant Agrawal { 1453ce294f2SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1463ce294f2SHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 1473ce294f2SHemant Agrawal int ret; 1483ce294f2SHemant Agrawal 1493ce294f2SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1503ce294f2SHemant Agrawal 1513ce294f2SHemant Agrawal if (mask & ETH_VLAN_FILTER_MASK) { 1523ce294f2SHemant Agrawal if (dev->data->dev_conf.rxmode.hw_vlan_filter) 1533ce294f2SHemant Agrawal ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW, 1543ce294f2SHemant Agrawal priv->token, true); 1553ce294f2SHemant Agrawal else 1563ce294f2SHemant Agrawal ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW, 1573ce294f2SHemant Agrawal priv->token, false); 1583ce294f2SHemant Agrawal if (ret < 0) 1593ce294f2SHemant Agrawal RTE_LOG(ERR, PMD, "Unable to set vlan filter ret = %d", 1603ce294f2SHemant Agrawal ret); 1613ce294f2SHemant Agrawal } 1623ce294f2SHemant Agrawal } 1633ce294f2SHemant Agrawal 1643e5a335dSHemant Agrawal static void 1653e5a335dSHemant Agrawal dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 1663e5a335dSHemant Agrawal { 1673e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1683e5a335dSHemant Agrawal 1693e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1703e5a335dSHemant Agrawal 1713e5a335dSHemant Agrawal dev_info->if_index = priv->hw_id; 1723e5a335dSHemant Agrawal 17333fad432SHemant Agrawal dev_info->max_mac_addrs = priv->max_mac_filters; 174bee61d86SHemant Agrawal dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN; 175bee61d86SHemant Agrawal dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE; 1763e5a335dSHemant Agrawal dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues; 1773e5a335dSHemant Agrawal dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues; 178ef18dafeSHemant Agrawal dev_info->rx_offload_capa = 179ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_IPV4_CKSUM | 180ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_UDP_CKSUM | 181ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_TCP_CKSUM | 182ef18dafeSHemant Agrawal DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; 183ef18dafeSHemant Agrawal dev_info->tx_offload_capa = 184ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_IPV4_CKSUM | 185ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_UDP_CKSUM | 186ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_TCP_CKSUM | 187ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_SCTP_CKSUM | 188ef18dafeSHemant Agrawal DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM; 1893e5a335dSHemant Agrawal dev_info->speed_capa = ETH_LINK_SPEED_1G | 1903e5a335dSHemant Agrawal ETH_LINK_SPEED_2_5G | 1913e5a335dSHemant Agrawal ETH_LINK_SPEED_10G; 1923e5a335dSHemant Agrawal } 1933e5a335dSHemant Agrawal 1943e5a335dSHemant Agrawal static int 1953e5a335dSHemant Agrawal dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) 1963e5a335dSHemant Agrawal { 1973e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 1983e5a335dSHemant Agrawal uint16_t dist_idx; 1993e5a335dSHemant Agrawal uint32_t vq_id; 2003e5a335dSHemant Agrawal struct dpaa2_queue *mc_q, *mcq; 2013e5a335dSHemant Agrawal uint32_t tot_queues; 2023e5a335dSHemant Agrawal int i; 2033e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 2043e5a335dSHemant Agrawal 2053e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 2063e5a335dSHemant Agrawal 2073e5a335dSHemant Agrawal tot_queues = priv->nb_rx_queues + priv->nb_tx_queues; 2083e5a335dSHemant Agrawal mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues, 2093e5a335dSHemant Agrawal RTE_CACHE_LINE_SIZE); 2103e5a335dSHemant Agrawal if (!mc_q) { 2113e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "malloc failed for rx/tx queues\n"); 2123e5a335dSHemant Agrawal return -1; 2133e5a335dSHemant Agrawal } 2143e5a335dSHemant Agrawal 2153e5a335dSHemant Agrawal for (i = 0; i < priv->nb_rx_queues; i++) { 2163e5a335dSHemant Agrawal mc_q->dev = dev; 2173e5a335dSHemant Agrawal priv->rx_vq[i] = mc_q++; 2183e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 2193e5a335dSHemant Agrawal dpaa2_q->q_storage = rte_malloc("dq_storage", 2203e5a335dSHemant Agrawal sizeof(struct queue_storage_info_t), 2213e5a335dSHemant Agrawal RTE_CACHE_LINE_SIZE); 2223e5a335dSHemant Agrawal if (!dpaa2_q->q_storage) 2233e5a335dSHemant Agrawal goto fail; 2243e5a335dSHemant Agrawal 2253e5a335dSHemant Agrawal memset(dpaa2_q->q_storage, 0, 2263e5a335dSHemant Agrawal sizeof(struct queue_storage_info_t)); 2273cf50ff5SHemant Agrawal if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage)) 2283cf50ff5SHemant Agrawal goto fail; 2293e5a335dSHemant Agrawal } 2303e5a335dSHemant Agrawal 2313e5a335dSHemant Agrawal for (i = 0; i < priv->nb_tx_queues; i++) { 2323e5a335dSHemant Agrawal mc_q->dev = dev; 2337ae777d0SHemant Agrawal mc_q->flow_id = 0xffff; 2343e5a335dSHemant Agrawal priv->tx_vq[i] = mc_q++; 2357ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i]; 2367ae777d0SHemant Agrawal dpaa2_q->cscn = rte_malloc(NULL, 2377ae777d0SHemant Agrawal sizeof(struct qbman_result), 16); 2387ae777d0SHemant Agrawal if (!dpaa2_q->cscn) 2397ae777d0SHemant Agrawal goto fail_tx; 2403e5a335dSHemant Agrawal } 2413e5a335dSHemant Agrawal 2423e5a335dSHemant Agrawal vq_id = 0; 24389c2ea8fSHemant Agrawal for (dist_idx = 0; dist_idx < priv->num_dist_per_tc[DPAA2_DEF_TC]; 24489c2ea8fSHemant Agrawal dist_idx++) { 2453e5a335dSHemant Agrawal mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id]; 2463e5a335dSHemant Agrawal mcq->tc_index = DPAA2_DEF_TC; 2473e5a335dSHemant Agrawal mcq->flow_id = dist_idx; 2483e5a335dSHemant Agrawal vq_id++; 2493e5a335dSHemant Agrawal } 2503e5a335dSHemant Agrawal 2513e5a335dSHemant Agrawal return 0; 2527ae777d0SHemant Agrawal fail_tx: 2537ae777d0SHemant Agrawal i -= 1; 2547ae777d0SHemant Agrawal while (i >= 0) { 2557ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i]; 2567ae777d0SHemant Agrawal rte_free(dpaa2_q->cscn); 2577ae777d0SHemant Agrawal priv->tx_vq[i--] = NULL; 2587ae777d0SHemant Agrawal } 2597ae777d0SHemant Agrawal i = priv->nb_rx_queues; 2603e5a335dSHemant Agrawal fail: 2613e5a335dSHemant Agrawal i -= 1; 2623e5a335dSHemant Agrawal mc_q = priv->rx_vq[0]; 2633e5a335dSHemant Agrawal while (i >= 0) { 2643e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 2653cf50ff5SHemant Agrawal dpaa2_free_dq_storage(dpaa2_q->q_storage); 2663e5a335dSHemant Agrawal rte_free(dpaa2_q->q_storage); 2673e5a335dSHemant Agrawal priv->rx_vq[i--] = NULL; 2683e5a335dSHemant Agrawal } 2693e5a335dSHemant Agrawal rte_free(mc_q); 2703e5a335dSHemant Agrawal return -1; 2713e5a335dSHemant Agrawal } 2723e5a335dSHemant Agrawal 2733e5a335dSHemant Agrawal static int 2743e5a335dSHemant Agrawal dpaa2_eth_dev_configure(struct rte_eth_dev *dev) 2753e5a335dSHemant Agrawal { 2763e5a335dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 2773e5a335dSHemant Agrawal struct rte_eth_conf *eth_conf = &data->dev_conf; 27889c2ea8fSHemant Agrawal int ret; 2793e5a335dSHemant Agrawal 2803e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 2813e5a335dSHemant Agrawal 282*e1640849SHemant Agrawal if (eth_conf->rxmode.jumbo_frame == 1) { 283*e1640849SHemant Agrawal if (eth_conf->rxmode.max_rx_pkt_len <= DPAA2_MAX_RX_PKT_LEN) { 284*e1640849SHemant Agrawal ret = dpaa2_dev_mtu_set(dev, 285*e1640849SHemant Agrawal eth_conf->rxmode.max_rx_pkt_len); 286*e1640849SHemant Agrawal if (ret) { 287*e1640849SHemant Agrawal PMD_INIT_LOG(ERR, 288*e1640849SHemant Agrawal "unable to set mtu. check config\n"); 289*e1640849SHemant Agrawal return ret; 290*e1640849SHemant Agrawal } 291*e1640849SHemant Agrawal } else { 292*e1640849SHemant Agrawal return -1; 293*e1640849SHemant Agrawal } 294*e1640849SHemant Agrawal } 295*e1640849SHemant Agrawal 2963e5a335dSHemant Agrawal /* Check for correct configuration */ 2973e5a335dSHemant Agrawal if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS && 2983e5a335dSHemant Agrawal data->nb_rx_queues > 1) { 2993e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Distribution is not enabled, " 3003e5a335dSHemant Agrawal "but Rx queues more than 1\n"); 3013e5a335dSHemant Agrawal return -1; 3023e5a335dSHemant Agrawal } 3033e5a335dSHemant Agrawal 30489c2ea8fSHemant Agrawal if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) { 30589c2ea8fSHemant Agrawal /* Return in case number of Rx queues is 1 */ 30689c2ea8fSHemant Agrawal if (data->nb_rx_queues == 1) 30789c2ea8fSHemant Agrawal return 0; 30889c2ea8fSHemant Agrawal ret = dpaa2_setup_flow_dist(dev, 30989c2ea8fSHemant Agrawal eth_conf->rx_adv_conf.rss_conf.rss_hf); 31089c2ea8fSHemant Agrawal if (ret) { 31189c2ea8fSHemant Agrawal PMD_INIT_LOG(ERR, "unable to set flow distribution." 31289c2ea8fSHemant Agrawal "please check queue config\n"); 31389c2ea8fSHemant Agrawal return ret; 31489c2ea8fSHemant Agrawal } 31589c2ea8fSHemant Agrawal } 3163e5a335dSHemant Agrawal return 0; 3173e5a335dSHemant Agrawal } 3183e5a335dSHemant Agrawal 3193e5a335dSHemant Agrawal /* Function to setup RX flow information. It contains traffic class ID, 3203e5a335dSHemant Agrawal * flow ID, destination configuration etc. 3213e5a335dSHemant Agrawal */ 3223e5a335dSHemant Agrawal static int 3233e5a335dSHemant Agrawal dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, 3243e5a335dSHemant Agrawal uint16_t rx_queue_id, 3253e5a335dSHemant Agrawal uint16_t nb_rx_desc __rte_unused, 3263e5a335dSHemant Agrawal unsigned int socket_id __rte_unused, 3273e5a335dSHemant Agrawal const struct rte_eth_rxconf *rx_conf __rte_unused, 3283e5a335dSHemant Agrawal struct rte_mempool *mb_pool) 3293e5a335dSHemant Agrawal { 3303e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 3313e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 3323e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 3333e5a335dSHemant Agrawal struct dpni_queue cfg; 3343e5a335dSHemant Agrawal uint8_t options = 0; 3353e5a335dSHemant Agrawal uint8_t flow_id; 336bee61d86SHemant Agrawal uint32_t bpid; 3373e5a335dSHemant Agrawal int ret; 3383e5a335dSHemant Agrawal 3393e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 3403e5a335dSHemant Agrawal 3413e5a335dSHemant Agrawal PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p", 3423e5a335dSHemant Agrawal dev, rx_queue_id, mb_pool, rx_conf); 3433e5a335dSHemant Agrawal 344bee61d86SHemant Agrawal if (!priv->bp_list || priv->bp_list->mp != mb_pool) { 345bee61d86SHemant Agrawal bpid = mempool_to_bpid(mb_pool); 346bee61d86SHemant Agrawal ret = dpaa2_attach_bp_list(priv, 347bee61d86SHemant Agrawal rte_dpaa2_bpid_info[bpid].bp_list); 348bee61d86SHemant Agrawal if (ret) 349bee61d86SHemant Agrawal return ret; 350bee61d86SHemant Agrawal } 3513e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id]; 3523e5a335dSHemant Agrawal dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */ 3533e5a335dSHemant Agrawal 3543e5a335dSHemant Agrawal /*Get the tc id and flow id from given VQ id*/ 35589c2ea8fSHemant Agrawal flow_id = rx_queue_id % priv->num_dist_per_tc[dpaa2_q->tc_index]; 3563e5a335dSHemant Agrawal memset(&cfg, 0, sizeof(struct dpni_queue)); 3573e5a335dSHemant Agrawal 3583e5a335dSHemant Agrawal options = options | DPNI_QUEUE_OPT_USER_CTX; 3593e5a335dSHemant Agrawal cfg.user_context = (uint64_t)(dpaa2_q); 3603e5a335dSHemant Agrawal 36137529eceSHemant Agrawal /*if ls2088 or rev2 device, enable the stashing */ 36237529eceSHemant Agrawal if ((qbman_get_version() & 0xFFFF0000) > QMAN_REV_4000) { 36337529eceSHemant Agrawal options |= DPNI_QUEUE_OPT_FLC; 36437529eceSHemant Agrawal cfg.flc.stash_control = true; 36537529eceSHemant Agrawal cfg.flc.value &= 0xFFFFFFFFFFFFFFC0; 36637529eceSHemant Agrawal /* 00 00 00 - last 6 bit represent annotation, context stashing, 36737529eceSHemant Agrawal * data stashing setting 01 01 00 (0x14) to enable 3689464dbe9SHemant Agrawal * 1 line data, 1 line annotation 36937529eceSHemant Agrawal */ 37037529eceSHemant Agrawal cfg.flc.value |= 0x14; 37137529eceSHemant Agrawal } 3723e5a335dSHemant Agrawal ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX, 3733e5a335dSHemant Agrawal dpaa2_q->tc_index, flow_id, options, &cfg); 3743e5a335dSHemant Agrawal if (ret) { 3753e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the rx flow: = %d\n", ret); 3763e5a335dSHemant Agrawal return -1; 3773e5a335dSHemant Agrawal } 3783e5a335dSHemant Agrawal 37923d6a87eSHemant Agrawal if (!(priv->flags & DPAA2_RX_TAILDROP_OFF)) { 38023d6a87eSHemant Agrawal struct dpni_taildrop taildrop; 38123d6a87eSHemant Agrawal 38223d6a87eSHemant Agrawal taildrop.enable = 1; 38323d6a87eSHemant Agrawal /*enabling per rx queue congestion control */ 38423d6a87eSHemant Agrawal taildrop.threshold = CONG_THRESHOLD_RX_Q; 38523d6a87eSHemant Agrawal taildrop.units = DPNI_CONGESTION_UNIT_BYTES; 38623d6a87eSHemant Agrawal PMD_INIT_LOG(DEBUG, "Enabling Early Drop on queue = %d", 38723d6a87eSHemant Agrawal rx_queue_id); 38823d6a87eSHemant Agrawal ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, 38923d6a87eSHemant Agrawal DPNI_CP_QUEUE, DPNI_QUEUE_RX, 39023d6a87eSHemant Agrawal dpaa2_q->tc_index, flow_id, &taildrop); 39123d6a87eSHemant Agrawal if (ret) { 39223d6a87eSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the rx flow" 39323d6a87eSHemant Agrawal " err : = %d\n", ret); 39423d6a87eSHemant Agrawal return -1; 39523d6a87eSHemant Agrawal } 39623d6a87eSHemant Agrawal } 39723d6a87eSHemant Agrawal 3983e5a335dSHemant Agrawal dev->data->rx_queues[rx_queue_id] = dpaa2_q; 3993e5a335dSHemant Agrawal return 0; 4003e5a335dSHemant Agrawal } 4013e5a335dSHemant Agrawal 4023e5a335dSHemant Agrawal static int 4033e5a335dSHemant Agrawal dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, 4043e5a335dSHemant Agrawal uint16_t tx_queue_id, 4053e5a335dSHemant Agrawal uint16_t nb_tx_desc __rte_unused, 4063e5a335dSHemant Agrawal unsigned int socket_id __rte_unused, 4073e5a335dSHemant Agrawal const struct rte_eth_txconf *tx_conf __rte_unused) 4083e5a335dSHemant Agrawal { 4093e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 4103e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *) 4113e5a335dSHemant Agrawal priv->tx_vq[tx_queue_id]; 4123e5a335dSHemant Agrawal struct fsl_mc_io *dpni = priv->hw; 4133e5a335dSHemant Agrawal struct dpni_queue tx_conf_cfg; 4143e5a335dSHemant Agrawal struct dpni_queue tx_flow_cfg; 4153e5a335dSHemant Agrawal uint8_t options = 0, flow_id; 4163e5a335dSHemant Agrawal uint32_t tc_id; 4173e5a335dSHemant Agrawal int ret; 4183e5a335dSHemant Agrawal 4193e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 4203e5a335dSHemant Agrawal 4213e5a335dSHemant Agrawal /* Return if queue already configured */ 4227ae777d0SHemant Agrawal if (dpaa2_q->flow_id != 0xffff) 4233e5a335dSHemant Agrawal return 0; 4243e5a335dSHemant Agrawal 4253e5a335dSHemant Agrawal memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue)); 4263e5a335dSHemant Agrawal memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue)); 4273e5a335dSHemant Agrawal 428ef18dafeSHemant Agrawal if (priv->num_tc == 1) { 4293e5a335dSHemant Agrawal tc_id = 0; 430ef18dafeSHemant Agrawal flow_id = tx_queue_id % priv->num_dist_per_tc[tc_id]; 431ef18dafeSHemant Agrawal } else { 432ef18dafeSHemant Agrawal tc_id = tx_queue_id; 433ef18dafeSHemant Agrawal flow_id = 0; 434ef18dafeSHemant Agrawal } 4353e5a335dSHemant Agrawal 4363e5a335dSHemant Agrawal ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX, 4373e5a335dSHemant Agrawal tc_id, flow_id, options, &tx_flow_cfg); 4383e5a335dSHemant Agrawal if (ret) { 4393e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in setting the tx flow: " 4403e5a335dSHemant Agrawal "tc_id=%d, flow =%d ErrorCode = %x\n", 4413e5a335dSHemant Agrawal tc_id, flow_id, -ret); 4423e5a335dSHemant Agrawal return -1; 4433e5a335dSHemant Agrawal } 4443e5a335dSHemant Agrawal 4453e5a335dSHemant Agrawal dpaa2_q->flow_id = flow_id; 4463e5a335dSHemant Agrawal 4473e5a335dSHemant Agrawal if (tx_queue_id == 0) { 4483e5a335dSHemant Agrawal /*Set tx-conf and error configuration*/ 4493e5a335dSHemant Agrawal ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW, 4503e5a335dSHemant Agrawal priv->token, 4513e5a335dSHemant Agrawal DPNI_CONF_DISABLE); 4523e5a335dSHemant Agrawal if (ret) { 4533e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error in set tx conf mode settings" 4543e5a335dSHemant Agrawal " ErrorCode = %x", ret); 4553e5a335dSHemant Agrawal return -1; 4563e5a335dSHemant Agrawal } 4573e5a335dSHemant Agrawal } 4583e5a335dSHemant Agrawal dpaa2_q->tc_index = tc_id; 4593e5a335dSHemant Agrawal 4607ae777d0SHemant Agrawal if (priv->flags & DPAA2_TX_CGR_SUPPORT) { 4617ae777d0SHemant Agrawal struct dpni_congestion_notification_cfg cong_notif_cfg; 4627ae777d0SHemant Agrawal 4637ae777d0SHemant Agrawal cong_notif_cfg.units = DPNI_CONGESTION_UNIT_BYTES; 4647ae777d0SHemant Agrawal /* Notify about congestion when the queue size is 32 KB */ 4657ae777d0SHemant Agrawal cong_notif_cfg.threshold_entry = CONG_ENTER_TX_THRESHOLD; 4667ae777d0SHemant Agrawal /* Notify that the queue is not congested when the data in 4677ae777d0SHemant Agrawal * the queue is below this thershold. 4687ae777d0SHemant Agrawal */ 4697ae777d0SHemant Agrawal cong_notif_cfg.threshold_exit = CONG_EXIT_TX_THRESHOLD; 4707ae777d0SHemant Agrawal cong_notif_cfg.message_ctx = 0; 4717ae777d0SHemant Agrawal cong_notif_cfg.message_iova = (uint64_t)dpaa2_q->cscn; 4727ae777d0SHemant Agrawal cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE; 4737ae777d0SHemant Agrawal cong_notif_cfg.notification_mode = 4747ae777d0SHemant Agrawal DPNI_CONG_OPT_WRITE_MEM_ON_ENTER | 4757ae777d0SHemant Agrawal DPNI_CONG_OPT_WRITE_MEM_ON_EXIT | 4767ae777d0SHemant Agrawal DPNI_CONG_OPT_COHERENT_WRITE; 4777ae777d0SHemant Agrawal 4787ae777d0SHemant Agrawal ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW, 4797ae777d0SHemant Agrawal priv->token, 4807ae777d0SHemant Agrawal DPNI_QUEUE_TX, 4817ae777d0SHemant Agrawal tc_id, 4827ae777d0SHemant Agrawal &cong_notif_cfg); 4837ae777d0SHemant Agrawal if (ret) { 4847ae777d0SHemant Agrawal PMD_INIT_LOG(ERR, 4857ae777d0SHemant Agrawal "Error in setting tx congestion notification: = %d", 4867ae777d0SHemant Agrawal -ret); 4877ae777d0SHemant Agrawal return -ret; 4887ae777d0SHemant Agrawal } 4897ae777d0SHemant Agrawal } 4903e5a335dSHemant Agrawal dev->data->tx_queues[tx_queue_id] = dpaa2_q; 4913e5a335dSHemant Agrawal return 0; 4923e5a335dSHemant Agrawal } 4933e5a335dSHemant Agrawal 4943e5a335dSHemant Agrawal static void 4953e5a335dSHemant Agrawal dpaa2_dev_rx_queue_release(void *q __rte_unused) 4963e5a335dSHemant Agrawal { 4973e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 4983e5a335dSHemant Agrawal } 4993e5a335dSHemant Agrawal 5003e5a335dSHemant Agrawal static void 5013e5a335dSHemant Agrawal dpaa2_dev_tx_queue_release(void *q __rte_unused) 5023e5a335dSHemant Agrawal { 5033e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 5043e5a335dSHemant Agrawal } 5053e5a335dSHemant Agrawal 506a5fc38d4SHemant Agrawal static const uint32_t * 507a5fc38d4SHemant Agrawal dpaa2_supported_ptypes_get(struct rte_eth_dev *dev) 508a5fc38d4SHemant Agrawal { 509a5fc38d4SHemant Agrawal static const uint32_t ptypes[] = { 510a5fc38d4SHemant Agrawal /*todo -= add more types */ 511a5fc38d4SHemant Agrawal RTE_PTYPE_L2_ETHER, 512a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV4, 513a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV4_EXT, 514a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV6, 515a5fc38d4SHemant Agrawal RTE_PTYPE_L3_IPV6_EXT, 516a5fc38d4SHemant Agrawal RTE_PTYPE_L4_TCP, 517a5fc38d4SHemant Agrawal RTE_PTYPE_L4_UDP, 518a5fc38d4SHemant Agrawal RTE_PTYPE_L4_SCTP, 519a5fc38d4SHemant Agrawal RTE_PTYPE_L4_ICMP, 520a5fc38d4SHemant Agrawal RTE_PTYPE_UNKNOWN 521a5fc38d4SHemant Agrawal }; 522a5fc38d4SHemant Agrawal 5235c6942fdSHemant Agrawal if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx) 524a5fc38d4SHemant Agrawal return ptypes; 525a5fc38d4SHemant Agrawal return NULL; 526a5fc38d4SHemant Agrawal } 527a5fc38d4SHemant Agrawal 5283e5a335dSHemant Agrawal static int 5293e5a335dSHemant Agrawal dpaa2_dev_start(struct rte_eth_dev *dev) 5303e5a335dSHemant Agrawal { 5313e5a335dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 5323e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = data->dev_private; 5333e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 5343e5a335dSHemant Agrawal struct dpni_queue cfg; 535ef18dafeSHemant Agrawal struct dpni_error_cfg err_cfg; 5363e5a335dSHemant Agrawal uint16_t qdid; 5373e5a335dSHemant Agrawal struct dpni_queue_id qid; 5383e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 5393e5a335dSHemant Agrawal int ret, i; 5403e5a335dSHemant Agrawal 5413e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 5423e5a335dSHemant Agrawal 5433e5a335dSHemant Agrawal ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token); 5443e5a335dSHemant Agrawal if (ret) { 5453e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n", 5463e5a335dSHemant Agrawal ret, priv->hw_id); 5473e5a335dSHemant Agrawal return ret; 5483e5a335dSHemant Agrawal } 5493e5a335dSHemant Agrawal 550a1f3a12cSHemant Agrawal /* Power up the phy. Needed to make the link go Up */ 551a1f3a12cSHemant Agrawal dpaa2_dev_set_link_up(dev); 552a1f3a12cSHemant Agrawal 5533e5a335dSHemant Agrawal ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token, 5543e5a335dSHemant Agrawal DPNI_QUEUE_TX, &qdid); 5553e5a335dSHemant Agrawal if (ret) { 5563e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get qdid:ErrorCode = %d\n", ret); 5573e5a335dSHemant Agrawal return ret; 5583e5a335dSHemant Agrawal } 5593e5a335dSHemant Agrawal priv->qdid = qdid; 5603e5a335dSHemant Agrawal 5613e5a335dSHemant Agrawal for (i = 0; i < data->nb_rx_queues; i++) { 5623e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i]; 5633e5a335dSHemant Agrawal ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token, 5643e5a335dSHemant Agrawal DPNI_QUEUE_RX, dpaa2_q->tc_index, 5653e5a335dSHemant Agrawal dpaa2_q->flow_id, &cfg, &qid); 5663e5a335dSHemant Agrawal if (ret) { 5673e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get flow " 5683e5a335dSHemant Agrawal "information Error code = %d\n", ret); 5693e5a335dSHemant Agrawal return ret; 5703e5a335dSHemant Agrawal } 5713e5a335dSHemant Agrawal dpaa2_q->fqid = qid.fqid; 5723e5a335dSHemant Agrawal } 5733e5a335dSHemant Agrawal 574ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 575ef18dafeSHemant Agrawal DPNI_OFF_RX_L3_CSUM, true); 576ef18dafeSHemant Agrawal if (ret) { 577ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret); 578ef18dafeSHemant Agrawal return ret; 579ef18dafeSHemant Agrawal } 580ef18dafeSHemant Agrawal 581ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 582ef18dafeSHemant Agrawal DPNI_OFF_RX_L4_CSUM, true); 583ef18dafeSHemant Agrawal if (ret) { 584ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret); 585ef18dafeSHemant Agrawal return ret; 586ef18dafeSHemant Agrawal } 587ef18dafeSHemant Agrawal 588ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 589ef18dafeSHemant Agrawal DPNI_OFF_TX_L3_CSUM, true); 590ef18dafeSHemant Agrawal if (ret) { 591ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret); 592ef18dafeSHemant Agrawal return ret; 593ef18dafeSHemant Agrawal } 594ef18dafeSHemant Agrawal 595ef18dafeSHemant Agrawal ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token, 596ef18dafeSHemant Agrawal DPNI_OFF_TX_L4_CSUM, true); 597ef18dafeSHemant Agrawal if (ret) { 598ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret); 599ef18dafeSHemant Agrawal return ret; 600ef18dafeSHemant Agrawal } 601ef18dafeSHemant Agrawal 602ef18dafeSHemant Agrawal /*checksum errors, send them to normal path and set it in annotation */ 603ef18dafeSHemant Agrawal err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE; 604ef18dafeSHemant Agrawal 605ef18dafeSHemant Agrawal err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE; 606ef18dafeSHemant Agrawal err_cfg.set_frame_annotation = true; 607ef18dafeSHemant Agrawal 608ef18dafeSHemant Agrawal ret = dpni_set_errors_behavior(dpni, CMD_PRI_LOW, 609ef18dafeSHemant Agrawal priv->token, &err_cfg); 610ef18dafeSHemant Agrawal if (ret) { 611ef18dafeSHemant Agrawal PMD_INIT_LOG(ERR, "Error to dpni_set_errors_behavior:" 612ef18dafeSHemant Agrawal "code = %d\n", ret); 613ef18dafeSHemant Agrawal return ret; 614ef18dafeSHemant Agrawal } 6153ce294f2SHemant Agrawal /* VLAN Offload Settings */ 6163ce294f2SHemant Agrawal if (priv->max_vlan_filters) 6173ce294f2SHemant Agrawal dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); 618ef18dafeSHemant Agrawal 6193e5a335dSHemant Agrawal return 0; 6203e5a335dSHemant Agrawal } 6213e5a335dSHemant Agrawal 6223e5a335dSHemant Agrawal /** 6233e5a335dSHemant Agrawal * This routine disables all traffic on the adapter by issuing a 6243e5a335dSHemant Agrawal * global reset on the MAC. 6253e5a335dSHemant Agrawal */ 6263e5a335dSHemant Agrawal static void 6273e5a335dSHemant Agrawal dpaa2_dev_stop(struct rte_eth_dev *dev) 6283e5a335dSHemant Agrawal { 6293e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 6303e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 6313e5a335dSHemant Agrawal int ret; 632c56c86ffSHemant Agrawal struct rte_eth_link link; 6333e5a335dSHemant Agrawal 6343e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 6353e5a335dSHemant Agrawal 636a1f3a12cSHemant Agrawal dpaa2_dev_set_link_down(dev); 637a1f3a12cSHemant Agrawal 6383e5a335dSHemant Agrawal ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token); 6393e5a335dSHemant Agrawal if (ret) { 6403e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure (ret %d) in disabling dpni %d dev\n", 6413e5a335dSHemant Agrawal ret, priv->hw_id); 6423e5a335dSHemant Agrawal return; 6433e5a335dSHemant Agrawal } 644c56c86ffSHemant Agrawal 645c56c86ffSHemant Agrawal /* clear the recorded link status */ 646c56c86ffSHemant Agrawal memset(&link, 0, sizeof(link)); 647c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 6483e5a335dSHemant Agrawal } 6493e5a335dSHemant Agrawal 6503e5a335dSHemant Agrawal static void 6513e5a335dSHemant Agrawal dpaa2_dev_close(struct rte_eth_dev *dev) 6523e5a335dSHemant Agrawal { 6537ae777d0SHemant Agrawal struct rte_eth_dev_data *data = dev->data; 6543e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 6553e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 6567ae777d0SHemant Agrawal int i, ret; 657a1f3a12cSHemant Agrawal struct rte_eth_link link; 6587ae777d0SHemant Agrawal struct dpaa2_queue *dpaa2_q; 6593e5a335dSHemant Agrawal 6603e5a335dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 6613e5a335dSHemant Agrawal 6627ae777d0SHemant Agrawal for (i = 0; i < data->nb_tx_queues; i++) { 6637ae777d0SHemant Agrawal dpaa2_q = (struct dpaa2_queue *)data->tx_queues[i]; 6647ae777d0SHemant Agrawal if (!dpaa2_q->cscn) { 6657ae777d0SHemant Agrawal rte_free(dpaa2_q->cscn); 6667ae777d0SHemant Agrawal dpaa2_q->cscn = NULL; 6677ae777d0SHemant Agrawal } 6687ae777d0SHemant Agrawal } 6697ae777d0SHemant Agrawal 6703e5a335dSHemant Agrawal /* Clean the device first */ 6713e5a335dSHemant Agrawal ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token); 6723e5a335dSHemant Agrawal if (ret) { 6733e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "Failure cleaning dpni device with" 6743e5a335dSHemant Agrawal " error code %d\n", ret); 6753e5a335dSHemant Agrawal return; 6763e5a335dSHemant Agrawal } 677a1f3a12cSHemant Agrawal 678a1f3a12cSHemant Agrawal memset(&link, 0, sizeof(link)); 679a1f3a12cSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 6803e5a335dSHemant Agrawal } 6813e5a335dSHemant Agrawal 682c0e5c69aSHemant Agrawal static void 683c0e5c69aSHemant Agrawal dpaa2_dev_promiscuous_enable( 684c0e5c69aSHemant Agrawal struct rte_eth_dev *dev) 685c0e5c69aSHemant Agrawal { 686c0e5c69aSHemant Agrawal int ret; 687c0e5c69aSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 688c0e5c69aSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 689c0e5c69aSHemant Agrawal 690c0e5c69aSHemant Agrawal PMD_INIT_FUNC_TRACE(); 691c0e5c69aSHemant Agrawal 692c0e5c69aSHemant Agrawal if (dpni == NULL) { 693c0e5c69aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 694c0e5c69aSHemant Agrawal return; 695c0e5c69aSHemant Agrawal } 696c0e5c69aSHemant Agrawal 697c0e5c69aSHemant Agrawal ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 698c0e5c69aSHemant Agrawal if (ret < 0) 6995d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable U promisc mode %d", ret); 7005d5aeeedSHemant Agrawal 7015d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 7025d5aeeedSHemant Agrawal if (ret < 0) 7035d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable M promisc mode %d", ret); 704c0e5c69aSHemant Agrawal } 705c0e5c69aSHemant Agrawal 706c0e5c69aSHemant Agrawal static void 707c0e5c69aSHemant Agrawal dpaa2_dev_promiscuous_disable( 708c0e5c69aSHemant Agrawal struct rte_eth_dev *dev) 709c0e5c69aSHemant Agrawal { 710c0e5c69aSHemant Agrawal int ret; 711c0e5c69aSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 712c0e5c69aSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 713c0e5c69aSHemant Agrawal 714c0e5c69aSHemant Agrawal PMD_INIT_FUNC_TRACE(); 715c0e5c69aSHemant Agrawal 716c0e5c69aSHemant Agrawal if (dpni == NULL) { 717c0e5c69aSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 718c0e5c69aSHemant Agrawal return; 719c0e5c69aSHemant Agrawal } 720c0e5c69aSHemant Agrawal 721c0e5c69aSHemant Agrawal ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); 722c0e5c69aSHemant Agrawal if (ret < 0) 7235d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to disable U promisc mode %d", ret); 7245d5aeeedSHemant Agrawal 7255d5aeeedSHemant Agrawal if (dev->data->all_multicast == 0) { 7265d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, 7275d5aeeedSHemant Agrawal priv->token, false); 7285d5aeeedSHemant Agrawal if (ret < 0) 7295d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to disable M promisc mode %d", 7305d5aeeedSHemant Agrawal ret); 7315d5aeeedSHemant Agrawal } 7325d5aeeedSHemant Agrawal } 7335d5aeeedSHemant Agrawal 7345d5aeeedSHemant Agrawal static void 7355d5aeeedSHemant Agrawal dpaa2_dev_allmulticast_enable( 7365d5aeeedSHemant Agrawal struct rte_eth_dev *dev) 7375d5aeeedSHemant Agrawal { 7385d5aeeedSHemant Agrawal int ret; 7395d5aeeedSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 7405d5aeeedSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 7415d5aeeedSHemant Agrawal 7425d5aeeedSHemant Agrawal PMD_INIT_FUNC_TRACE(); 7435d5aeeedSHemant Agrawal 7445d5aeeedSHemant Agrawal if (dpni == NULL) { 7455d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 7465d5aeeedSHemant Agrawal return; 7475d5aeeedSHemant Agrawal } 7485d5aeeedSHemant Agrawal 7495d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true); 7505d5aeeedSHemant Agrawal if (ret < 0) 7515d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to enable multicast mode %d", ret); 7525d5aeeedSHemant Agrawal } 7535d5aeeedSHemant Agrawal 7545d5aeeedSHemant Agrawal static void 7555d5aeeedSHemant Agrawal dpaa2_dev_allmulticast_disable(struct rte_eth_dev *dev) 7565d5aeeedSHemant Agrawal { 7575d5aeeedSHemant Agrawal int ret; 7585d5aeeedSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 7595d5aeeedSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 7605d5aeeedSHemant Agrawal 7615d5aeeedSHemant Agrawal PMD_INIT_FUNC_TRACE(); 7625d5aeeedSHemant Agrawal 7635d5aeeedSHemant Agrawal if (dpni == NULL) { 7645d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 7655d5aeeedSHemant Agrawal return; 7665d5aeeedSHemant Agrawal } 7675d5aeeedSHemant Agrawal 7685d5aeeedSHemant Agrawal /* must remain on for all promiscuous */ 7695d5aeeedSHemant Agrawal if (dev->data->promiscuous == 1) 7705d5aeeedSHemant Agrawal return; 7715d5aeeedSHemant Agrawal 7725d5aeeedSHemant Agrawal ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, false); 7735d5aeeedSHemant Agrawal if (ret < 0) 7745d5aeeedSHemant Agrawal RTE_LOG(ERR, PMD, "Unable to disable multicast mode %d", ret); 775c0e5c69aSHemant Agrawal } 776e31d4d21SHemant Agrawal 777e31d4d21SHemant Agrawal static int 778e31d4d21SHemant Agrawal dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 779e31d4d21SHemant Agrawal { 780e31d4d21SHemant Agrawal int ret; 781e31d4d21SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 782e31d4d21SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 783e31d4d21SHemant Agrawal uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; 784e31d4d21SHemant Agrawal 785e31d4d21SHemant Agrawal PMD_INIT_FUNC_TRACE(); 786e31d4d21SHemant Agrawal 787e31d4d21SHemant Agrawal if (dpni == NULL) { 788e31d4d21SHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 789e31d4d21SHemant Agrawal return -EINVAL; 790e31d4d21SHemant Agrawal } 791e31d4d21SHemant Agrawal 792e31d4d21SHemant Agrawal /* check that mtu is within the allowed range */ 793e31d4d21SHemant Agrawal if ((mtu < ETHER_MIN_MTU) || (frame_size > DPAA2_MAX_RX_PKT_LEN)) 794e31d4d21SHemant Agrawal return -EINVAL; 795e31d4d21SHemant Agrawal 796*e1640849SHemant Agrawal if (frame_size > ETHER_MAX_LEN) 797*e1640849SHemant Agrawal dev->data->dev_conf.rxmode.jumbo_frame = 1; 798*e1640849SHemant Agrawal else 799*e1640849SHemant Agrawal dev->data->dev_conf.rxmode.jumbo_frame = 0; 800*e1640849SHemant Agrawal 801e31d4d21SHemant Agrawal /* Set the Max Rx frame length as 'mtu' + 802e31d4d21SHemant Agrawal * Maximum Ethernet header length 803e31d4d21SHemant Agrawal */ 804e31d4d21SHemant Agrawal ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token, 805e31d4d21SHemant Agrawal mtu + ETH_VLAN_HLEN); 806e31d4d21SHemant Agrawal if (ret) { 807e31d4d21SHemant Agrawal PMD_DRV_LOG(ERR, "setting the max frame length failed"); 808e31d4d21SHemant Agrawal return -1; 809e31d4d21SHemant Agrawal } 810e31d4d21SHemant Agrawal PMD_DRV_LOG(INFO, "MTU is configured %d for the device\n", mtu); 811e31d4d21SHemant Agrawal return 0; 812e31d4d21SHemant Agrawal } 813e31d4d21SHemant Agrawal 814b4d97b7dSHemant Agrawal static int 815b4d97b7dSHemant Agrawal dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev, 816b4d97b7dSHemant Agrawal struct ether_addr *addr, 817b4d97b7dSHemant Agrawal __rte_unused uint32_t index, 818b4d97b7dSHemant Agrawal __rte_unused uint32_t pool) 819b4d97b7dSHemant Agrawal { 820b4d97b7dSHemant Agrawal int ret; 821b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 822b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 823b4d97b7dSHemant Agrawal 824b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 825b4d97b7dSHemant Agrawal 826b4d97b7dSHemant Agrawal if (dpni == NULL) { 827b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 828b4d97b7dSHemant Agrawal return -1; 829b4d97b7dSHemant Agrawal } 830b4d97b7dSHemant Agrawal 831b4d97b7dSHemant Agrawal ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW, 832b4d97b7dSHemant Agrawal priv->token, addr->addr_bytes); 833b4d97b7dSHemant Agrawal if (ret) 834b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "error: Adding the MAC ADDR failed:" 835b4d97b7dSHemant Agrawal " err = %d", ret); 836b4d97b7dSHemant Agrawal return 0; 837b4d97b7dSHemant Agrawal } 838b4d97b7dSHemant Agrawal 839b4d97b7dSHemant Agrawal static void 840b4d97b7dSHemant Agrawal dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev, 841b4d97b7dSHemant Agrawal uint32_t index) 842b4d97b7dSHemant Agrawal { 843b4d97b7dSHemant Agrawal int ret; 844b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 845b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 846b4d97b7dSHemant Agrawal struct rte_eth_dev_data *data = dev->data; 847b4d97b7dSHemant Agrawal struct ether_addr *macaddr; 848b4d97b7dSHemant Agrawal 849b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 850b4d97b7dSHemant Agrawal 851b4d97b7dSHemant Agrawal macaddr = &data->mac_addrs[index]; 852b4d97b7dSHemant Agrawal 853b4d97b7dSHemant Agrawal if (dpni == NULL) { 854b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 855b4d97b7dSHemant Agrawal return; 856b4d97b7dSHemant Agrawal } 857b4d97b7dSHemant Agrawal 858b4d97b7dSHemant Agrawal ret = dpni_remove_mac_addr(dpni, CMD_PRI_LOW, 859b4d97b7dSHemant Agrawal priv->token, macaddr->addr_bytes); 860b4d97b7dSHemant Agrawal if (ret) 861b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "error: Removing the MAC ADDR failed:" 862b4d97b7dSHemant Agrawal " err = %d", ret); 863b4d97b7dSHemant Agrawal } 864b4d97b7dSHemant Agrawal 865b4d97b7dSHemant Agrawal static void 866b4d97b7dSHemant Agrawal dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev, 867b4d97b7dSHemant Agrawal struct ether_addr *addr) 868b4d97b7dSHemant Agrawal { 869b4d97b7dSHemant Agrawal int ret; 870b4d97b7dSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 871b4d97b7dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 872b4d97b7dSHemant Agrawal 873b4d97b7dSHemant Agrawal PMD_INIT_FUNC_TRACE(); 874b4d97b7dSHemant Agrawal 875b4d97b7dSHemant Agrawal if (dpni == NULL) { 876b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 877b4d97b7dSHemant Agrawal return; 878b4d97b7dSHemant Agrawal } 879b4d97b7dSHemant Agrawal 880b4d97b7dSHemant Agrawal ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW, 881b4d97b7dSHemant Agrawal priv->token, addr->addr_bytes); 882b4d97b7dSHemant Agrawal 883b4d97b7dSHemant Agrawal if (ret) 884b4d97b7dSHemant Agrawal RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret); 885b4d97b7dSHemant Agrawal } 886b0aa5459SHemant Agrawal static 887b0aa5459SHemant Agrawal void dpaa2_dev_stats_get(struct rte_eth_dev *dev, 888b0aa5459SHemant Agrawal struct rte_eth_stats *stats) 889b0aa5459SHemant Agrawal { 890b0aa5459SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 891b0aa5459SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 892b0aa5459SHemant Agrawal int32_t retcode; 893b0aa5459SHemant Agrawal uint8_t page0 = 0, page1 = 1, page2 = 2; 894b0aa5459SHemant Agrawal union dpni_statistics value; 895b0aa5459SHemant Agrawal 896b0aa5459SHemant Agrawal memset(&value, 0, sizeof(union dpni_statistics)); 897b0aa5459SHemant Agrawal 898b0aa5459SHemant Agrawal PMD_INIT_FUNC_TRACE(); 899b0aa5459SHemant Agrawal 900b0aa5459SHemant Agrawal if (!dpni) { 901b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 902b0aa5459SHemant Agrawal return; 903b0aa5459SHemant Agrawal } 904b0aa5459SHemant Agrawal 905b0aa5459SHemant Agrawal if (!stats) { 906b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "stats is NULL"); 907b0aa5459SHemant Agrawal return; 908b0aa5459SHemant Agrawal } 909b0aa5459SHemant Agrawal 910b0aa5459SHemant Agrawal /*Get Counters from page_0*/ 911b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 912b0aa5459SHemant Agrawal page0, &value); 913b0aa5459SHemant Agrawal if (retcode) 914b0aa5459SHemant Agrawal goto err; 915b0aa5459SHemant Agrawal 916b0aa5459SHemant Agrawal stats->ipackets = value.page_0.ingress_all_frames; 917b0aa5459SHemant Agrawal stats->ibytes = value.page_0.ingress_all_bytes; 918b0aa5459SHemant Agrawal 919b0aa5459SHemant Agrawal /*Get Counters from page_1*/ 920b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 921b0aa5459SHemant Agrawal page1, &value); 922b0aa5459SHemant Agrawal if (retcode) 923b0aa5459SHemant Agrawal goto err; 924b0aa5459SHemant Agrawal 925b0aa5459SHemant Agrawal stats->opackets = value.page_1.egress_all_frames; 926b0aa5459SHemant Agrawal stats->obytes = value.page_1.egress_all_bytes; 927b0aa5459SHemant Agrawal 928b0aa5459SHemant Agrawal /*Get Counters from page_2*/ 929b0aa5459SHemant Agrawal retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 930b0aa5459SHemant Agrawal page2, &value); 931b0aa5459SHemant Agrawal if (retcode) 932b0aa5459SHemant Agrawal goto err; 933b0aa5459SHemant Agrawal 934b4d97b7dSHemant Agrawal /* Ingress drop frame count due to configured rules */ 935b4d97b7dSHemant Agrawal stats->ierrors = value.page_2.ingress_filtered_frames; 936b4d97b7dSHemant Agrawal /* Ingress drop frame count due to error */ 937b4d97b7dSHemant Agrawal stats->ierrors += value.page_2.ingress_discarded_frames; 938b4d97b7dSHemant Agrawal 939b0aa5459SHemant Agrawal stats->oerrors = value.page_2.egress_discarded_frames; 940b0aa5459SHemant Agrawal stats->imissed = value.page_2.ingress_nobuffer_discards; 941b0aa5459SHemant Agrawal 942b0aa5459SHemant Agrawal return; 943b0aa5459SHemant Agrawal 944b0aa5459SHemant Agrawal err: 945b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode); 946b0aa5459SHemant Agrawal return; 947b0aa5459SHemant Agrawal }; 948b0aa5459SHemant Agrawal 949b0aa5459SHemant Agrawal static 950b0aa5459SHemant Agrawal void dpaa2_dev_stats_reset(struct rte_eth_dev *dev) 951b0aa5459SHemant Agrawal { 952b0aa5459SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 953b0aa5459SHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 954b0aa5459SHemant Agrawal int32_t retcode; 955b0aa5459SHemant Agrawal 956b0aa5459SHemant Agrawal PMD_INIT_FUNC_TRACE(); 957b0aa5459SHemant Agrawal 958b0aa5459SHemant Agrawal if (dpni == NULL) { 959b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 960b0aa5459SHemant Agrawal return; 961b0aa5459SHemant Agrawal } 962b0aa5459SHemant Agrawal 963b0aa5459SHemant Agrawal retcode = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token); 964b0aa5459SHemant Agrawal if (retcode) 965b0aa5459SHemant Agrawal goto error; 966b0aa5459SHemant Agrawal 967b0aa5459SHemant Agrawal return; 968b0aa5459SHemant Agrawal 969b0aa5459SHemant Agrawal error: 970b0aa5459SHemant Agrawal RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode); 971b0aa5459SHemant Agrawal return; 972b0aa5459SHemant Agrawal }; 973b0aa5459SHemant Agrawal 974c56c86ffSHemant Agrawal /* return 0 means link status changed, -1 means not changed */ 975c56c86ffSHemant Agrawal static int 976c56c86ffSHemant Agrawal dpaa2_dev_link_update(struct rte_eth_dev *dev, 977c56c86ffSHemant Agrawal int wait_to_complete __rte_unused) 978c56c86ffSHemant Agrawal { 979c56c86ffSHemant Agrawal int ret; 980c56c86ffSHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 981c56c86ffSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 982c56c86ffSHemant Agrawal struct rte_eth_link link, old; 983c56c86ffSHemant Agrawal struct dpni_link_state state = {0}; 984c56c86ffSHemant Agrawal 985c56c86ffSHemant Agrawal PMD_INIT_FUNC_TRACE(); 986c56c86ffSHemant Agrawal 987c56c86ffSHemant Agrawal if (dpni == NULL) { 988c56c86ffSHemant Agrawal RTE_LOG(ERR, PMD, "error : dpni is NULL"); 989c56c86ffSHemant Agrawal return 0; 990c56c86ffSHemant Agrawal } 991c56c86ffSHemant Agrawal memset(&old, 0, sizeof(old)); 992c56c86ffSHemant Agrawal dpaa2_dev_atomic_read_link_status(dev, &old); 993c56c86ffSHemant Agrawal 994c56c86ffSHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 995c56c86ffSHemant Agrawal if (ret < 0) { 996c56c86ffSHemant Agrawal RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d", ret); 997c56c86ffSHemant Agrawal return -1; 998c56c86ffSHemant Agrawal } 999c56c86ffSHemant Agrawal 1000c56c86ffSHemant Agrawal if ((old.link_status == state.up) && (old.link_speed == state.rate)) { 1001c56c86ffSHemant Agrawal RTE_LOG(DEBUG, PMD, "No change in status\n"); 1002c56c86ffSHemant Agrawal return -1; 1003c56c86ffSHemant Agrawal } 1004c56c86ffSHemant Agrawal 1005c56c86ffSHemant Agrawal memset(&link, 0, sizeof(struct rte_eth_link)); 1006c56c86ffSHemant Agrawal link.link_status = state.up; 1007c56c86ffSHemant Agrawal link.link_speed = state.rate; 1008c56c86ffSHemant Agrawal 1009c56c86ffSHemant Agrawal if (state.options & DPNI_LINK_OPT_HALF_DUPLEX) 1010c56c86ffSHemant Agrawal link.link_duplex = ETH_LINK_HALF_DUPLEX; 1011c56c86ffSHemant Agrawal else 1012c56c86ffSHemant Agrawal link.link_duplex = ETH_LINK_FULL_DUPLEX; 1013c56c86ffSHemant Agrawal 1014c56c86ffSHemant Agrawal dpaa2_dev_atomic_write_link_status(dev, &link); 1015c56c86ffSHemant Agrawal 1016c56c86ffSHemant Agrawal if (link.link_status) 1017c56c86ffSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id); 1018c56c86ffSHemant Agrawal else 1019c56c86ffSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link is Down\n", dev->data->port_id); 1020c56c86ffSHemant Agrawal return 0; 1021c56c86ffSHemant Agrawal } 1022c56c86ffSHemant Agrawal 1023a1f3a12cSHemant Agrawal /** 1024a1f3a12cSHemant Agrawal * Toggle the DPNI to enable, if not already enabled. 1025a1f3a12cSHemant Agrawal * This is not strictly PHY up/down - it is more of logical toggling. 1026a1f3a12cSHemant Agrawal */ 1027a1f3a12cSHemant Agrawal static int 1028a1f3a12cSHemant Agrawal dpaa2_dev_set_link_up(struct rte_eth_dev *dev) 1029a1f3a12cSHemant Agrawal { 1030a1f3a12cSHemant Agrawal int ret = -EINVAL; 1031a1f3a12cSHemant Agrawal struct dpaa2_dev_priv *priv; 1032a1f3a12cSHemant Agrawal struct fsl_mc_io *dpni; 1033a1f3a12cSHemant Agrawal int en = 0; 1034a1f3a12cSHemant Agrawal 1035a1f3a12cSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1036a1f3a12cSHemant Agrawal 1037a1f3a12cSHemant Agrawal priv = dev->data->dev_private; 1038a1f3a12cSHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1039a1f3a12cSHemant Agrawal 1040a1f3a12cSHemant Agrawal if (dpni == NULL) { 1041a1f3a12cSHemant Agrawal RTE_LOG(ERR, PMD, "Device has not yet been configured"); 1042a1f3a12cSHemant Agrawal return ret; 1043a1f3a12cSHemant Agrawal } 1044a1f3a12cSHemant Agrawal 1045a1f3a12cSHemant Agrawal /* Check if DPNI is currently enabled */ 1046a1f3a12cSHemant Agrawal ret = dpni_is_enabled(dpni, CMD_PRI_LOW, priv->token, &en); 1047a1f3a12cSHemant Agrawal if (ret) { 1048a1f3a12cSHemant Agrawal /* Unable to obtain dpni status; Not continuing */ 1049a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret); 1050a1f3a12cSHemant Agrawal return -EINVAL; 1051a1f3a12cSHemant Agrawal } 1052a1f3a12cSHemant Agrawal 1053a1f3a12cSHemant Agrawal /* Enable link if not already enabled */ 1054a1f3a12cSHemant Agrawal if (!en) { 1055a1f3a12cSHemant Agrawal ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token); 1056a1f3a12cSHemant Agrawal if (ret) { 1057a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret); 1058a1f3a12cSHemant Agrawal return -EINVAL; 1059a1f3a12cSHemant Agrawal } 1060a1f3a12cSHemant Agrawal } 1061a1f3a12cSHemant Agrawal /* changing tx burst function to start enqueues */ 1062a1f3a12cSHemant Agrawal dev->tx_pkt_burst = dpaa2_dev_tx; 1063a1f3a12cSHemant Agrawal dev->data->dev_link.link_status = 1; 1064a1f3a12cSHemant Agrawal 1065a1f3a12cSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link UP successful", dev->data->port_id); 1066a1f3a12cSHemant Agrawal return ret; 1067a1f3a12cSHemant Agrawal } 1068a1f3a12cSHemant Agrawal 1069a1f3a12cSHemant Agrawal /** 1070a1f3a12cSHemant Agrawal * Toggle the DPNI to disable, if not already disabled. 1071a1f3a12cSHemant Agrawal * This is not strictly PHY up/down - it is more of logical toggling. 1072a1f3a12cSHemant Agrawal */ 1073a1f3a12cSHemant Agrawal static int 1074a1f3a12cSHemant Agrawal dpaa2_dev_set_link_down(struct rte_eth_dev *dev) 1075a1f3a12cSHemant Agrawal { 1076a1f3a12cSHemant Agrawal int ret = -EINVAL; 1077a1f3a12cSHemant Agrawal struct dpaa2_dev_priv *priv; 1078a1f3a12cSHemant Agrawal struct fsl_mc_io *dpni; 1079a1f3a12cSHemant Agrawal int dpni_enabled = 0; 1080a1f3a12cSHemant Agrawal int retries = 10; 1081a1f3a12cSHemant Agrawal 1082a1f3a12cSHemant Agrawal PMD_INIT_FUNC_TRACE(); 1083a1f3a12cSHemant Agrawal 1084a1f3a12cSHemant Agrawal priv = dev->data->dev_private; 1085a1f3a12cSHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1086a1f3a12cSHemant Agrawal 1087a1f3a12cSHemant Agrawal if (dpni == NULL) { 1088a1f3a12cSHemant Agrawal RTE_LOG(ERR, PMD, "Device has not yet been configured"); 1089a1f3a12cSHemant Agrawal return ret; 1090a1f3a12cSHemant Agrawal } 1091a1f3a12cSHemant Agrawal 1092a1f3a12cSHemant Agrawal /*changing tx burst function to avoid any more enqueues */ 1093a1f3a12cSHemant Agrawal dev->tx_pkt_burst = dummy_dev_tx; 1094a1f3a12cSHemant Agrawal 1095a1f3a12cSHemant Agrawal /* Loop while dpni_disable() attempts to drain the egress FQs 1096a1f3a12cSHemant Agrawal * and confirm them back to us. 1097a1f3a12cSHemant Agrawal */ 1098a1f3a12cSHemant Agrawal do { 1099a1f3a12cSHemant Agrawal ret = dpni_disable(dpni, 0, priv->token); 1100a1f3a12cSHemant Agrawal if (ret) { 1101a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "dpni disable failed (%d)", ret); 1102a1f3a12cSHemant Agrawal return ret; 1103a1f3a12cSHemant Agrawal } 1104a1f3a12cSHemant Agrawal ret = dpni_is_enabled(dpni, 0, priv->token, &dpni_enabled); 1105a1f3a12cSHemant Agrawal if (ret) { 1106a1f3a12cSHemant Agrawal PMD_DRV_LOG(ERR, "dpni_is_enabled failed (%d)", ret); 1107a1f3a12cSHemant Agrawal return ret; 1108a1f3a12cSHemant Agrawal } 1109a1f3a12cSHemant Agrawal if (dpni_enabled) 1110a1f3a12cSHemant Agrawal /* Allow the MC some slack */ 1111a1f3a12cSHemant Agrawal rte_delay_us(100 * 1000); 1112a1f3a12cSHemant Agrawal } while (dpni_enabled && --retries); 1113a1f3a12cSHemant Agrawal 1114a1f3a12cSHemant Agrawal if (!retries) { 1115a1f3a12cSHemant Agrawal PMD_DRV_LOG(WARNING, "Retry count exceeded disabling DPNI\n"); 1116a1f3a12cSHemant Agrawal /* todo- we may have to manually cleanup queues. 1117a1f3a12cSHemant Agrawal */ 1118a1f3a12cSHemant Agrawal } else { 1119a1f3a12cSHemant Agrawal PMD_DRV_LOG(INFO, "Port %d Link DOWN successful", 1120a1f3a12cSHemant Agrawal dev->data->port_id); 1121a1f3a12cSHemant Agrawal } 1122a1f3a12cSHemant Agrawal 1123a1f3a12cSHemant Agrawal dev->data->dev_link.link_status = 0; 1124a1f3a12cSHemant Agrawal 1125a1f3a12cSHemant Agrawal return ret; 1126a1f3a12cSHemant Agrawal } 1127a1f3a12cSHemant Agrawal 1128977d0006SHemant Agrawal static int 1129977d0006SHemant Agrawal dpaa2_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1130977d0006SHemant Agrawal { 1131977d0006SHemant Agrawal int ret = -EINVAL; 1132977d0006SHemant Agrawal struct dpaa2_dev_priv *priv; 1133977d0006SHemant Agrawal struct fsl_mc_io *dpni; 1134977d0006SHemant Agrawal struct dpni_link_state state = {0}; 1135977d0006SHemant Agrawal 1136977d0006SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1137977d0006SHemant Agrawal 1138977d0006SHemant Agrawal priv = dev->data->dev_private; 1139977d0006SHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1140977d0006SHemant Agrawal 1141977d0006SHemant Agrawal if (dpni == NULL || fc_conf == NULL) { 1142977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "device not configured"); 1143977d0006SHemant Agrawal return ret; 1144977d0006SHemant Agrawal } 1145977d0006SHemant Agrawal 1146977d0006SHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 1147977d0006SHemant Agrawal if (ret) { 1148977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d", ret); 1149977d0006SHemant Agrawal return ret; 1150977d0006SHemant Agrawal } 1151977d0006SHemant Agrawal 1152977d0006SHemant Agrawal memset(fc_conf, 0, sizeof(struct rte_eth_fc_conf)); 1153977d0006SHemant Agrawal if (state.options & DPNI_LINK_OPT_PAUSE) { 1154977d0006SHemant Agrawal /* DPNI_LINK_OPT_PAUSE set 1155977d0006SHemant Agrawal * if ASYM_PAUSE not set, 1156977d0006SHemant Agrawal * RX Side flow control (handle received Pause frame) 1157977d0006SHemant Agrawal * TX side flow control (send Pause frame) 1158977d0006SHemant Agrawal * if ASYM_PAUSE set, 1159977d0006SHemant Agrawal * RX Side flow control (handle received Pause frame) 1160977d0006SHemant Agrawal * No TX side flow control (send Pause frame disabled) 1161977d0006SHemant Agrawal */ 1162977d0006SHemant Agrawal if (!(state.options & DPNI_LINK_OPT_ASYM_PAUSE)) 1163977d0006SHemant Agrawal fc_conf->mode = RTE_FC_FULL; 1164977d0006SHemant Agrawal else 1165977d0006SHemant Agrawal fc_conf->mode = RTE_FC_RX_PAUSE; 1166977d0006SHemant Agrawal } else { 1167977d0006SHemant Agrawal /* DPNI_LINK_OPT_PAUSE not set 1168977d0006SHemant Agrawal * if ASYM_PAUSE set, 1169977d0006SHemant Agrawal * TX side flow control (send Pause frame) 1170977d0006SHemant Agrawal * No RX side flow control (No action on pause frame rx) 1171977d0006SHemant Agrawal * if ASYM_PAUSE not set, 1172977d0006SHemant Agrawal * Flow control disabled 1173977d0006SHemant Agrawal */ 1174977d0006SHemant Agrawal if (state.options & DPNI_LINK_OPT_ASYM_PAUSE) 1175977d0006SHemant Agrawal fc_conf->mode = RTE_FC_TX_PAUSE; 1176977d0006SHemant Agrawal else 1177977d0006SHemant Agrawal fc_conf->mode = RTE_FC_NONE; 1178977d0006SHemant Agrawal } 1179977d0006SHemant Agrawal 1180977d0006SHemant Agrawal return ret; 1181977d0006SHemant Agrawal } 1182977d0006SHemant Agrawal 1183977d0006SHemant Agrawal static int 1184977d0006SHemant Agrawal dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1185977d0006SHemant Agrawal { 1186977d0006SHemant Agrawal int ret = -EINVAL; 1187977d0006SHemant Agrawal struct dpaa2_dev_priv *priv; 1188977d0006SHemant Agrawal struct fsl_mc_io *dpni; 1189977d0006SHemant Agrawal struct dpni_link_state state = {0}; 1190977d0006SHemant Agrawal struct dpni_link_cfg cfg = {0}; 1191977d0006SHemant Agrawal 1192977d0006SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1193977d0006SHemant Agrawal 1194977d0006SHemant Agrawal priv = dev->data->dev_private; 1195977d0006SHemant Agrawal dpni = (struct fsl_mc_io *)priv->hw; 1196977d0006SHemant Agrawal 1197977d0006SHemant Agrawal if (dpni == NULL) { 1198977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "dpni is NULL"); 1199977d0006SHemant Agrawal return ret; 1200977d0006SHemant Agrawal } 1201977d0006SHemant Agrawal 1202977d0006SHemant Agrawal /* It is necessary to obtain the current state before setting fc_conf 1203977d0006SHemant Agrawal * as MC would return error in case rate, autoneg or duplex values are 1204977d0006SHemant Agrawal * different. 1205977d0006SHemant Agrawal */ 1206977d0006SHemant Agrawal ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); 1207977d0006SHemant Agrawal if (ret) { 1208977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "Unable to get link state (err=%d)", ret); 1209977d0006SHemant Agrawal return -1; 1210977d0006SHemant Agrawal } 1211977d0006SHemant Agrawal 1212977d0006SHemant Agrawal /* Disable link before setting configuration */ 1213977d0006SHemant Agrawal dpaa2_dev_set_link_down(dev); 1214977d0006SHemant Agrawal 1215977d0006SHemant Agrawal /* Based on fc_conf, update cfg */ 1216977d0006SHemant Agrawal cfg.rate = state.rate; 1217977d0006SHemant Agrawal cfg.options = state.options; 1218977d0006SHemant Agrawal 1219977d0006SHemant Agrawal /* update cfg with fc_conf */ 1220977d0006SHemant Agrawal switch (fc_conf->mode) { 1221977d0006SHemant Agrawal case RTE_FC_FULL: 1222977d0006SHemant Agrawal /* Full flow control; 1223977d0006SHemant Agrawal * OPT_PAUSE set, ASYM_PAUSE not set 1224977d0006SHemant Agrawal */ 1225977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_PAUSE; 1226977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE; 1227977d0006SHemant Agrawal case RTE_FC_TX_PAUSE: 1228977d0006SHemant Agrawal /* Enable RX flow control 1229977d0006SHemant Agrawal * OPT_PAUSE not set; 1230977d0006SHemant Agrawal * ASYM_PAUSE set; 1231977d0006SHemant Agrawal */ 1232977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE; 1233977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_PAUSE; 1234977d0006SHemant Agrawal break; 1235977d0006SHemant Agrawal case RTE_FC_RX_PAUSE: 1236977d0006SHemant Agrawal /* Enable TX Flow control 1237977d0006SHemant Agrawal * OPT_PAUSE set 1238977d0006SHemant Agrawal * ASYM_PAUSE set 1239977d0006SHemant Agrawal */ 1240977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_PAUSE; 1241977d0006SHemant Agrawal cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE; 1242977d0006SHemant Agrawal break; 1243977d0006SHemant Agrawal case RTE_FC_NONE: 1244977d0006SHemant Agrawal /* Disable Flow control 1245977d0006SHemant Agrawal * OPT_PAUSE not set 1246977d0006SHemant Agrawal * ASYM_PAUSE not set 1247977d0006SHemant Agrawal */ 1248977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_PAUSE; 1249977d0006SHemant Agrawal cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE; 1250977d0006SHemant Agrawal break; 1251977d0006SHemant Agrawal default: 1252977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "Incorrect Flow control flag (%d)", 1253977d0006SHemant Agrawal fc_conf->mode); 1254977d0006SHemant Agrawal return -1; 1255977d0006SHemant Agrawal } 1256977d0006SHemant Agrawal 1257977d0006SHemant Agrawal ret = dpni_set_link_cfg(dpni, CMD_PRI_LOW, priv->token, &cfg); 1258977d0006SHemant Agrawal if (ret) 1259977d0006SHemant Agrawal RTE_LOG(ERR, PMD, "Unable to set Link configuration (err=%d)", 1260977d0006SHemant Agrawal ret); 1261977d0006SHemant Agrawal 1262977d0006SHemant Agrawal /* Enable link */ 1263977d0006SHemant Agrawal dpaa2_dev_set_link_up(dev); 1264977d0006SHemant Agrawal 1265977d0006SHemant Agrawal return ret; 1266977d0006SHemant Agrawal } 1267977d0006SHemant Agrawal 12683e5a335dSHemant Agrawal static struct eth_dev_ops dpaa2_ethdev_ops = { 12693e5a335dSHemant Agrawal .dev_configure = dpaa2_eth_dev_configure, 12703e5a335dSHemant Agrawal .dev_start = dpaa2_dev_start, 12713e5a335dSHemant Agrawal .dev_stop = dpaa2_dev_stop, 12723e5a335dSHemant Agrawal .dev_close = dpaa2_dev_close, 1273c0e5c69aSHemant Agrawal .promiscuous_enable = dpaa2_dev_promiscuous_enable, 1274c0e5c69aSHemant Agrawal .promiscuous_disable = dpaa2_dev_promiscuous_disable, 12755d5aeeedSHemant Agrawal .allmulticast_enable = dpaa2_dev_allmulticast_enable, 12765d5aeeedSHemant Agrawal .allmulticast_disable = dpaa2_dev_allmulticast_disable, 1277a1f3a12cSHemant Agrawal .dev_set_link_up = dpaa2_dev_set_link_up, 1278a1f3a12cSHemant Agrawal .dev_set_link_down = dpaa2_dev_set_link_down, 1279c56c86ffSHemant Agrawal .link_update = dpaa2_dev_link_update, 1280b0aa5459SHemant Agrawal .stats_get = dpaa2_dev_stats_get, 1281b0aa5459SHemant Agrawal .stats_reset = dpaa2_dev_stats_reset, 12823e5a335dSHemant Agrawal .dev_infos_get = dpaa2_dev_info_get, 1283a5fc38d4SHemant Agrawal .dev_supported_ptypes_get = dpaa2_supported_ptypes_get, 1284e31d4d21SHemant Agrawal .mtu_set = dpaa2_dev_mtu_set, 12853ce294f2SHemant Agrawal .vlan_filter_set = dpaa2_vlan_filter_set, 12863ce294f2SHemant Agrawal .vlan_offload_set = dpaa2_vlan_offload_set, 12873e5a335dSHemant Agrawal .rx_queue_setup = dpaa2_dev_rx_queue_setup, 12883e5a335dSHemant Agrawal .rx_queue_release = dpaa2_dev_rx_queue_release, 12893e5a335dSHemant Agrawal .tx_queue_setup = dpaa2_dev_tx_queue_setup, 12903e5a335dSHemant Agrawal .tx_queue_release = dpaa2_dev_tx_queue_release, 1291977d0006SHemant Agrawal .flow_ctrl_get = dpaa2_flow_ctrl_get, 1292977d0006SHemant Agrawal .flow_ctrl_set = dpaa2_flow_ctrl_set, 1293b4d97b7dSHemant Agrawal .mac_addr_add = dpaa2_dev_add_mac_addr, 1294b4d97b7dSHemant Agrawal .mac_addr_remove = dpaa2_dev_remove_mac_addr, 1295b4d97b7dSHemant Agrawal .mac_addr_set = dpaa2_dev_set_mac_addr, 12963e5a335dSHemant Agrawal }; 12973e5a335dSHemant Agrawal 1298c147eae0SHemant Agrawal static int 1299c147eae0SHemant Agrawal dpaa2_dev_init(struct rte_eth_dev *eth_dev) 1300c147eae0SHemant Agrawal { 13013e5a335dSHemant Agrawal struct rte_device *dev = eth_dev->device; 13023e5a335dSHemant Agrawal struct rte_dpaa2_device *dpaa2_dev; 13033e5a335dSHemant Agrawal struct fsl_mc_io *dpni_dev; 13043e5a335dSHemant Agrawal struct dpni_attr attr; 13053e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; 1306bee61d86SHemant Agrawal struct dpni_buffer_layout layout; 130789c2ea8fSHemant Agrawal int i, ret, hw_id; 13083e5a335dSHemant Agrawal 1309d401ead1SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1310d401ead1SHemant Agrawal 1311c147eae0SHemant Agrawal /* For secondary processes, the primary has done all the work */ 1312c147eae0SHemant Agrawal if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1313c147eae0SHemant Agrawal return 0; 1314c147eae0SHemant Agrawal 13153e5a335dSHemant Agrawal dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device); 13163e5a335dSHemant Agrawal 13173e5a335dSHemant Agrawal hw_id = dpaa2_dev->object_id; 13183e5a335dSHemant Agrawal 1319d4984046SHemant Agrawal dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0); 13203e5a335dSHemant Agrawal if (!dpni_dev) { 13213e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "malloc failed for dpni device\n"); 13223e5a335dSHemant Agrawal return -1; 13233e5a335dSHemant Agrawal } 13243e5a335dSHemant Agrawal 13253e5a335dSHemant Agrawal dpni_dev->regs = rte_mcp_ptr_list[0]; 13263e5a335dSHemant Agrawal ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token); 13273e5a335dSHemant Agrawal if (ret) { 1328d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1329d4984046SHemant Agrawal "Failure in opening dpni@%d with err code %d\n", 1330d4984046SHemant Agrawal hw_id, ret); 1331d4984046SHemant Agrawal rte_free(dpni_dev); 13323e5a335dSHemant Agrawal return -1; 13333e5a335dSHemant Agrawal } 13343e5a335dSHemant Agrawal 13353e5a335dSHemant Agrawal /* Clean the device first */ 13363e5a335dSHemant Agrawal ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token); 13373e5a335dSHemant Agrawal if (ret) { 1338d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1339d4984046SHemant Agrawal "Failure cleaning dpni@%d with err code %d\n", 1340d4984046SHemant Agrawal hw_id, ret); 1341d4984046SHemant Agrawal goto init_err; 13423e5a335dSHemant Agrawal } 13433e5a335dSHemant Agrawal 13443e5a335dSHemant Agrawal ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr); 13453e5a335dSHemant Agrawal if (ret) { 1346d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1347d4984046SHemant Agrawal "Failure in get dpni@%d attribute, err code %d\n", 1348d4984046SHemant Agrawal hw_id, ret); 1349d4984046SHemant Agrawal goto init_err; 13503e5a335dSHemant Agrawal } 13513e5a335dSHemant Agrawal 13523e5a335dSHemant Agrawal priv->num_tc = attr.num_tcs; 135389c2ea8fSHemant Agrawal for (i = 0; i < attr.num_tcs; i++) { 135489c2ea8fSHemant Agrawal priv->num_dist_per_tc[i] = attr.num_queues; 135589c2ea8fSHemant Agrawal break; 135689c2ea8fSHemant Agrawal } 135789c2ea8fSHemant Agrawal 135889c2ea8fSHemant Agrawal /* Distribution is per Tc only, 135989c2ea8fSHemant Agrawal * so choosing RX queues from default TC only 136089c2ea8fSHemant Agrawal */ 136189c2ea8fSHemant Agrawal priv->nb_rx_queues = priv->num_dist_per_tc[DPAA2_DEF_TC]; 136289c2ea8fSHemant Agrawal 1363ef18dafeSHemant Agrawal if (attr.num_tcs == 1) 13643e5a335dSHemant Agrawal priv->nb_tx_queues = attr.num_queues; 1365ef18dafeSHemant Agrawal else 1366ef18dafeSHemant Agrawal priv->nb_tx_queues = attr.num_tcs; 1367ef18dafeSHemant Agrawal 1368ef18dafeSHemant Agrawal PMD_INIT_LOG(DEBUG, "num_tc %d", priv->num_tc); 1369ef18dafeSHemant Agrawal PMD_INIT_LOG(DEBUG, "nb_rx_queues %d", priv->nb_rx_queues); 13703e5a335dSHemant Agrawal 13713e5a335dSHemant Agrawal priv->hw = dpni_dev; 13723e5a335dSHemant Agrawal priv->hw_id = hw_id; 137333fad432SHemant Agrawal priv->options = attr.options; 137433fad432SHemant Agrawal priv->max_mac_filters = attr.mac_filter_entries; 137533fad432SHemant Agrawal priv->max_vlan_filters = attr.vlan_filter_entries; 13763e5a335dSHemant Agrawal priv->flags = 0; 13773e5a335dSHemant Agrawal 13787ae777d0SHemant Agrawal priv->flags |= DPAA2_TX_CGR_SUPPORT; 13797ae777d0SHemant Agrawal PMD_INIT_LOG(INFO, "Enable the tx congestion control support"); 13807ae777d0SHemant Agrawal 13813e5a335dSHemant Agrawal /* Allocate memory for hardware structure for queues */ 13823e5a335dSHemant Agrawal ret = dpaa2_alloc_rx_tx_queues(eth_dev); 13833e5a335dSHemant Agrawal if (ret) { 13843e5a335dSHemant Agrawal PMD_INIT_LOG(ERR, "dpaa2_alloc_rx_tx_queuesFailed\n"); 1385d4984046SHemant Agrawal goto init_err; 13863e5a335dSHemant Agrawal } 13873e5a335dSHemant Agrawal 138833fad432SHemant Agrawal /* Allocate memory for storing MAC addresses */ 138933fad432SHemant Agrawal eth_dev->data->mac_addrs = rte_zmalloc("dpni", 139033fad432SHemant Agrawal ETHER_ADDR_LEN * attr.mac_filter_entries, 0); 139133fad432SHemant Agrawal if (eth_dev->data->mac_addrs == NULL) { 1392d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1393d4984046SHemant Agrawal "Failed to allocate %d bytes needed to store MAC addresses", 139433fad432SHemant Agrawal ETHER_ADDR_LEN * attr.mac_filter_entries); 1395d4984046SHemant Agrawal ret = -ENOMEM; 1396d4984046SHemant Agrawal goto init_err; 139733fad432SHemant Agrawal } 139833fad432SHemant Agrawal 139933fad432SHemant Agrawal ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW, 140033fad432SHemant Agrawal priv->token, 140133fad432SHemant Agrawal (uint8_t *)(eth_dev->data->mac_addrs[0].addr_bytes)); 140233fad432SHemant Agrawal if (ret) { 1403d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "DPNI get mac address failed:Err Code = %d\n", 1404d4984046SHemant Agrawal ret); 1405d4984046SHemant Agrawal goto init_err; 140633fad432SHemant Agrawal } 140733fad432SHemant Agrawal 1408bee61d86SHemant Agrawal /* ... tx buffer layout ... */ 1409bee61d86SHemant Agrawal memset(&layout, 0, sizeof(struct dpni_buffer_layout)); 1410bee61d86SHemant Agrawal layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; 1411bee61d86SHemant Agrawal layout.pass_frame_status = 1; 1412bee61d86SHemant Agrawal ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, 1413bee61d86SHemant Agrawal DPNI_QUEUE_TX, &layout); 1414bee61d86SHemant Agrawal if (ret) { 1415d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "Error (%d) in setting tx buffer layout", 1416d4984046SHemant Agrawal ret); 1417d4984046SHemant Agrawal goto init_err; 1418bee61d86SHemant Agrawal } 1419bee61d86SHemant Agrawal 1420bee61d86SHemant Agrawal /* ... tx-conf and error buffer layout ... */ 1421bee61d86SHemant Agrawal memset(&layout, 0, sizeof(struct dpni_buffer_layout)); 1422bee61d86SHemant Agrawal layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; 1423bee61d86SHemant Agrawal layout.pass_frame_status = 1; 1424bee61d86SHemant Agrawal ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token, 1425bee61d86SHemant Agrawal DPNI_QUEUE_TX_CONFIRM, &layout); 1426bee61d86SHemant Agrawal if (ret) { 1427d4984046SHemant Agrawal PMD_INIT_LOG(ERR, "Error (%d) in setting tx-conf buffer layout", 1428d4984046SHemant Agrawal ret); 1429d4984046SHemant Agrawal goto init_err; 1430bee61d86SHemant Agrawal } 1431bee61d86SHemant Agrawal 14323e5a335dSHemant Agrawal eth_dev->dev_ops = &dpaa2_ethdev_ops; 1433c147eae0SHemant Agrawal eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name; 1434c147eae0SHemant Agrawal 14355c6942fdSHemant Agrawal eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; 1436cd9935ceSHemant Agrawal eth_dev->tx_pkt_burst = dpaa2_dev_tx; 14371261cd68SHemant Agrawal rte_fslmc_vfio_dmamap(); 14381261cd68SHemant Agrawal 1439c147eae0SHemant Agrawal return 0; 1440d4984046SHemant Agrawal init_err: 1441d4984046SHemant Agrawal dpaa2_dev_uninit(eth_dev); 1442d4984046SHemant Agrawal return ret; 1443c147eae0SHemant Agrawal } 1444c147eae0SHemant Agrawal 1445c147eae0SHemant Agrawal static int 14463e5a335dSHemant Agrawal dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) 1447c147eae0SHemant Agrawal { 14483e5a335dSHemant Agrawal struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; 14493e5a335dSHemant Agrawal struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 14503e5a335dSHemant Agrawal int i, ret; 14513e5a335dSHemant Agrawal struct dpaa2_queue *dpaa2_q; 14523e5a335dSHemant Agrawal 1453d401ead1SHemant Agrawal PMD_INIT_FUNC_TRACE(); 1454d401ead1SHemant Agrawal 1455c147eae0SHemant Agrawal if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1456c147eae0SHemant Agrawal return -EPERM; 1457c147eae0SHemant Agrawal 14583e5a335dSHemant Agrawal if (!dpni) { 14593e5a335dSHemant Agrawal PMD_INIT_LOG(WARNING, "Already closed or not started"); 14603e5a335dSHemant Agrawal return -1; 14613e5a335dSHemant Agrawal } 14623e5a335dSHemant Agrawal 14633e5a335dSHemant Agrawal dpaa2_dev_close(eth_dev); 14643e5a335dSHemant Agrawal 14653e5a335dSHemant Agrawal if (priv->rx_vq[0]) { 14663e5a335dSHemant Agrawal /* cleaning up queue storage */ 14673e5a335dSHemant Agrawal for (i = 0; i < priv->nb_rx_queues; i++) { 14683e5a335dSHemant Agrawal dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i]; 14693e5a335dSHemant Agrawal if (dpaa2_q->q_storage) 14703e5a335dSHemant Agrawal rte_free(dpaa2_q->q_storage); 14713e5a335dSHemant Agrawal } 14723e5a335dSHemant Agrawal /*free the all queue memory */ 14733e5a335dSHemant Agrawal rte_free(priv->rx_vq[0]); 14743e5a335dSHemant Agrawal priv->rx_vq[0] = NULL; 14753e5a335dSHemant Agrawal } 14763e5a335dSHemant Agrawal 1477d4984046SHemant Agrawal /* free memory for storing MAC addresses */ 147833fad432SHemant Agrawal if (eth_dev->data->mac_addrs) { 147933fad432SHemant Agrawal rte_free(eth_dev->data->mac_addrs); 148033fad432SHemant Agrawal eth_dev->data->mac_addrs = NULL; 148133fad432SHemant Agrawal } 14823e5a335dSHemant Agrawal 14833e5a335dSHemant Agrawal /* Close the device at underlying layer*/ 14843e5a335dSHemant Agrawal ret = dpni_close(dpni, CMD_PRI_LOW, priv->token); 14853e5a335dSHemant Agrawal if (ret) { 1486d4984046SHemant Agrawal PMD_INIT_LOG(ERR, 1487d4984046SHemant Agrawal "Failure closing dpni device with err code %d\n", 1488d4984046SHemant Agrawal ret); 14893e5a335dSHemant Agrawal } 14903e5a335dSHemant Agrawal 14913e5a335dSHemant Agrawal /* Free the allocated memory for ethernet private data and dpni*/ 14923e5a335dSHemant Agrawal priv->hw = NULL; 1493d4984046SHemant Agrawal rte_free(dpni); 14943e5a335dSHemant Agrawal 14953e5a335dSHemant Agrawal eth_dev->dev_ops = NULL; 1496cd9935ceSHemant Agrawal eth_dev->rx_pkt_burst = NULL; 1497cd9935ceSHemant Agrawal eth_dev->tx_pkt_burst = NULL; 14983e5a335dSHemant Agrawal 1499c147eae0SHemant Agrawal return 0; 1500c147eae0SHemant Agrawal } 1501c147eae0SHemant Agrawal 1502c147eae0SHemant Agrawal static int 1503c147eae0SHemant Agrawal rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused, 1504c147eae0SHemant Agrawal struct rte_dpaa2_device *dpaa2_dev) 1505c147eae0SHemant Agrawal { 1506c147eae0SHemant Agrawal struct rte_eth_dev *eth_dev; 1507c147eae0SHemant Agrawal char ethdev_name[RTE_ETH_NAME_MAX_LEN]; 1508c147eae0SHemant Agrawal 1509c147eae0SHemant Agrawal int diag; 1510c147eae0SHemant Agrawal 1511c147eae0SHemant Agrawal sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id); 1512c147eae0SHemant Agrawal 1513c147eae0SHemant Agrawal eth_dev = rte_eth_dev_allocate(ethdev_name); 1514c147eae0SHemant Agrawal if (eth_dev == NULL) 1515c147eae0SHemant Agrawal return -ENOMEM; 1516c147eae0SHemant Agrawal 1517c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1518c147eae0SHemant Agrawal eth_dev->data->dev_private = rte_zmalloc( 1519c147eae0SHemant Agrawal "ethdev private structure", 1520c147eae0SHemant Agrawal sizeof(struct dpaa2_dev_priv), 1521c147eae0SHemant Agrawal RTE_CACHE_LINE_SIZE); 1522c147eae0SHemant Agrawal if (eth_dev->data->dev_private == NULL) { 1523d401ead1SHemant Agrawal PMD_INIT_LOG(CRIT, "Cannot allocate memzone for" 1524c147eae0SHemant Agrawal " private port data\n"); 1525c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1526c147eae0SHemant Agrawal return -ENOMEM; 1527c147eae0SHemant Agrawal } 1528c147eae0SHemant Agrawal } 1529c147eae0SHemant Agrawal eth_dev->device = &dpaa2_dev->device; 1530c147eae0SHemant Agrawal dpaa2_dev->eth_dev = eth_dev; 1531c147eae0SHemant Agrawal eth_dev->data->rx_mbuf_alloc_failed = 0; 1532c147eae0SHemant Agrawal 1533c147eae0SHemant Agrawal /* Invoke PMD device initialization function */ 1534c147eae0SHemant Agrawal diag = dpaa2_dev_init(eth_dev); 1535c147eae0SHemant Agrawal if (diag == 0) 1536c147eae0SHemant Agrawal return 0; 1537c147eae0SHemant Agrawal 1538c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) 1539c147eae0SHemant Agrawal rte_free(eth_dev->data->dev_private); 1540c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1541c147eae0SHemant Agrawal return diag; 1542c147eae0SHemant Agrawal } 1543c147eae0SHemant Agrawal 1544c147eae0SHemant Agrawal static int 1545c147eae0SHemant Agrawal rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev) 1546c147eae0SHemant Agrawal { 1547c147eae0SHemant Agrawal struct rte_eth_dev *eth_dev; 1548c147eae0SHemant Agrawal 1549c147eae0SHemant Agrawal eth_dev = dpaa2_dev->eth_dev; 1550c147eae0SHemant Agrawal dpaa2_dev_uninit(eth_dev); 1551c147eae0SHemant Agrawal 1552c147eae0SHemant Agrawal if (rte_eal_process_type() == RTE_PROC_PRIMARY) 1553c147eae0SHemant Agrawal rte_free(eth_dev->data->dev_private); 1554c147eae0SHemant Agrawal rte_eth_dev_release_port(eth_dev); 1555c147eae0SHemant Agrawal 1556c147eae0SHemant Agrawal return 0; 1557c147eae0SHemant Agrawal } 1558c147eae0SHemant Agrawal 1559c147eae0SHemant Agrawal static struct rte_dpaa2_driver rte_dpaa2_pmd = { 1560c147eae0SHemant Agrawal .drv_type = DPAA2_MC_DPNI_DEVID, 1561c147eae0SHemant Agrawal .probe = rte_dpaa2_probe, 1562c147eae0SHemant Agrawal .remove = rte_dpaa2_remove, 1563c147eae0SHemant Agrawal }; 1564c147eae0SHemant Agrawal 1565c147eae0SHemant Agrawal RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd); 1566