1a41f593fSFerruh Yigit /* SPDX-License-Identifier: BSD-3-Clause 2a41f593fSFerruh Yigit * Copyright(c) 2022 Intel Corporation 3a41f593fSFerruh Yigit */ 4a41f593fSFerruh Yigit 59a9eb104SHarman Kalra #include <ctype.h> 608966fe7STyler Retzlaff #include <stdalign.h> 772b452c5SDmitry Kozlyuk #include <stdlib.h> 82744cb6eSThomas Monjalon #include <pthread.h> 972b452c5SDmitry Kozlyuk 104b4f810eSFerruh Yigit #include <rte_kvargs.h> 114b4f810eSFerruh Yigit #include <rte_malloc.h> 124b4f810eSFerruh Yigit 13a41f593fSFerruh Yigit #include "ethdev_driver.h" 144b4f810eSFerruh Yigit #include "ethdev_private.h" 15537bfddaSDariusz Sosnowski #include "rte_flow_driver.h" 164b4f810eSFerruh Yigit 174b4f810eSFerruh Yigit /** 184b4f810eSFerruh Yigit * A set of values to describe the possible states of a switch domain. 194b4f810eSFerruh Yigit */ 204b4f810eSFerruh Yigit enum rte_eth_switch_domain_state { 214b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_UNUSED = 0, 224b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED 234b4f810eSFerruh Yigit }; 244b4f810eSFerruh Yigit 254b4f810eSFerruh Yigit /** 264b4f810eSFerruh Yigit * Array of switch domains available for allocation. Array is sized to 274b4f810eSFerruh Yigit * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than 284b4f810eSFerruh Yigit * ethdev ports in a single process. 294b4f810eSFerruh Yigit */ 304b4f810eSFerruh Yigit static struct rte_eth_dev_switch { 314b4f810eSFerruh Yigit enum rte_eth_switch_domain_state state; 324b4f810eSFerruh Yigit } eth_dev_switch_domains[RTE_MAX_ETHPORTS]; 334b4f810eSFerruh Yigit 344b4f810eSFerruh Yigit static struct rte_eth_dev * 354b4f810eSFerruh Yigit eth_dev_allocated(const char *name) 364b4f810eSFerruh Yigit { 374b4f810eSFerruh Yigit uint16_t i; 384b4f810eSFerruh Yigit 394b4f810eSFerruh Yigit RTE_BUILD_BUG_ON(RTE_MAX_ETHPORTS >= UINT16_MAX); 404b4f810eSFerruh Yigit 414b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 424b4f810eSFerruh Yigit if (rte_eth_devices[i].data != NULL && 434b4f810eSFerruh Yigit strcmp(rte_eth_devices[i].data->name, name) == 0) 444b4f810eSFerruh Yigit return &rte_eth_devices[i]; 454b4f810eSFerruh Yigit } 464b4f810eSFerruh Yigit return NULL; 474b4f810eSFerruh Yigit } 484b4f810eSFerruh Yigit 494b4f810eSFerruh Yigit static uint16_t 504b4f810eSFerruh Yigit eth_dev_find_free_port(void) 515fa33785SDavid Marchand __rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock()) 524b4f810eSFerruh Yigit { 534b4f810eSFerruh Yigit uint16_t i; 544b4f810eSFerruh Yigit 554b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 564b4f810eSFerruh Yigit /* Using shared name field to find a free port. */ 574b4f810eSFerruh Yigit if (eth_dev_shared_data->data[i].name[0] == '\0') { 584b4f810eSFerruh Yigit RTE_ASSERT(rte_eth_devices[i].state == 594b4f810eSFerruh Yigit RTE_ETH_DEV_UNUSED); 604b4f810eSFerruh Yigit return i; 614b4f810eSFerruh Yigit } 624b4f810eSFerruh Yigit } 634b4f810eSFerruh Yigit return RTE_MAX_ETHPORTS; 644b4f810eSFerruh Yigit } 654b4f810eSFerruh Yigit 664b4f810eSFerruh Yigit static struct rte_eth_dev * 674b4f810eSFerruh Yigit eth_dev_get(uint16_t port_id) 685fa33785SDavid Marchand __rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock()) 694b4f810eSFerruh Yigit { 704b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id]; 714b4f810eSFerruh Yigit 724b4f810eSFerruh Yigit eth_dev->data = ð_dev_shared_data->data[port_id]; 734b4f810eSFerruh Yigit 744b4f810eSFerruh Yigit return eth_dev; 754b4f810eSFerruh Yigit } 764b4f810eSFerruh Yigit 774b4f810eSFerruh Yigit struct rte_eth_dev * 784b4f810eSFerruh Yigit rte_eth_dev_allocate(const char *name) 794b4f810eSFerruh Yigit { 804b4f810eSFerruh Yigit uint16_t port_id; 814b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = NULL; 824b4f810eSFerruh Yigit size_t name_len; 834b4f810eSFerruh Yigit 844b4f810eSFerruh Yigit name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN); 854b4f810eSFerruh Yigit if (name_len == 0) { 860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Zero length Ethernet device name"); 874b4f810eSFerruh Yigit return NULL; 884b4f810eSFerruh Yigit } 894b4f810eSFerruh Yigit 904b4f810eSFerruh Yigit if (name_len >= RTE_ETH_NAME_MAX_LEN) { 910e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethernet device name is too long"); 924b4f810eSFerruh Yigit return NULL; 934b4f810eSFerruh Yigit } 944b4f810eSFerruh Yigit 955fa33785SDavid Marchand /* Synchronize port creation between primary and secondary processes. */ 965fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 974b4f810eSFerruh Yigit 987fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() == NULL) 997fe371ebSDavid Marchand goto unlock; 1004b4f810eSFerruh Yigit 1014b4f810eSFerruh Yigit if (eth_dev_allocated(name) != NULL) { 1020e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 1030e21c7c0SDavid Marchand "Ethernet device with name %s already allocated", 1044b4f810eSFerruh Yigit name); 1054b4f810eSFerruh Yigit goto unlock; 1064b4f810eSFerruh Yigit } 1074b4f810eSFerruh Yigit 1084b4f810eSFerruh Yigit port_id = eth_dev_find_free_port(); 1094b4f810eSFerruh Yigit if (port_id == RTE_MAX_ETHPORTS) { 1100e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 1110e21c7c0SDavid Marchand "Reached maximum number of Ethernet ports"); 1124b4f810eSFerruh Yigit goto unlock; 1134b4f810eSFerruh Yigit } 1144b4f810eSFerruh Yigit 1154b4f810eSFerruh Yigit eth_dev = eth_dev_get(port_id); 116537bfddaSDariusz Sosnowski eth_dev->flow_fp_ops = &rte_flow_fp_default_ops; 1174b4f810eSFerruh Yigit strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name)); 1184b4f810eSFerruh Yigit eth_dev->data->port_id = port_id; 1194b4f810eSFerruh Yigit eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS; 1204b4f810eSFerruh Yigit eth_dev->data->mtu = RTE_ETHER_MTU; 1214b4f810eSFerruh Yigit pthread_mutex_init(ð_dev->data->flow_ops_mutex, NULL); 12236c46e73SDavid Marchand RTE_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); 12336c46e73SDavid Marchand eth_dev_shared_data->allocated_ports++; 1244b4f810eSFerruh Yigit 1254b4f810eSFerruh Yigit unlock: 1265fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 1274b4f810eSFerruh Yigit 1284b4f810eSFerruh Yigit return eth_dev; 1294b4f810eSFerruh Yigit } 1304b4f810eSFerruh Yigit 1314b4f810eSFerruh Yigit struct rte_eth_dev * 1324b4f810eSFerruh Yigit rte_eth_dev_allocated(const char *name) 1334b4f810eSFerruh Yigit { 1344b4f810eSFerruh Yigit struct rte_eth_dev *ethdev; 1354b4f810eSFerruh Yigit 1365fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 1374b4f810eSFerruh Yigit 1387fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() != NULL) 1394b4f810eSFerruh Yigit ethdev = eth_dev_allocated(name); 1407fe371ebSDavid Marchand else 1417fe371ebSDavid Marchand ethdev = NULL; 1424b4f810eSFerruh Yigit 1435fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 1444b4f810eSFerruh Yigit 1454b4f810eSFerruh Yigit return ethdev; 1464b4f810eSFerruh Yigit } 1474b4f810eSFerruh Yigit 1484b4f810eSFerruh Yigit /* 1494b4f810eSFerruh Yigit * Attach to a port already registered by the primary process, which 1504b4f810eSFerruh Yigit * makes sure that the same device would have the same port ID both 1514b4f810eSFerruh Yigit * in the primary and secondary process. 1524b4f810eSFerruh Yigit */ 1534b4f810eSFerruh Yigit struct rte_eth_dev * 1544b4f810eSFerruh Yigit rte_eth_dev_attach_secondary(const char *name) 1554b4f810eSFerruh Yigit { 1564b4f810eSFerruh Yigit uint16_t i; 1574b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = NULL; 1584b4f810eSFerruh Yigit 1594b4f810eSFerruh Yigit /* Synchronize port attachment to primary port creation and release. */ 1605fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 1615fa33785SDavid Marchand 1627fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() == NULL) 1637fe371ebSDavid Marchand goto unlock; 1644b4f810eSFerruh Yigit 1654b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 1664b4f810eSFerruh Yigit if (strcmp(eth_dev_shared_data->data[i].name, name) == 0) 1674b4f810eSFerruh Yigit break; 1684b4f810eSFerruh Yigit } 1694b4f810eSFerruh Yigit if (i == RTE_MAX_ETHPORTS) { 1700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 1710e21c7c0SDavid Marchand "Device %s is not driven by the primary process", 1724b4f810eSFerruh Yigit name); 1734b4f810eSFerruh Yigit } else { 1744b4f810eSFerruh Yigit eth_dev = eth_dev_get(i); 1754b4f810eSFerruh Yigit RTE_ASSERT(eth_dev->data->port_id == i); 1764b4f810eSFerruh Yigit } 1774b4f810eSFerruh Yigit 1787fe371ebSDavid Marchand unlock: 1795fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 1804b4f810eSFerruh Yigit return eth_dev; 1814b4f810eSFerruh Yigit } 1824b4f810eSFerruh Yigit 1834b4f810eSFerruh Yigit int 1844b4f810eSFerruh Yigit rte_eth_dev_callback_process(struct rte_eth_dev *dev, 1854b4f810eSFerruh Yigit enum rte_eth_event_type event, void *ret_param) 1864b4f810eSFerruh Yigit { 1874b4f810eSFerruh Yigit struct rte_eth_dev_callback *cb_lst; 1884b4f810eSFerruh Yigit struct rte_eth_dev_callback dev_cb; 1894b4f810eSFerruh Yigit int rc = 0; 1904b4f810eSFerruh Yigit 1914b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_cb_lock); 1924b4f810eSFerruh Yigit TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) { 1934b4f810eSFerruh Yigit if (cb_lst->cb_fn == NULL || cb_lst->event != event) 1944b4f810eSFerruh Yigit continue; 1954b4f810eSFerruh Yigit dev_cb = *cb_lst; 1964b4f810eSFerruh Yigit cb_lst->active = 1; 1974b4f810eSFerruh Yigit if (ret_param != NULL) 1984b4f810eSFerruh Yigit dev_cb.ret_param = ret_param; 1994b4f810eSFerruh Yigit 2004b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_cb_lock); 2014b4f810eSFerruh Yigit rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event, 2024b4f810eSFerruh Yigit dev_cb.cb_arg, dev_cb.ret_param); 2034b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_cb_lock); 2044b4f810eSFerruh Yigit cb_lst->active = 0; 2054b4f810eSFerruh Yigit } 2064b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_cb_lock); 2074b4f810eSFerruh Yigit return rc; 2084b4f810eSFerruh Yigit } 2094b4f810eSFerruh Yigit 2104b4f810eSFerruh Yigit void 2114b4f810eSFerruh Yigit rte_eth_dev_probing_finish(struct rte_eth_dev *dev) 2124b4f810eSFerruh Yigit { 2134b4f810eSFerruh Yigit if (dev == NULL) 2144b4f810eSFerruh Yigit return; 2154b4f810eSFerruh Yigit 2164b4f810eSFerruh Yigit /* 2174b4f810eSFerruh Yigit * for secondary process, at that point we expect device 2184b4f810eSFerruh Yigit * to be already 'usable', so shared data and all function pointers 2194b4f810eSFerruh Yigit * for fast-path devops have to be setup properly inside rte_eth_dev. 2204b4f810eSFerruh Yigit */ 2214b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_SECONDARY) 2224b4f810eSFerruh Yigit eth_dev_fp_ops_setup(rte_eth_fp_ops + dev->data->port_id, dev); 2234b4f810eSFerruh Yigit 2244b4f810eSFerruh Yigit rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL); 2254b4f810eSFerruh Yigit 2264b4f810eSFerruh Yigit dev->state = RTE_ETH_DEV_ATTACHED; 2274b4f810eSFerruh Yigit } 2284b4f810eSFerruh Yigit 2294b4f810eSFerruh Yigit int 2304b4f810eSFerruh Yigit rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) 2314b4f810eSFerruh Yigit { 2327fe371ebSDavid Marchand int ret; 2337fe371ebSDavid Marchand 2344b4f810eSFerruh Yigit if (eth_dev == NULL) 2354b4f810eSFerruh Yigit return -EINVAL; 2364b4f810eSFerruh Yigit 2375fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 2387fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() == NULL) 2397fe371ebSDavid Marchand ret = -EINVAL; 2407fe371ebSDavid Marchand else 2417fe371ebSDavid Marchand ret = 0; 2425fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 2437fe371ebSDavid Marchand if (ret != 0) 2447fe371ebSDavid Marchand return ret; 2454b4f810eSFerruh Yigit 2464b4f810eSFerruh Yigit if (eth_dev->state != RTE_ETH_DEV_UNUSED) 2474b4f810eSFerruh Yigit rte_eth_dev_callback_process(eth_dev, 2484b4f810eSFerruh Yigit RTE_ETH_EVENT_DESTROY, NULL); 2494b4f810eSFerruh Yigit 2504b4f810eSFerruh Yigit eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id); 2514b4f810eSFerruh Yigit 252537bfddaSDariusz Sosnowski eth_dev->flow_fp_ops = &rte_flow_fp_default_ops; 253537bfddaSDariusz Sosnowski 2545fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 2554b4f810eSFerruh Yigit 2564b4f810eSFerruh Yigit eth_dev->state = RTE_ETH_DEV_UNUSED; 2574b4f810eSFerruh Yigit eth_dev->device = NULL; 2584b4f810eSFerruh Yigit eth_dev->process_private = NULL; 2594b4f810eSFerruh Yigit eth_dev->intr_handle = NULL; 2604b4f810eSFerruh Yigit eth_dev->rx_pkt_burst = NULL; 2614b4f810eSFerruh Yigit eth_dev->tx_pkt_burst = NULL; 2624b4f810eSFerruh Yigit eth_dev->tx_pkt_prepare = NULL; 2634b4f810eSFerruh Yigit eth_dev->rx_queue_count = NULL; 2644b4f810eSFerruh Yigit eth_dev->rx_descriptor_status = NULL; 2654b4f810eSFerruh Yigit eth_dev->tx_descriptor_status = NULL; 2664b4f810eSFerruh Yigit eth_dev->dev_ops = NULL; 2674b4f810eSFerruh Yigit 2684b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 2694b4f810eSFerruh Yigit rte_free(eth_dev->data->rx_queues); 2704b4f810eSFerruh Yigit rte_free(eth_dev->data->tx_queues); 2714b4f810eSFerruh Yigit rte_free(eth_dev->data->mac_addrs); 2724b4f810eSFerruh Yigit rte_free(eth_dev->data->hash_mac_addrs); 2734b4f810eSFerruh Yigit rte_free(eth_dev->data->dev_private); 2744b4f810eSFerruh Yigit pthread_mutex_destroy(ð_dev->data->flow_ops_mutex); 2754b4f810eSFerruh Yigit memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); 27636c46e73SDavid Marchand eth_dev->data = NULL; 27736c46e73SDavid Marchand 27836c46e73SDavid Marchand eth_dev_shared_data->allocated_ports--; 27936c46e73SDavid Marchand eth_dev_shared_data_release(); 2804b4f810eSFerruh Yigit } 2814b4f810eSFerruh Yigit 2825fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 2834b4f810eSFerruh Yigit 2844b4f810eSFerruh Yigit return 0; 2854b4f810eSFerruh Yigit } 2864b4f810eSFerruh Yigit 2874b4f810eSFerruh Yigit int 2884b4f810eSFerruh Yigit rte_eth_dev_create(struct rte_device *device, const char *name, 2894b4f810eSFerruh Yigit size_t priv_data_size, 2904b4f810eSFerruh Yigit ethdev_bus_specific_init ethdev_bus_specific_init, 2914b4f810eSFerruh Yigit void *bus_init_params, 2924b4f810eSFerruh Yigit ethdev_init_t ethdev_init, void *init_params) 2934b4f810eSFerruh Yigit { 2944b4f810eSFerruh Yigit struct rte_eth_dev *ethdev; 2954b4f810eSFerruh Yigit int retval; 2964b4f810eSFerruh Yigit 2978f1d23ecSDavid Marchand if (*ethdev_init == NULL) 2988f1d23ecSDavid Marchand return -EINVAL; 2994b4f810eSFerruh Yigit 3004b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 3014b4f810eSFerruh Yigit ethdev = rte_eth_dev_allocate(name); 3024b4f810eSFerruh Yigit if (!ethdev) 3034b4f810eSFerruh Yigit return -ENODEV; 3044b4f810eSFerruh Yigit 3054b4f810eSFerruh Yigit if (priv_data_size) { 306ed34d87dSBruce Richardson /* try alloc private data on device-local node. */ 3074b4f810eSFerruh Yigit ethdev->data->dev_private = rte_zmalloc_socket( 3084b4f810eSFerruh Yigit name, priv_data_size, RTE_CACHE_LINE_SIZE, 3094b4f810eSFerruh Yigit device->numa_node); 3104b4f810eSFerruh Yigit 311ed34d87dSBruce Richardson /* fall back to alloc on any socket on failure */ 312ed34d87dSBruce Richardson if (ethdev->data->dev_private == NULL) { 313ed34d87dSBruce Richardson ethdev->data->dev_private = rte_zmalloc(name, 314ed34d87dSBruce Richardson priv_data_size, RTE_CACHE_LINE_SIZE); 315ed34d87dSBruce Richardson 316ed34d87dSBruce Richardson if (ethdev->data->dev_private == NULL) { 317ed34d87dSBruce Richardson RTE_ETHDEV_LOG_LINE(ERR, "failed to allocate private data"); 3184b4f810eSFerruh Yigit retval = -ENOMEM; 3194b4f810eSFerruh Yigit goto probe_failed; 3204b4f810eSFerruh Yigit } 321ed34d87dSBruce Richardson /* got memory, but not local, so issue warning */ 322ed34d87dSBruce Richardson RTE_ETHDEV_LOG_LINE(WARNING, 323ed34d87dSBruce Richardson "Private data for ethdev '%s' not allocated on local NUMA node %d", 324ed34d87dSBruce Richardson device->name, device->numa_node); 325ed34d87dSBruce Richardson } 3264b4f810eSFerruh Yigit } 3274b4f810eSFerruh Yigit } else { 3284b4f810eSFerruh Yigit ethdev = rte_eth_dev_attach_secondary(name); 3294b4f810eSFerruh Yigit if (!ethdev) { 3300e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 3310e21c7c0SDavid Marchand "secondary process attach failed, ethdev doesn't exist"); 3324b4f810eSFerruh Yigit return -ENODEV; 3334b4f810eSFerruh Yigit } 3344b4f810eSFerruh Yigit } 3354b4f810eSFerruh Yigit 3364b4f810eSFerruh Yigit ethdev->device = device; 3374b4f810eSFerruh Yigit 3384b4f810eSFerruh Yigit if (ethdev_bus_specific_init) { 3394b4f810eSFerruh Yigit retval = ethdev_bus_specific_init(ethdev, bus_init_params); 3404b4f810eSFerruh Yigit if (retval) { 3410e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 3420e21c7c0SDavid Marchand "ethdev bus specific initialisation failed"); 3434b4f810eSFerruh Yigit goto probe_failed; 3444b4f810eSFerruh Yigit } 3454b4f810eSFerruh Yigit } 3464b4f810eSFerruh Yigit 3474b4f810eSFerruh Yigit retval = ethdev_init(ethdev, init_params); 3484b4f810eSFerruh Yigit if (retval) { 3490e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "ethdev initialisation failed"); 3504b4f810eSFerruh Yigit goto probe_failed; 3514b4f810eSFerruh Yigit } 3524b4f810eSFerruh Yigit 3534b4f810eSFerruh Yigit rte_eth_dev_probing_finish(ethdev); 3544b4f810eSFerruh Yigit 3554b4f810eSFerruh Yigit return retval; 3564b4f810eSFerruh Yigit 3574b4f810eSFerruh Yigit probe_failed: 3584b4f810eSFerruh Yigit rte_eth_dev_release_port(ethdev); 3594b4f810eSFerruh Yigit return retval; 3604b4f810eSFerruh Yigit } 3614b4f810eSFerruh Yigit 3624b4f810eSFerruh Yigit int 3634b4f810eSFerruh Yigit rte_eth_dev_destroy(struct rte_eth_dev *ethdev, 3644b4f810eSFerruh Yigit ethdev_uninit_t ethdev_uninit) 3654b4f810eSFerruh Yigit { 3664b4f810eSFerruh Yigit int ret; 3674b4f810eSFerruh Yigit 3684b4f810eSFerruh Yigit ethdev = rte_eth_dev_allocated(ethdev->data->name); 3694b4f810eSFerruh Yigit if (!ethdev) 3704b4f810eSFerruh Yigit return -ENODEV; 3714b4f810eSFerruh Yigit 3728f1d23ecSDavid Marchand if (*ethdev_uninit == NULL) 3738f1d23ecSDavid Marchand return -EINVAL; 3744b4f810eSFerruh Yigit 3754b4f810eSFerruh Yigit ret = ethdev_uninit(ethdev); 3764b4f810eSFerruh Yigit if (ret) 3774b4f810eSFerruh Yigit return ret; 3784b4f810eSFerruh Yigit 3794b4f810eSFerruh Yigit return rte_eth_dev_release_port(ethdev); 3804b4f810eSFerruh Yigit } 3814b4f810eSFerruh Yigit 3824b4f810eSFerruh Yigit struct rte_eth_dev * 3834b4f810eSFerruh Yigit rte_eth_dev_get_by_name(const char *name) 3844b4f810eSFerruh Yigit { 3854b4f810eSFerruh Yigit uint16_t pid; 3864b4f810eSFerruh Yigit 3874b4f810eSFerruh Yigit if (rte_eth_dev_get_port_by_name(name, &pid)) 3884b4f810eSFerruh Yigit return NULL; 3894b4f810eSFerruh Yigit 3904b4f810eSFerruh Yigit return &rte_eth_devices[pid]; 3914b4f810eSFerruh Yigit } 3924b4f810eSFerruh Yigit 3934b4f810eSFerruh Yigit int 3944b4f810eSFerruh Yigit rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 3954b4f810eSFerruh Yigit { 3964b4f810eSFerruh Yigit if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 3974b4f810eSFerruh Yigit return 1; 3984b4f810eSFerruh Yigit return 0; 3994b4f810eSFerruh Yigit } 4004b4f810eSFerruh Yigit 4014b4f810eSFerruh Yigit int 4024b4f810eSFerruh Yigit rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 4034b4f810eSFerruh Yigit { 4044b4f810eSFerruh Yigit if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 4054b4f810eSFerruh Yigit return 1; 4064b4f810eSFerruh Yigit return 0; 4074b4f810eSFerruh Yigit } 4084b4f810eSFerruh Yigit 4094b4f810eSFerruh Yigit void 4104b4f810eSFerruh Yigit rte_eth_dev_internal_reset(struct rte_eth_dev *dev) 4114b4f810eSFerruh Yigit { 4124b4f810eSFerruh Yigit if (dev->data->dev_started) { 4130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u must be stopped to allow reset", 4144b4f810eSFerruh Yigit dev->data->port_id); 4154b4f810eSFerruh Yigit return; 4164b4f810eSFerruh Yigit } 4174b4f810eSFerruh Yigit 4184b4f810eSFerruh Yigit eth_dev_rx_queue_config(dev, 0); 4194b4f810eSFerruh Yigit eth_dev_tx_queue_config(dev, 0); 4204b4f810eSFerruh Yigit 4214b4f810eSFerruh Yigit memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf)); 4224b4f810eSFerruh Yigit } 4234b4f810eSFerruh Yigit 4244b4f810eSFerruh Yigit static int 4254b4f810eSFerruh Yigit eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) 4264b4f810eSFerruh Yigit { 4274b4f810eSFerruh Yigit int state; 4284b4f810eSFerruh Yigit struct rte_kvargs_pair *pair; 4294b4f810eSFerruh Yigit char *letter; 4304b4f810eSFerruh Yigit 4314b4f810eSFerruh Yigit arglist->str = strdup(str_in); 4324b4f810eSFerruh Yigit if (arglist->str == NULL) 4334b4f810eSFerruh Yigit return -ENOMEM; 4344b4f810eSFerruh Yigit 4354b4f810eSFerruh Yigit letter = arglist->str; 4364b4f810eSFerruh Yigit state = 0; 4374b4f810eSFerruh Yigit arglist->count = 0; 4384b4f810eSFerruh Yigit pair = &arglist->pairs[0]; 4394b4f810eSFerruh Yigit while (1) { 4404b4f810eSFerruh Yigit switch (state) { 4414b4f810eSFerruh Yigit case 0: /* Initial */ 4424b4f810eSFerruh Yigit if (*letter == '=') 4434b4f810eSFerruh Yigit return -EINVAL; 4444b4f810eSFerruh Yigit else if (*letter == '\0') 4454b4f810eSFerruh Yigit return 0; 4464b4f810eSFerruh Yigit 4474b4f810eSFerruh Yigit state = 1; 4484b4f810eSFerruh Yigit pair->key = letter; 4494b4f810eSFerruh Yigit /* fallthrough */ 4504b4f810eSFerruh Yigit 4514b4f810eSFerruh Yigit case 1: /* Parsing key */ 4524b4f810eSFerruh Yigit if (*letter == '=') { 4534b4f810eSFerruh Yigit *letter = '\0'; 4544b4f810eSFerruh Yigit pair->value = letter + 1; 4554b4f810eSFerruh Yigit state = 2; 4564b4f810eSFerruh Yigit } else if (*letter == ',' || *letter == '\0') 4574b4f810eSFerruh Yigit return -EINVAL; 4584b4f810eSFerruh Yigit break; 4594b4f810eSFerruh Yigit 4604b4f810eSFerruh Yigit 4614b4f810eSFerruh Yigit case 2: /* Parsing value */ 4624b4f810eSFerruh Yigit if (*letter == '[') 4634b4f810eSFerruh Yigit state = 3; 4644b4f810eSFerruh Yigit else if (*letter == ',') { 4654b4f810eSFerruh Yigit *letter = '\0'; 4664b4f810eSFerruh Yigit arglist->count++; 4674b4f810eSFerruh Yigit pair = &arglist->pairs[arglist->count]; 4684b4f810eSFerruh Yigit state = 0; 4694b4f810eSFerruh Yigit } else if (*letter == '\0') { 4704b4f810eSFerruh Yigit letter--; 4714b4f810eSFerruh Yigit arglist->count++; 4724b4f810eSFerruh Yigit pair = &arglist->pairs[arglist->count]; 4734b4f810eSFerruh Yigit state = 0; 4744b4f810eSFerruh Yigit } 4754b4f810eSFerruh Yigit break; 4764b4f810eSFerruh Yigit 4774b4f810eSFerruh Yigit case 3: /* Parsing list */ 4789a9eb104SHarman Kalra if (*letter == ']') { 4799a9eb104SHarman Kalra /* For devargs having singles lists move to state 2 once letter 4809a9eb104SHarman Kalra * becomes ']' so each can be considered as different pair key 4819a9eb104SHarman Kalra * value. But in nested lists case e.g. multiple representors 4829a9eb104SHarman Kalra * case i.e. [pf[0-3],pfvf[3,4-6]], complete nested list should 4839a9eb104SHarman Kalra * be considered as one pair value, hence checking if end of outer 4849a9eb104SHarman Kalra * list ']' is reached else stay on state 3. 4859a9eb104SHarman Kalra */ 4869a9eb104SHarman Kalra if ((strcmp("representor", pair->key) == 0) && 4879a9eb104SHarman Kalra (*(letter + 1) != '\0' && *(letter + 2) != '\0' && 4889a9eb104SHarman Kalra *(letter + 3) != '\0') && 4899a9eb104SHarman Kalra ((*(letter + 2) == 'p' && *(letter + 3) == 'f') || 4909a9eb104SHarman Kalra (*(letter + 2) == 'v' && *(letter + 3) == 'f') || 4919a9eb104SHarman Kalra (*(letter + 2) == 's' && *(letter + 3) == 'f') || 4929a9eb104SHarman Kalra (*(letter + 2) == 'c' && isdigit(*(letter + 3))) || 4939a9eb104SHarman Kalra (*(letter + 2) == '[' && isdigit(*(letter + 3))) || 4949a9eb104SHarman Kalra (isdigit(*(letter + 2))))) 4959a9eb104SHarman Kalra state = 3; 4969a9eb104SHarman Kalra else 4974b4f810eSFerruh Yigit state = 2; 4989a9eb104SHarman Kalra } else if (*letter == '\0') { 4994b4f810eSFerruh Yigit return -EINVAL; 5009a9eb104SHarman Kalra } 5014b4f810eSFerruh Yigit break; 5024b4f810eSFerruh Yigit } 5034b4f810eSFerruh Yigit letter++; 5044b4f810eSFerruh Yigit } 5054b4f810eSFerruh Yigit } 5064b4f810eSFerruh Yigit 5079a9eb104SHarman Kalra static int 5089a9eb104SHarman Kalra devargs_parse_representor_ports(struct rte_eth_devargs *eth_devargs, char 5099a9eb104SHarman Kalra *da_val, unsigned int da_idx, unsigned int nb_da) 5104b4f810eSFerruh Yigit { 5119a9eb104SHarman Kalra struct rte_eth_devargs *eth_da; 5124b4f810eSFerruh Yigit int result = 0; 5134b4f810eSFerruh Yigit 5149a9eb104SHarman Kalra if (da_idx + 1 > nb_da) { 5159a9eb104SHarman Kalra RTE_ETHDEV_LOG_LINE(ERR, "Devargs parsed %d > max array size %d", 5169a9eb104SHarman Kalra da_idx + 1, nb_da); 5179a9eb104SHarman Kalra result = -1; 5189a9eb104SHarman Kalra goto parse_cleanup; 5199a9eb104SHarman Kalra } 5209a9eb104SHarman Kalra eth_da = ð_devargs[da_idx]; 5214b4f810eSFerruh Yigit memset(eth_da, 0, sizeof(*eth_da)); 5229a9eb104SHarman Kalra RTE_ETHDEV_LOG_LINE(DEBUG, " Devargs idx %d value %s", da_idx, da_val); 5239a9eb104SHarman Kalra result = rte_eth_devargs_parse_representor_ports(da_val, eth_da); 5249a9eb104SHarman Kalra 5259a9eb104SHarman Kalra parse_cleanup: 5269a9eb104SHarman Kalra return result; 5279a9eb104SHarman Kalra } 5289a9eb104SHarman Kalra 5299a9eb104SHarman Kalra static int 5309a9eb104SHarman Kalra eth_dev_tokenise_representor_list(char *p_val, struct rte_eth_devargs *eth_devargs, 5319a9eb104SHarman Kalra unsigned int nb_da) 5329a9eb104SHarman Kalra { 5339a9eb104SHarman Kalra char da_val[BUFSIZ], str[BUFSIZ]; 5349a9eb104SHarman Kalra bool is_rep_portid_list = true; 5359a9eb104SHarman Kalra unsigned int devargs = 0; 5369a9eb104SHarman Kalra int result = 0, len = 0; 5379a9eb104SHarman Kalra int i = 0, j = 0; 5389a9eb104SHarman Kalra char *pos; 5399a9eb104SHarman Kalra 5409a9eb104SHarman Kalra pos = p_val; 5419a9eb104SHarman Kalra /* Length of consolidated list */ 5429a9eb104SHarman Kalra while (*pos++ != '\0') { 5439a9eb104SHarman Kalra len++; 5449a9eb104SHarman Kalra if (isalpha(*pos)) 5459a9eb104SHarman Kalra is_rep_portid_list = false; 5469a9eb104SHarman Kalra } 5479a9eb104SHarman Kalra 5489a9eb104SHarman Kalra /* List of representor portIDs i.e.[1,2,3] should be considered as single representor case*/ 5499a9eb104SHarman Kalra if (is_rep_portid_list) { 5509a9eb104SHarman Kalra result = devargs_parse_representor_ports(eth_devargs, p_val, 0, 1); 5519a9eb104SHarman Kalra if (result < 0) 5529a9eb104SHarman Kalra return result; 5539a9eb104SHarman Kalra 5549a9eb104SHarman Kalra devargs++; 5559a9eb104SHarman Kalra return devargs; 5569a9eb104SHarman Kalra } 5579a9eb104SHarman Kalra 5589a9eb104SHarman Kalra memset(str, 0, BUFSIZ); 5599c0c704aSHarman Kalra memset(da_val, 0, BUFSIZ); 5609a9eb104SHarman Kalra /* Remove the exterior [] of the consolidated list */ 5619a9eb104SHarman Kalra strncpy(str, &p_val[1], len - 2); 5629a9eb104SHarman Kalra while (1) { 5639a9eb104SHarman Kalra if (str[i] == '\0') { 5649a9eb104SHarman Kalra if (da_val[0] != '\0') { 5659a9eb104SHarman Kalra result = devargs_parse_representor_ports(eth_devargs, da_val, 5669a9eb104SHarman Kalra devargs, nb_da); 5679a9eb104SHarman Kalra if (result < 0) 5689a9eb104SHarman Kalra goto parse_cleanup; 5699a9eb104SHarman Kalra 5709a9eb104SHarman Kalra devargs++; 5719a9eb104SHarman Kalra } 5729a9eb104SHarman Kalra break; 5739a9eb104SHarman Kalra } 5749a9eb104SHarman Kalra if (str[i] == ',' || str[i] == '[') { 5759a9eb104SHarman Kalra if (str[i] == ',') { 5769a9eb104SHarman Kalra if (da_val[0] != '\0') { 5779a9eb104SHarman Kalra da_val[j + 1] = '\0'; 5789a9eb104SHarman Kalra result = devargs_parse_representor_ports(eth_devargs, 5799a9eb104SHarman Kalra da_val, devargs, 5809a9eb104SHarman Kalra nb_da); 5819a9eb104SHarman Kalra if (result < 0) 5829a9eb104SHarman Kalra goto parse_cleanup; 5839a9eb104SHarman Kalra 5849a9eb104SHarman Kalra devargs++; 5859a9eb104SHarman Kalra j = 0; 5869a9eb104SHarman Kalra memset(da_val, 0, BUFSIZ); 5879a9eb104SHarman Kalra } 5889a9eb104SHarman Kalra } 5899a9eb104SHarman Kalra 5909a9eb104SHarman Kalra if (str[i] == '[') { 5919a9eb104SHarman Kalra while (str[i] != ']' || isalpha(str[i + 1])) { 5929a9eb104SHarman Kalra da_val[j] = str[i]; 5939a9eb104SHarman Kalra j++; 5949a9eb104SHarman Kalra i++; 5959a9eb104SHarman Kalra } 5969a9eb104SHarman Kalra da_val[j] = ']'; 5979a9eb104SHarman Kalra da_val[j + 1] = '\0'; 5989a9eb104SHarman Kalra result = devargs_parse_representor_ports(eth_devargs, da_val, 5999a9eb104SHarman Kalra devargs, nb_da); 6009a9eb104SHarman Kalra if (result < 0) 6019a9eb104SHarman Kalra goto parse_cleanup; 6029a9eb104SHarman Kalra 6039a9eb104SHarman Kalra devargs++; 6049a9eb104SHarman Kalra j = 0; 6059a9eb104SHarman Kalra memset(da_val, 0, BUFSIZ); 6069a9eb104SHarman Kalra } 6079a9eb104SHarman Kalra } else { 6089a9eb104SHarman Kalra da_val[j] = str[i]; 6099a9eb104SHarman Kalra j++; 6109a9eb104SHarman Kalra } 6119a9eb104SHarman Kalra i++; 6129a9eb104SHarman Kalra } 6139a9eb104SHarman Kalra result = devargs; 6149a9eb104SHarman Kalra 6159a9eb104SHarman Kalra parse_cleanup: 6169a9eb104SHarman Kalra return result; 6179a9eb104SHarman Kalra } 6189a9eb104SHarman Kalra 6199a9eb104SHarman Kalra int 6209a9eb104SHarman Kalra rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs, 6219a9eb104SHarman Kalra unsigned int nb_da) 6229a9eb104SHarman Kalra { 6239a9eb104SHarman Kalra struct rte_kvargs_pair *pair; 6249a9eb104SHarman Kalra struct rte_kvargs args; 6259a9eb104SHarman Kalra bool dup_rep = false; 6269a9eb104SHarman Kalra int devargs = 0; 6279a9eb104SHarman Kalra unsigned int i; 6289a9eb104SHarman Kalra int result = 0; 6294b4f810eSFerruh Yigit 630aa2f2d33SThierry Herbelot memset(eth_devargs, 0, nb_da * sizeof(*eth_devargs)); 631aa2f2d33SThierry Herbelot 6324b4f810eSFerruh Yigit result = eth_dev_devargs_tokenise(&args, dargs); 6334b4f810eSFerruh Yigit if (result < 0) 6344b4f810eSFerruh Yigit goto parse_cleanup; 6354b4f810eSFerruh Yigit 6364b4f810eSFerruh Yigit for (i = 0; i < args.count; i++) { 6374b4f810eSFerruh Yigit pair = &args.pairs[i]; 6384b4f810eSFerruh Yigit if (strcmp("representor", pair->key) == 0) { 6399a9eb104SHarman Kalra if (dup_rep) { 6409a9eb104SHarman Kalra RTE_ETHDEV_LOG_LINE(ERR, "Duplicated representor key: %s", 6419a9eb104SHarman Kalra pair->value); 6424b4f810eSFerruh Yigit result = -1; 6434b4f810eSFerruh Yigit goto parse_cleanup; 6444b4f810eSFerruh Yigit } 6459a9eb104SHarman Kalra 6469a9eb104SHarman Kalra RTE_ETHDEV_LOG_LINE(DEBUG, "Devarg pattern: %s", pair->value); 6479a9eb104SHarman Kalra if (pair->value[0] == '[') { 6489a9eb104SHarman Kalra /* Multiple representor list case */ 6499a9eb104SHarman Kalra devargs = eth_dev_tokenise_representor_list(pair->value, 6509a9eb104SHarman Kalra eth_devargs, nb_da); 6519a9eb104SHarman Kalra if (devargs < 0) 6524b4f810eSFerruh Yigit goto parse_cleanup; 6539a9eb104SHarman Kalra } else { 6549a9eb104SHarman Kalra /* Single representor case */ 6559a9eb104SHarman Kalra devargs = devargs_parse_representor_ports(eth_devargs, pair->value, 6569a9eb104SHarman Kalra 0, 1); 6579a9eb104SHarman Kalra if (devargs < 0) 6589a9eb104SHarman Kalra goto parse_cleanup; 6599a9eb104SHarman Kalra devargs++; 6609a9eb104SHarman Kalra } 6619a9eb104SHarman Kalra dup_rep = true; 6624b4f810eSFerruh Yigit } 6634b4f810eSFerruh Yigit } 6649a9eb104SHarman Kalra RTE_ETHDEV_LOG_LINE(DEBUG, "Total devargs parsed %d", devargs); 6659a9eb104SHarman Kalra result = devargs; 6664b4f810eSFerruh Yigit 6674b4f810eSFerruh Yigit parse_cleanup: 6684b4f810eSFerruh Yigit free(args.str); 6694b4f810eSFerruh Yigit 6704b4f810eSFerruh Yigit return result; 6714b4f810eSFerruh Yigit } 6724b4f810eSFerruh Yigit 6734b4f810eSFerruh Yigit static inline int 6744b4f810eSFerruh Yigit eth_dev_dma_mzone_name(char *name, size_t len, uint16_t port_id, uint16_t queue_id, 6754b4f810eSFerruh Yigit const char *ring_name) 6764b4f810eSFerruh Yigit { 6774b4f810eSFerruh Yigit return snprintf(name, len, "eth_p%d_q%d_%s", 6784b4f810eSFerruh Yigit port_id, queue_id, ring_name); 6794b4f810eSFerruh Yigit } 6804b4f810eSFerruh Yigit 6814b4f810eSFerruh Yigit int 6824b4f810eSFerruh Yigit rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name, 6834b4f810eSFerruh Yigit uint16_t queue_id) 6844b4f810eSFerruh Yigit { 6854b4f810eSFerruh Yigit char z_name[RTE_MEMZONE_NAMESIZE]; 6864b4f810eSFerruh Yigit const struct rte_memzone *mz; 6874b4f810eSFerruh Yigit int rc = 0; 6884b4f810eSFerruh Yigit 6894b4f810eSFerruh Yigit rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 6904b4f810eSFerruh Yigit queue_id, ring_name); 6914b4f810eSFerruh Yigit if (rc >= RTE_MEMZONE_NAMESIZE) { 6920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "ring name too long"); 6934b4f810eSFerruh Yigit return -ENAMETOOLONG; 6944b4f810eSFerruh Yigit } 6954b4f810eSFerruh Yigit 6964b4f810eSFerruh Yigit mz = rte_memzone_lookup(z_name); 6974b4f810eSFerruh Yigit if (mz) 6984b4f810eSFerruh Yigit rc = rte_memzone_free(mz); 6994b4f810eSFerruh Yigit else 7004b4f810eSFerruh Yigit rc = -ENOENT; 7014b4f810eSFerruh Yigit 7024b4f810eSFerruh Yigit return rc; 7034b4f810eSFerruh Yigit } 7044b4f810eSFerruh Yigit 7054b4f810eSFerruh Yigit const struct rte_memzone * 7064b4f810eSFerruh Yigit rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, 7074b4f810eSFerruh Yigit uint16_t queue_id, size_t size, unsigned int align, 7084b4f810eSFerruh Yigit int socket_id) 7094b4f810eSFerruh Yigit { 7104b4f810eSFerruh Yigit char z_name[RTE_MEMZONE_NAMESIZE]; 7114b4f810eSFerruh Yigit const struct rte_memzone *mz; 7124b4f810eSFerruh Yigit int rc; 7134b4f810eSFerruh Yigit 7144b4f810eSFerruh Yigit rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 7154b4f810eSFerruh Yigit queue_id, ring_name); 7164b4f810eSFerruh Yigit if (rc >= RTE_MEMZONE_NAMESIZE) { 7170e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "ring name too long"); 7184b4f810eSFerruh Yigit rte_errno = ENAMETOOLONG; 7194b4f810eSFerruh Yigit return NULL; 7204b4f810eSFerruh Yigit } 7214b4f810eSFerruh Yigit 7224b4f810eSFerruh Yigit mz = rte_memzone_lookup(z_name); 7234b4f810eSFerruh Yigit if (mz) { 7244b4f810eSFerruh Yigit if ((socket_id != SOCKET_ID_ANY && socket_id != mz->socket_id) || 7254b4f810eSFerruh Yigit size > mz->len || 7264b4f810eSFerruh Yigit ((uintptr_t)mz->addr & (align - 1)) != 0) { 7270e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7280e21c7c0SDavid Marchand "memzone %s does not justify the requested attributes", 7294b4f810eSFerruh Yigit mz->name); 7304b4f810eSFerruh Yigit return NULL; 7314b4f810eSFerruh Yigit } 7324b4f810eSFerruh Yigit 7334b4f810eSFerruh Yigit return mz; 7344b4f810eSFerruh Yigit } 7354b4f810eSFerruh Yigit 7364b4f810eSFerruh Yigit return rte_memzone_reserve_aligned(z_name, size, socket_id, 7374b4f810eSFerruh Yigit RTE_MEMZONE_IOVA_CONTIG, align); 7384b4f810eSFerruh Yigit } 7394b4f810eSFerruh Yigit 7404b4f810eSFerruh Yigit int 7414b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, 7424b4f810eSFerruh Yigit struct rte_hairpin_peer_info *peer_info, 7434b4f810eSFerruh Yigit uint32_t direction) 7444b4f810eSFerruh Yigit { 7454b4f810eSFerruh Yigit struct rte_eth_dev *dev; 7464b4f810eSFerruh Yigit 7474b4f810eSFerruh Yigit if (peer_info == NULL) 7484b4f810eSFerruh Yigit return -EINVAL; 7494b4f810eSFerruh Yigit 7504b4f810eSFerruh Yigit /* No need to check the validity again. */ 7514b4f810eSFerruh Yigit dev = &rte_eth_devices[cur_port]; 7528f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_queue_peer_bind == NULL) 7538f1d23ecSDavid Marchand return -ENOTSUP; 7544b4f810eSFerruh Yigit 7554b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue, 7564b4f810eSFerruh Yigit peer_info, direction); 7574b4f810eSFerruh Yigit } 7584b4f810eSFerruh Yigit 7594b4f810eSFerruh Yigit int 7604b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, 7614b4f810eSFerruh Yigit uint32_t direction) 7624b4f810eSFerruh Yigit { 7634b4f810eSFerruh Yigit struct rte_eth_dev *dev; 7644b4f810eSFerruh Yigit 7654b4f810eSFerruh Yigit /* No need to check the validity again. */ 7664b4f810eSFerruh Yigit dev = &rte_eth_devices[cur_port]; 7678f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_queue_peer_unbind == NULL) 7688f1d23ecSDavid Marchand return -ENOTSUP; 7694b4f810eSFerruh Yigit 7704b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue, 7714b4f810eSFerruh Yigit direction); 7724b4f810eSFerruh Yigit } 7734b4f810eSFerruh Yigit 7744b4f810eSFerruh Yigit int 7754b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, 7764b4f810eSFerruh Yigit struct rte_hairpin_peer_info *cur_info, 7774b4f810eSFerruh Yigit struct rte_hairpin_peer_info *peer_info, 7784b4f810eSFerruh Yigit uint32_t direction) 7794b4f810eSFerruh Yigit { 7804b4f810eSFerruh Yigit struct rte_eth_dev *dev; 7814b4f810eSFerruh Yigit 7824b4f810eSFerruh Yigit /* Current queue information is not mandatory. */ 7834b4f810eSFerruh Yigit if (peer_info == NULL) 7844b4f810eSFerruh Yigit return -EINVAL; 7854b4f810eSFerruh Yigit 7864b4f810eSFerruh Yigit /* No need to check the validity again. */ 7874b4f810eSFerruh Yigit dev = &rte_eth_devices[peer_port]; 7888f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_queue_peer_update == NULL) 7898f1d23ecSDavid Marchand return -ENOTSUP; 7904b4f810eSFerruh Yigit 7914b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue, 7924b4f810eSFerruh Yigit cur_info, peer_info, direction); 7934b4f810eSFerruh Yigit } 7944b4f810eSFerruh Yigit 7954b4f810eSFerruh Yigit int 7964b4f810eSFerruh Yigit rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset) 7974b4f810eSFerruh Yigit { 7984b4f810eSFerruh Yigit static const struct rte_mbuf_dynfield field_desc = { 7994b4f810eSFerruh Yigit .name = RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, 8004b4f810eSFerruh Yigit .size = sizeof(rte_eth_ip_reassembly_dynfield_t), 80108966fe7STyler Retzlaff .align = alignof(rte_eth_ip_reassembly_dynfield_t), 8024b4f810eSFerruh Yigit }; 8034b4f810eSFerruh Yigit static const struct rte_mbuf_dynflag ip_reassembly_dynflag = { 8044b4f810eSFerruh Yigit .name = RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, 8054b4f810eSFerruh Yigit }; 8064b4f810eSFerruh Yigit int offset; 8074b4f810eSFerruh Yigit 8084b4f810eSFerruh Yigit offset = rte_mbuf_dynfield_register(&field_desc); 8094b4f810eSFerruh Yigit if (offset < 0) 8104b4f810eSFerruh Yigit return -1; 8114b4f810eSFerruh Yigit if (field_offset != NULL) 8124b4f810eSFerruh Yigit *field_offset = offset; 8134b4f810eSFerruh Yigit 8144b4f810eSFerruh Yigit offset = rte_mbuf_dynflag_register(&ip_reassembly_dynflag); 8154b4f810eSFerruh Yigit if (offset < 0) 8164b4f810eSFerruh Yigit return -1; 8174b4f810eSFerruh Yigit if (flag_offset != NULL) 8184b4f810eSFerruh Yigit *flag_offset = offset; 8194b4f810eSFerruh Yigit 8204b4f810eSFerruh Yigit return 0; 8214b4f810eSFerruh Yigit } 822a41f593fSFerruh Yigit 823a41f593fSFerruh Yigit uint16_t 824a41f593fSFerruh Yigit rte_eth_pkt_burst_dummy(void *queue __rte_unused, 825a41f593fSFerruh Yigit struct rte_mbuf **pkts __rte_unused, 826a41f593fSFerruh Yigit uint16_t nb_pkts __rte_unused) 827a41f593fSFerruh Yigit { 828a41f593fSFerruh Yigit return 0; 829a41f593fSFerruh Yigit } 8304b4f810eSFerruh Yigit 8314b4f810eSFerruh Yigit int 8324b4f810eSFerruh Yigit rte_eth_representor_id_get(uint16_t port_id, 8334b4f810eSFerruh Yigit enum rte_eth_representor_type type, 8344b4f810eSFerruh Yigit int controller, int pf, int representor_port, 8354b4f810eSFerruh Yigit uint16_t *repr_id) 8364b4f810eSFerruh Yigit { 8374b4f810eSFerruh Yigit int ret, n, count; 8384b4f810eSFerruh Yigit uint32_t i; 8394b4f810eSFerruh Yigit struct rte_eth_representor_info *info = NULL; 8404b4f810eSFerruh Yigit size_t size; 8414b4f810eSFerruh Yigit 8424b4f810eSFerruh Yigit if (type == RTE_ETH_REPRESENTOR_NONE) 8434b4f810eSFerruh Yigit return 0; 8444b4f810eSFerruh Yigit if (repr_id == NULL) 8454b4f810eSFerruh Yigit return -EINVAL; 8464b4f810eSFerruh Yigit 8474b4f810eSFerruh Yigit /* Get PMD representor range info. */ 8484b4f810eSFerruh Yigit ret = rte_eth_representor_info_get(port_id, NULL); 8494b4f810eSFerruh Yigit if (ret == -ENOTSUP && type == RTE_ETH_REPRESENTOR_VF && 8504b4f810eSFerruh Yigit controller == -1 && pf == -1) { 8514b4f810eSFerruh Yigit /* Direct mapping for legacy VF representor. */ 8524b4f810eSFerruh Yigit *repr_id = representor_port; 8534b4f810eSFerruh Yigit return 0; 8544b4f810eSFerruh Yigit } else if (ret < 0) { 8554b4f810eSFerruh Yigit return ret; 8564b4f810eSFerruh Yigit } 8574b4f810eSFerruh Yigit n = ret; 8584b4f810eSFerruh Yigit size = sizeof(*info) + n * sizeof(info->ranges[0]); 8594b4f810eSFerruh Yigit info = calloc(1, size); 8604b4f810eSFerruh Yigit if (info == NULL) 8614b4f810eSFerruh Yigit return -ENOMEM; 8624b4f810eSFerruh Yigit info->nb_ranges_alloc = n; 8634b4f810eSFerruh Yigit ret = rte_eth_representor_info_get(port_id, info); 8644b4f810eSFerruh Yigit if (ret < 0) 8654b4f810eSFerruh Yigit goto out; 8664b4f810eSFerruh Yigit 8674b4f810eSFerruh Yigit /* Default controller and pf to caller. */ 8684b4f810eSFerruh Yigit if (controller == -1) 8694b4f810eSFerruh Yigit controller = info->controller; 8704b4f810eSFerruh Yigit if (pf == -1) 8714b4f810eSFerruh Yigit pf = info->pf; 8724b4f810eSFerruh Yigit 8734b4f810eSFerruh Yigit /* Locate representor ID. */ 8744b4f810eSFerruh Yigit ret = -ENOENT; 8754b4f810eSFerruh Yigit for (i = 0; i < info->nb_ranges; ++i) { 8764b4f810eSFerruh Yigit if (info->ranges[i].type != type) 8774b4f810eSFerruh Yigit continue; 8784b4f810eSFerruh Yigit if (info->ranges[i].controller != controller) 8794b4f810eSFerruh Yigit continue; 8804b4f810eSFerruh Yigit if (info->ranges[i].id_end < info->ranges[i].id_base) { 8810e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(WARNING, "Port %hu invalid representor ID Range %u - %u, entry %d", 8824b4f810eSFerruh Yigit port_id, info->ranges[i].id_base, 8834b4f810eSFerruh Yigit info->ranges[i].id_end, i); 8844b4f810eSFerruh Yigit continue; 8854b4f810eSFerruh Yigit 8864b4f810eSFerruh Yigit } 8874b4f810eSFerruh Yigit count = info->ranges[i].id_end - info->ranges[i].id_base + 1; 8884b4f810eSFerruh Yigit switch (info->ranges[i].type) { 8894b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_PF: 8904b4f810eSFerruh Yigit if (pf < info->ranges[i].pf || 8914b4f810eSFerruh Yigit pf >= info->ranges[i].pf + count) 8924b4f810eSFerruh Yigit continue; 8934b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 8944b4f810eSFerruh Yigit (pf - info->ranges[i].pf); 8954b4f810eSFerruh Yigit ret = 0; 8964b4f810eSFerruh Yigit goto out; 8974b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_VF: 8984b4f810eSFerruh Yigit if (info->ranges[i].pf != pf) 8994b4f810eSFerruh Yigit continue; 9004b4f810eSFerruh Yigit if (representor_port < info->ranges[i].vf || 9014b4f810eSFerruh Yigit representor_port >= info->ranges[i].vf + count) 9024b4f810eSFerruh Yigit continue; 9034b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 9044b4f810eSFerruh Yigit (representor_port - info->ranges[i].vf); 9054b4f810eSFerruh Yigit ret = 0; 9064b4f810eSFerruh Yigit goto out; 9074b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_SF: 9084b4f810eSFerruh Yigit if (info->ranges[i].pf != pf) 9094b4f810eSFerruh Yigit continue; 9104b4f810eSFerruh Yigit if (representor_port < info->ranges[i].sf || 9114b4f810eSFerruh Yigit representor_port >= info->ranges[i].sf + count) 9124b4f810eSFerruh Yigit continue; 9134b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 9144b4f810eSFerruh Yigit (representor_port - info->ranges[i].sf); 9154b4f810eSFerruh Yigit ret = 0; 9164b4f810eSFerruh Yigit goto out; 9174b4f810eSFerruh Yigit default: 9184b4f810eSFerruh Yigit break; 9194b4f810eSFerruh Yigit } 9204b4f810eSFerruh Yigit } 9214b4f810eSFerruh Yigit out: 9224b4f810eSFerruh Yigit free(info); 9234b4f810eSFerruh Yigit return ret; 9244b4f810eSFerruh Yigit } 9254b4f810eSFerruh Yigit 9264b4f810eSFerruh Yigit int 9274b4f810eSFerruh Yigit rte_eth_switch_domain_alloc(uint16_t *domain_id) 9284b4f810eSFerruh Yigit { 9294b4f810eSFerruh Yigit uint16_t i; 9304b4f810eSFerruh Yigit 9314b4f810eSFerruh Yigit *domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 9324b4f810eSFerruh Yigit 9334b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 9344b4f810eSFerruh Yigit if (eth_dev_switch_domains[i].state == 9354b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_UNUSED) { 9364b4f810eSFerruh Yigit eth_dev_switch_domains[i].state = 9374b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED; 9384b4f810eSFerruh Yigit *domain_id = i; 9394b4f810eSFerruh Yigit return 0; 9404b4f810eSFerruh Yigit } 9414b4f810eSFerruh Yigit } 9424b4f810eSFerruh Yigit 9434b4f810eSFerruh Yigit return -ENOSPC; 9444b4f810eSFerruh Yigit } 9454b4f810eSFerruh Yigit 9464b4f810eSFerruh Yigit int 9474b4f810eSFerruh Yigit rte_eth_switch_domain_free(uint16_t domain_id) 9484b4f810eSFerruh Yigit { 9494b4f810eSFerruh Yigit if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID || 9504b4f810eSFerruh Yigit domain_id >= RTE_MAX_ETHPORTS) 9514b4f810eSFerruh Yigit return -EINVAL; 9524b4f810eSFerruh Yigit 9534b4f810eSFerruh Yigit if (eth_dev_switch_domains[domain_id].state != 9544b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED) 9554b4f810eSFerruh Yigit return -EINVAL; 9564b4f810eSFerruh Yigit 9574b4f810eSFerruh Yigit eth_dev_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED; 9584b4f810eSFerruh Yigit 9594b4f810eSFerruh Yigit return 0; 9604b4f810eSFerruh Yigit } 961*5e46b176SDariusz Sosnowski 962*5e46b176SDariusz Sosnowski uint64_t 963*5e46b176SDariusz Sosnowski rte_eth_get_restore_flags(struct rte_eth_dev *dev, enum rte_eth_dev_operation op) 964*5e46b176SDariusz Sosnowski { 965*5e46b176SDariusz Sosnowski if (dev->dev_ops->get_restore_flags != NULL) 966*5e46b176SDariusz Sosnowski return dev->dev_ops->get_restore_flags(dev, op); 967*5e46b176SDariusz Sosnowski else 968*5e46b176SDariusz Sosnowski return RTE_ETH_RESTORE_ALL; 969*5e46b176SDariusz Sosnowski } 970