1a41f593fSFerruh Yigit /* SPDX-License-Identifier: BSD-3-Clause 2a41f593fSFerruh Yigit * Copyright(c) 2022 Intel Corporation 3a41f593fSFerruh Yigit */ 4a41f593fSFerruh Yigit 5*4b4f810eSFerruh Yigit #include <rte_kvargs.h> 6*4b4f810eSFerruh Yigit #include <rte_malloc.h> 7*4b4f810eSFerruh Yigit 8a41f593fSFerruh Yigit #include "ethdev_driver.h" 9*4b4f810eSFerruh Yigit #include "ethdev_private.h" 10*4b4f810eSFerruh Yigit 11*4b4f810eSFerruh Yigit /** 12*4b4f810eSFerruh Yigit * A set of values to describe the possible states of a switch domain. 13*4b4f810eSFerruh Yigit */ 14*4b4f810eSFerruh Yigit enum rte_eth_switch_domain_state { 15*4b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_UNUSED = 0, 16*4b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED 17*4b4f810eSFerruh Yigit }; 18*4b4f810eSFerruh Yigit 19*4b4f810eSFerruh Yigit /** 20*4b4f810eSFerruh Yigit * Array of switch domains available for allocation. Array is sized to 21*4b4f810eSFerruh Yigit * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than 22*4b4f810eSFerruh Yigit * ethdev ports in a single process. 23*4b4f810eSFerruh Yigit */ 24*4b4f810eSFerruh Yigit static struct rte_eth_dev_switch { 25*4b4f810eSFerruh Yigit enum rte_eth_switch_domain_state state; 26*4b4f810eSFerruh Yigit } eth_dev_switch_domains[RTE_MAX_ETHPORTS]; 27*4b4f810eSFerruh Yigit 28*4b4f810eSFerruh Yigit static struct rte_eth_dev * 29*4b4f810eSFerruh Yigit eth_dev_allocated(const char *name) 30*4b4f810eSFerruh Yigit { 31*4b4f810eSFerruh Yigit uint16_t i; 32*4b4f810eSFerruh Yigit 33*4b4f810eSFerruh Yigit RTE_BUILD_BUG_ON(RTE_MAX_ETHPORTS >= UINT16_MAX); 34*4b4f810eSFerruh Yigit 35*4b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 36*4b4f810eSFerruh Yigit if (rte_eth_devices[i].data != NULL && 37*4b4f810eSFerruh Yigit strcmp(rte_eth_devices[i].data->name, name) == 0) 38*4b4f810eSFerruh Yigit return &rte_eth_devices[i]; 39*4b4f810eSFerruh Yigit } 40*4b4f810eSFerruh Yigit return NULL; 41*4b4f810eSFerruh Yigit } 42*4b4f810eSFerruh Yigit 43*4b4f810eSFerruh Yigit static uint16_t 44*4b4f810eSFerruh Yigit eth_dev_find_free_port(void) 45*4b4f810eSFerruh Yigit { 46*4b4f810eSFerruh Yigit uint16_t i; 47*4b4f810eSFerruh Yigit 48*4b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 49*4b4f810eSFerruh Yigit /* Using shared name field to find a free port. */ 50*4b4f810eSFerruh Yigit if (eth_dev_shared_data->data[i].name[0] == '\0') { 51*4b4f810eSFerruh Yigit RTE_ASSERT(rte_eth_devices[i].state == 52*4b4f810eSFerruh Yigit RTE_ETH_DEV_UNUSED); 53*4b4f810eSFerruh Yigit return i; 54*4b4f810eSFerruh Yigit } 55*4b4f810eSFerruh Yigit } 56*4b4f810eSFerruh Yigit return RTE_MAX_ETHPORTS; 57*4b4f810eSFerruh Yigit } 58*4b4f810eSFerruh Yigit 59*4b4f810eSFerruh Yigit static struct rte_eth_dev * 60*4b4f810eSFerruh Yigit eth_dev_get(uint16_t port_id) 61*4b4f810eSFerruh Yigit { 62*4b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id]; 63*4b4f810eSFerruh Yigit 64*4b4f810eSFerruh Yigit eth_dev->data = ð_dev_shared_data->data[port_id]; 65*4b4f810eSFerruh Yigit 66*4b4f810eSFerruh Yigit return eth_dev; 67*4b4f810eSFerruh Yigit } 68*4b4f810eSFerruh Yigit 69*4b4f810eSFerruh Yigit struct rte_eth_dev * 70*4b4f810eSFerruh Yigit rte_eth_dev_allocate(const char *name) 71*4b4f810eSFerruh Yigit { 72*4b4f810eSFerruh Yigit uint16_t port_id; 73*4b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = NULL; 74*4b4f810eSFerruh Yigit size_t name_len; 75*4b4f810eSFerruh Yigit 76*4b4f810eSFerruh Yigit name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN); 77*4b4f810eSFerruh Yigit if (name_len == 0) { 78*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n"); 79*4b4f810eSFerruh Yigit return NULL; 80*4b4f810eSFerruh Yigit } 81*4b4f810eSFerruh Yigit 82*4b4f810eSFerruh Yigit if (name_len >= RTE_ETH_NAME_MAX_LEN) { 83*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n"); 84*4b4f810eSFerruh Yigit return NULL; 85*4b4f810eSFerruh Yigit } 86*4b4f810eSFerruh Yigit 87*4b4f810eSFerruh Yigit eth_dev_shared_data_prepare(); 88*4b4f810eSFerruh Yigit 89*4b4f810eSFerruh Yigit /* Synchronize port creation between primary and secondary threads. */ 90*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 91*4b4f810eSFerruh Yigit 92*4b4f810eSFerruh Yigit if (eth_dev_allocated(name) != NULL) { 93*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 94*4b4f810eSFerruh Yigit "Ethernet device with name %s already allocated\n", 95*4b4f810eSFerruh Yigit name); 96*4b4f810eSFerruh Yigit goto unlock; 97*4b4f810eSFerruh Yigit } 98*4b4f810eSFerruh Yigit 99*4b4f810eSFerruh Yigit port_id = eth_dev_find_free_port(); 100*4b4f810eSFerruh Yigit if (port_id == RTE_MAX_ETHPORTS) { 101*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 102*4b4f810eSFerruh Yigit "Reached maximum number of Ethernet ports\n"); 103*4b4f810eSFerruh Yigit goto unlock; 104*4b4f810eSFerruh Yigit } 105*4b4f810eSFerruh Yigit 106*4b4f810eSFerruh Yigit eth_dev = eth_dev_get(port_id); 107*4b4f810eSFerruh Yigit strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name)); 108*4b4f810eSFerruh Yigit eth_dev->data->port_id = port_id; 109*4b4f810eSFerruh Yigit eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS; 110*4b4f810eSFerruh Yigit eth_dev->data->mtu = RTE_ETHER_MTU; 111*4b4f810eSFerruh Yigit pthread_mutex_init(ð_dev->data->flow_ops_mutex, NULL); 112*4b4f810eSFerruh Yigit 113*4b4f810eSFerruh Yigit unlock: 114*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 115*4b4f810eSFerruh Yigit 116*4b4f810eSFerruh Yigit return eth_dev; 117*4b4f810eSFerruh Yigit } 118*4b4f810eSFerruh Yigit 119*4b4f810eSFerruh Yigit struct rte_eth_dev * 120*4b4f810eSFerruh Yigit rte_eth_dev_allocated(const char *name) 121*4b4f810eSFerruh Yigit { 122*4b4f810eSFerruh Yigit struct rte_eth_dev *ethdev; 123*4b4f810eSFerruh Yigit 124*4b4f810eSFerruh Yigit eth_dev_shared_data_prepare(); 125*4b4f810eSFerruh Yigit 126*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 127*4b4f810eSFerruh Yigit 128*4b4f810eSFerruh Yigit ethdev = eth_dev_allocated(name); 129*4b4f810eSFerruh Yigit 130*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 131*4b4f810eSFerruh Yigit 132*4b4f810eSFerruh Yigit return ethdev; 133*4b4f810eSFerruh Yigit } 134*4b4f810eSFerruh Yigit 135*4b4f810eSFerruh Yigit /* 136*4b4f810eSFerruh Yigit * Attach to a port already registered by the primary process, which 137*4b4f810eSFerruh Yigit * makes sure that the same device would have the same port ID both 138*4b4f810eSFerruh Yigit * in the primary and secondary process. 139*4b4f810eSFerruh Yigit */ 140*4b4f810eSFerruh Yigit struct rte_eth_dev * 141*4b4f810eSFerruh Yigit rte_eth_dev_attach_secondary(const char *name) 142*4b4f810eSFerruh Yigit { 143*4b4f810eSFerruh Yigit uint16_t i; 144*4b4f810eSFerruh Yigit struct rte_eth_dev *eth_dev = NULL; 145*4b4f810eSFerruh Yigit 146*4b4f810eSFerruh Yigit eth_dev_shared_data_prepare(); 147*4b4f810eSFerruh Yigit 148*4b4f810eSFerruh Yigit /* Synchronize port attachment to primary port creation and release. */ 149*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 150*4b4f810eSFerruh Yigit 151*4b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 152*4b4f810eSFerruh Yigit if (strcmp(eth_dev_shared_data->data[i].name, name) == 0) 153*4b4f810eSFerruh Yigit break; 154*4b4f810eSFerruh Yigit } 155*4b4f810eSFerruh Yigit if (i == RTE_MAX_ETHPORTS) { 156*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 157*4b4f810eSFerruh Yigit "Device %s is not driven by the primary process\n", 158*4b4f810eSFerruh Yigit name); 159*4b4f810eSFerruh Yigit } else { 160*4b4f810eSFerruh Yigit eth_dev = eth_dev_get(i); 161*4b4f810eSFerruh Yigit RTE_ASSERT(eth_dev->data->port_id == i); 162*4b4f810eSFerruh Yigit } 163*4b4f810eSFerruh Yigit 164*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 165*4b4f810eSFerruh Yigit return eth_dev; 166*4b4f810eSFerruh Yigit } 167*4b4f810eSFerruh Yigit 168*4b4f810eSFerruh Yigit int 169*4b4f810eSFerruh Yigit rte_eth_dev_callback_process(struct rte_eth_dev *dev, 170*4b4f810eSFerruh Yigit enum rte_eth_event_type event, void *ret_param) 171*4b4f810eSFerruh Yigit { 172*4b4f810eSFerruh Yigit struct rte_eth_dev_callback *cb_lst; 173*4b4f810eSFerruh Yigit struct rte_eth_dev_callback dev_cb; 174*4b4f810eSFerruh Yigit int rc = 0; 175*4b4f810eSFerruh Yigit 176*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_cb_lock); 177*4b4f810eSFerruh Yigit TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) { 178*4b4f810eSFerruh Yigit if (cb_lst->cb_fn == NULL || cb_lst->event != event) 179*4b4f810eSFerruh Yigit continue; 180*4b4f810eSFerruh Yigit dev_cb = *cb_lst; 181*4b4f810eSFerruh Yigit cb_lst->active = 1; 182*4b4f810eSFerruh Yigit if (ret_param != NULL) 183*4b4f810eSFerruh Yigit dev_cb.ret_param = ret_param; 184*4b4f810eSFerruh Yigit 185*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_cb_lock); 186*4b4f810eSFerruh Yigit rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event, 187*4b4f810eSFerruh Yigit dev_cb.cb_arg, dev_cb.ret_param); 188*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_cb_lock); 189*4b4f810eSFerruh Yigit cb_lst->active = 0; 190*4b4f810eSFerruh Yigit } 191*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_cb_lock); 192*4b4f810eSFerruh Yigit return rc; 193*4b4f810eSFerruh Yigit } 194*4b4f810eSFerruh Yigit 195*4b4f810eSFerruh Yigit void 196*4b4f810eSFerruh Yigit rte_eth_dev_probing_finish(struct rte_eth_dev *dev) 197*4b4f810eSFerruh Yigit { 198*4b4f810eSFerruh Yigit if (dev == NULL) 199*4b4f810eSFerruh Yigit return; 200*4b4f810eSFerruh Yigit 201*4b4f810eSFerruh Yigit /* 202*4b4f810eSFerruh Yigit * for secondary process, at that point we expect device 203*4b4f810eSFerruh Yigit * to be already 'usable', so shared data and all function pointers 204*4b4f810eSFerruh Yigit * for fast-path devops have to be setup properly inside rte_eth_dev. 205*4b4f810eSFerruh Yigit */ 206*4b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_SECONDARY) 207*4b4f810eSFerruh Yigit eth_dev_fp_ops_setup(rte_eth_fp_ops + dev->data->port_id, dev); 208*4b4f810eSFerruh Yigit 209*4b4f810eSFerruh Yigit rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL); 210*4b4f810eSFerruh Yigit 211*4b4f810eSFerruh Yigit dev->state = RTE_ETH_DEV_ATTACHED; 212*4b4f810eSFerruh Yigit } 213*4b4f810eSFerruh Yigit 214*4b4f810eSFerruh Yigit int 215*4b4f810eSFerruh Yigit rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) 216*4b4f810eSFerruh Yigit { 217*4b4f810eSFerruh Yigit if (eth_dev == NULL) 218*4b4f810eSFerruh Yigit return -EINVAL; 219*4b4f810eSFerruh Yigit 220*4b4f810eSFerruh Yigit eth_dev_shared_data_prepare(); 221*4b4f810eSFerruh Yigit 222*4b4f810eSFerruh Yigit if (eth_dev->state != RTE_ETH_DEV_UNUSED) 223*4b4f810eSFerruh Yigit rte_eth_dev_callback_process(eth_dev, 224*4b4f810eSFerruh Yigit RTE_ETH_EVENT_DESTROY, NULL); 225*4b4f810eSFerruh Yigit 226*4b4f810eSFerruh Yigit eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id); 227*4b4f810eSFerruh Yigit 228*4b4f810eSFerruh Yigit rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 229*4b4f810eSFerruh Yigit 230*4b4f810eSFerruh Yigit eth_dev->state = RTE_ETH_DEV_UNUSED; 231*4b4f810eSFerruh Yigit eth_dev->device = NULL; 232*4b4f810eSFerruh Yigit eth_dev->process_private = NULL; 233*4b4f810eSFerruh Yigit eth_dev->intr_handle = NULL; 234*4b4f810eSFerruh Yigit eth_dev->rx_pkt_burst = NULL; 235*4b4f810eSFerruh Yigit eth_dev->tx_pkt_burst = NULL; 236*4b4f810eSFerruh Yigit eth_dev->tx_pkt_prepare = NULL; 237*4b4f810eSFerruh Yigit eth_dev->rx_queue_count = NULL; 238*4b4f810eSFerruh Yigit eth_dev->rx_descriptor_status = NULL; 239*4b4f810eSFerruh Yigit eth_dev->tx_descriptor_status = NULL; 240*4b4f810eSFerruh Yigit eth_dev->dev_ops = NULL; 241*4b4f810eSFerruh Yigit 242*4b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 243*4b4f810eSFerruh Yigit rte_free(eth_dev->data->rx_queues); 244*4b4f810eSFerruh Yigit rte_free(eth_dev->data->tx_queues); 245*4b4f810eSFerruh Yigit rte_free(eth_dev->data->mac_addrs); 246*4b4f810eSFerruh Yigit rte_free(eth_dev->data->hash_mac_addrs); 247*4b4f810eSFerruh Yigit rte_free(eth_dev->data->dev_private); 248*4b4f810eSFerruh Yigit pthread_mutex_destroy(ð_dev->data->flow_ops_mutex); 249*4b4f810eSFerruh Yigit memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); 250*4b4f810eSFerruh Yigit } 251*4b4f810eSFerruh Yigit 252*4b4f810eSFerruh Yigit rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 253*4b4f810eSFerruh Yigit 254*4b4f810eSFerruh Yigit return 0; 255*4b4f810eSFerruh Yigit } 256*4b4f810eSFerruh Yigit 257*4b4f810eSFerruh Yigit int 258*4b4f810eSFerruh Yigit rte_eth_dev_create(struct rte_device *device, const char *name, 259*4b4f810eSFerruh Yigit size_t priv_data_size, 260*4b4f810eSFerruh Yigit ethdev_bus_specific_init ethdev_bus_specific_init, 261*4b4f810eSFerruh Yigit void *bus_init_params, 262*4b4f810eSFerruh Yigit ethdev_init_t ethdev_init, void *init_params) 263*4b4f810eSFerruh Yigit { 264*4b4f810eSFerruh Yigit struct rte_eth_dev *ethdev; 265*4b4f810eSFerruh Yigit int retval; 266*4b4f810eSFerruh Yigit 267*4b4f810eSFerruh Yigit RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL); 268*4b4f810eSFerruh Yigit 269*4b4f810eSFerruh Yigit if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 270*4b4f810eSFerruh Yigit ethdev = rte_eth_dev_allocate(name); 271*4b4f810eSFerruh Yigit if (!ethdev) 272*4b4f810eSFerruh Yigit return -ENODEV; 273*4b4f810eSFerruh Yigit 274*4b4f810eSFerruh Yigit if (priv_data_size) { 275*4b4f810eSFerruh Yigit ethdev->data->dev_private = rte_zmalloc_socket( 276*4b4f810eSFerruh Yigit name, priv_data_size, RTE_CACHE_LINE_SIZE, 277*4b4f810eSFerruh Yigit device->numa_node); 278*4b4f810eSFerruh Yigit 279*4b4f810eSFerruh Yigit if (!ethdev->data->dev_private) { 280*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 281*4b4f810eSFerruh Yigit "failed to allocate private data\n"); 282*4b4f810eSFerruh Yigit retval = -ENOMEM; 283*4b4f810eSFerruh Yigit goto probe_failed; 284*4b4f810eSFerruh Yigit } 285*4b4f810eSFerruh Yigit } 286*4b4f810eSFerruh Yigit } else { 287*4b4f810eSFerruh Yigit ethdev = rte_eth_dev_attach_secondary(name); 288*4b4f810eSFerruh Yigit if (!ethdev) { 289*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 290*4b4f810eSFerruh Yigit "secondary process attach failed, ethdev doesn't exist\n"); 291*4b4f810eSFerruh Yigit return -ENODEV; 292*4b4f810eSFerruh Yigit } 293*4b4f810eSFerruh Yigit } 294*4b4f810eSFerruh Yigit 295*4b4f810eSFerruh Yigit ethdev->device = device; 296*4b4f810eSFerruh Yigit 297*4b4f810eSFerruh Yigit if (ethdev_bus_specific_init) { 298*4b4f810eSFerruh Yigit retval = ethdev_bus_specific_init(ethdev, bus_init_params); 299*4b4f810eSFerruh Yigit if (retval) { 300*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 301*4b4f810eSFerruh Yigit "ethdev bus specific initialisation failed\n"); 302*4b4f810eSFerruh Yigit goto probe_failed; 303*4b4f810eSFerruh Yigit } 304*4b4f810eSFerruh Yigit } 305*4b4f810eSFerruh Yigit 306*4b4f810eSFerruh Yigit retval = ethdev_init(ethdev, init_params); 307*4b4f810eSFerruh Yigit if (retval) { 308*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "ethdev initialisation failed\n"); 309*4b4f810eSFerruh Yigit goto probe_failed; 310*4b4f810eSFerruh Yigit } 311*4b4f810eSFerruh Yigit 312*4b4f810eSFerruh Yigit rte_eth_dev_probing_finish(ethdev); 313*4b4f810eSFerruh Yigit 314*4b4f810eSFerruh Yigit return retval; 315*4b4f810eSFerruh Yigit 316*4b4f810eSFerruh Yigit probe_failed: 317*4b4f810eSFerruh Yigit rte_eth_dev_release_port(ethdev); 318*4b4f810eSFerruh Yigit return retval; 319*4b4f810eSFerruh Yigit } 320*4b4f810eSFerruh Yigit 321*4b4f810eSFerruh Yigit int 322*4b4f810eSFerruh Yigit rte_eth_dev_destroy(struct rte_eth_dev *ethdev, 323*4b4f810eSFerruh Yigit ethdev_uninit_t ethdev_uninit) 324*4b4f810eSFerruh Yigit { 325*4b4f810eSFerruh Yigit int ret; 326*4b4f810eSFerruh Yigit 327*4b4f810eSFerruh Yigit ethdev = rte_eth_dev_allocated(ethdev->data->name); 328*4b4f810eSFerruh Yigit if (!ethdev) 329*4b4f810eSFerruh Yigit return -ENODEV; 330*4b4f810eSFerruh Yigit 331*4b4f810eSFerruh Yigit RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL); 332*4b4f810eSFerruh Yigit 333*4b4f810eSFerruh Yigit ret = ethdev_uninit(ethdev); 334*4b4f810eSFerruh Yigit if (ret) 335*4b4f810eSFerruh Yigit return ret; 336*4b4f810eSFerruh Yigit 337*4b4f810eSFerruh Yigit return rte_eth_dev_release_port(ethdev); 338*4b4f810eSFerruh Yigit } 339*4b4f810eSFerruh Yigit 340*4b4f810eSFerruh Yigit struct rte_eth_dev * 341*4b4f810eSFerruh Yigit rte_eth_dev_get_by_name(const char *name) 342*4b4f810eSFerruh Yigit { 343*4b4f810eSFerruh Yigit uint16_t pid; 344*4b4f810eSFerruh Yigit 345*4b4f810eSFerruh Yigit if (rte_eth_dev_get_port_by_name(name, &pid)) 346*4b4f810eSFerruh Yigit return NULL; 347*4b4f810eSFerruh Yigit 348*4b4f810eSFerruh Yigit return &rte_eth_devices[pid]; 349*4b4f810eSFerruh Yigit } 350*4b4f810eSFerruh Yigit 351*4b4f810eSFerruh Yigit int 352*4b4f810eSFerruh Yigit rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 353*4b4f810eSFerruh Yigit { 354*4b4f810eSFerruh Yigit if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 355*4b4f810eSFerruh Yigit return 1; 356*4b4f810eSFerruh Yigit return 0; 357*4b4f810eSFerruh Yigit } 358*4b4f810eSFerruh Yigit 359*4b4f810eSFerruh Yigit int 360*4b4f810eSFerruh Yigit rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 361*4b4f810eSFerruh Yigit { 362*4b4f810eSFerruh Yigit if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 363*4b4f810eSFerruh Yigit return 1; 364*4b4f810eSFerruh Yigit return 0; 365*4b4f810eSFerruh Yigit } 366*4b4f810eSFerruh Yigit 367*4b4f810eSFerruh Yigit void 368*4b4f810eSFerruh Yigit rte_eth_dev_internal_reset(struct rte_eth_dev *dev) 369*4b4f810eSFerruh Yigit { 370*4b4f810eSFerruh Yigit if (dev->data->dev_started) { 371*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n", 372*4b4f810eSFerruh Yigit dev->data->port_id); 373*4b4f810eSFerruh Yigit return; 374*4b4f810eSFerruh Yigit } 375*4b4f810eSFerruh Yigit 376*4b4f810eSFerruh Yigit eth_dev_rx_queue_config(dev, 0); 377*4b4f810eSFerruh Yigit eth_dev_tx_queue_config(dev, 0); 378*4b4f810eSFerruh Yigit 379*4b4f810eSFerruh Yigit memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf)); 380*4b4f810eSFerruh Yigit } 381*4b4f810eSFerruh Yigit 382*4b4f810eSFerruh Yigit static int 383*4b4f810eSFerruh Yigit eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) 384*4b4f810eSFerruh Yigit { 385*4b4f810eSFerruh Yigit int state; 386*4b4f810eSFerruh Yigit struct rte_kvargs_pair *pair; 387*4b4f810eSFerruh Yigit char *letter; 388*4b4f810eSFerruh Yigit 389*4b4f810eSFerruh Yigit arglist->str = strdup(str_in); 390*4b4f810eSFerruh Yigit if (arglist->str == NULL) 391*4b4f810eSFerruh Yigit return -ENOMEM; 392*4b4f810eSFerruh Yigit 393*4b4f810eSFerruh Yigit letter = arglist->str; 394*4b4f810eSFerruh Yigit state = 0; 395*4b4f810eSFerruh Yigit arglist->count = 0; 396*4b4f810eSFerruh Yigit pair = &arglist->pairs[0]; 397*4b4f810eSFerruh Yigit while (1) { 398*4b4f810eSFerruh Yigit switch (state) { 399*4b4f810eSFerruh Yigit case 0: /* Initial */ 400*4b4f810eSFerruh Yigit if (*letter == '=') 401*4b4f810eSFerruh Yigit return -EINVAL; 402*4b4f810eSFerruh Yigit else if (*letter == '\0') 403*4b4f810eSFerruh Yigit return 0; 404*4b4f810eSFerruh Yigit 405*4b4f810eSFerruh Yigit state = 1; 406*4b4f810eSFerruh Yigit pair->key = letter; 407*4b4f810eSFerruh Yigit /* fallthrough */ 408*4b4f810eSFerruh Yigit 409*4b4f810eSFerruh Yigit case 1: /* Parsing key */ 410*4b4f810eSFerruh Yigit if (*letter == '=') { 411*4b4f810eSFerruh Yigit *letter = '\0'; 412*4b4f810eSFerruh Yigit pair->value = letter + 1; 413*4b4f810eSFerruh Yigit state = 2; 414*4b4f810eSFerruh Yigit } else if (*letter == ',' || *letter == '\0') 415*4b4f810eSFerruh Yigit return -EINVAL; 416*4b4f810eSFerruh Yigit break; 417*4b4f810eSFerruh Yigit 418*4b4f810eSFerruh Yigit 419*4b4f810eSFerruh Yigit case 2: /* Parsing value */ 420*4b4f810eSFerruh Yigit if (*letter == '[') 421*4b4f810eSFerruh Yigit state = 3; 422*4b4f810eSFerruh Yigit else if (*letter == ',') { 423*4b4f810eSFerruh Yigit *letter = '\0'; 424*4b4f810eSFerruh Yigit arglist->count++; 425*4b4f810eSFerruh Yigit pair = &arglist->pairs[arglist->count]; 426*4b4f810eSFerruh Yigit state = 0; 427*4b4f810eSFerruh Yigit } else if (*letter == '\0') { 428*4b4f810eSFerruh Yigit letter--; 429*4b4f810eSFerruh Yigit arglist->count++; 430*4b4f810eSFerruh Yigit pair = &arglist->pairs[arglist->count]; 431*4b4f810eSFerruh Yigit state = 0; 432*4b4f810eSFerruh Yigit } 433*4b4f810eSFerruh Yigit break; 434*4b4f810eSFerruh Yigit 435*4b4f810eSFerruh Yigit case 3: /* Parsing list */ 436*4b4f810eSFerruh Yigit if (*letter == ']') 437*4b4f810eSFerruh Yigit state = 2; 438*4b4f810eSFerruh Yigit else if (*letter == '\0') 439*4b4f810eSFerruh Yigit return -EINVAL; 440*4b4f810eSFerruh Yigit break; 441*4b4f810eSFerruh Yigit } 442*4b4f810eSFerruh Yigit letter++; 443*4b4f810eSFerruh Yigit } 444*4b4f810eSFerruh Yigit } 445*4b4f810eSFerruh Yigit 446*4b4f810eSFerruh Yigit int 447*4b4f810eSFerruh Yigit rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) 448*4b4f810eSFerruh Yigit { 449*4b4f810eSFerruh Yigit struct rte_kvargs args; 450*4b4f810eSFerruh Yigit struct rte_kvargs_pair *pair; 451*4b4f810eSFerruh Yigit unsigned int i; 452*4b4f810eSFerruh Yigit int result = 0; 453*4b4f810eSFerruh Yigit 454*4b4f810eSFerruh Yigit memset(eth_da, 0, sizeof(*eth_da)); 455*4b4f810eSFerruh Yigit 456*4b4f810eSFerruh Yigit result = eth_dev_devargs_tokenise(&args, dargs); 457*4b4f810eSFerruh Yigit if (result < 0) 458*4b4f810eSFerruh Yigit goto parse_cleanup; 459*4b4f810eSFerruh Yigit 460*4b4f810eSFerruh Yigit for (i = 0; i < args.count; i++) { 461*4b4f810eSFerruh Yigit pair = &args.pairs[i]; 462*4b4f810eSFerruh Yigit if (strcmp("representor", pair->key) == 0) { 463*4b4f810eSFerruh Yigit if (eth_da->type != RTE_ETH_REPRESENTOR_NONE) { 464*4b4f810eSFerruh Yigit RTE_LOG(ERR, EAL, "duplicated representor key: %s\n", 465*4b4f810eSFerruh Yigit dargs); 466*4b4f810eSFerruh Yigit result = -1; 467*4b4f810eSFerruh Yigit goto parse_cleanup; 468*4b4f810eSFerruh Yigit } 469*4b4f810eSFerruh Yigit result = rte_eth_devargs_parse_representor_ports( 470*4b4f810eSFerruh Yigit pair->value, eth_da); 471*4b4f810eSFerruh Yigit if (result < 0) 472*4b4f810eSFerruh Yigit goto parse_cleanup; 473*4b4f810eSFerruh Yigit } 474*4b4f810eSFerruh Yigit } 475*4b4f810eSFerruh Yigit 476*4b4f810eSFerruh Yigit parse_cleanup: 477*4b4f810eSFerruh Yigit free(args.str); 478*4b4f810eSFerruh Yigit 479*4b4f810eSFerruh Yigit return result; 480*4b4f810eSFerruh Yigit } 481*4b4f810eSFerruh Yigit 482*4b4f810eSFerruh Yigit static inline int 483*4b4f810eSFerruh Yigit eth_dev_dma_mzone_name(char *name, size_t len, uint16_t port_id, uint16_t queue_id, 484*4b4f810eSFerruh Yigit const char *ring_name) 485*4b4f810eSFerruh Yigit { 486*4b4f810eSFerruh Yigit return snprintf(name, len, "eth_p%d_q%d_%s", 487*4b4f810eSFerruh Yigit port_id, queue_id, ring_name); 488*4b4f810eSFerruh Yigit } 489*4b4f810eSFerruh Yigit 490*4b4f810eSFerruh Yigit int 491*4b4f810eSFerruh Yigit rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name, 492*4b4f810eSFerruh Yigit uint16_t queue_id) 493*4b4f810eSFerruh Yigit { 494*4b4f810eSFerruh Yigit char z_name[RTE_MEMZONE_NAMESIZE]; 495*4b4f810eSFerruh Yigit const struct rte_memzone *mz; 496*4b4f810eSFerruh Yigit int rc = 0; 497*4b4f810eSFerruh Yigit 498*4b4f810eSFerruh Yigit rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 499*4b4f810eSFerruh Yigit queue_id, ring_name); 500*4b4f810eSFerruh Yigit if (rc >= RTE_MEMZONE_NAMESIZE) { 501*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "ring name too long\n"); 502*4b4f810eSFerruh Yigit return -ENAMETOOLONG; 503*4b4f810eSFerruh Yigit } 504*4b4f810eSFerruh Yigit 505*4b4f810eSFerruh Yigit mz = rte_memzone_lookup(z_name); 506*4b4f810eSFerruh Yigit if (mz) 507*4b4f810eSFerruh Yigit rc = rte_memzone_free(mz); 508*4b4f810eSFerruh Yigit else 509*4b4f810eSFerruh Yigit rc = -ENOENT; 510*4b4f810eSFerruh Yigit 511*4b4f810eSFerruh Yigit return rc; 512*4b4f810eSFerruh Yigit } 513*4b4f810eSFerruh Yigit 514*4b4f810eSFerruh Yigit const struct rte_memzone * 515*4b4f810eSFerruh Yigit rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, 516*4b4f810eSFerruh Yigit uint16_t queue_id, size_t size, unsigned int align, 517*4b4f810eSFerruh Yigit int socket_id) 518*4b4f810eSFerruh Yigit { 519*4b4f810eSFerruh Yigit char z_name[RTE_MEMZONE_NAMESIZE]; 520*4b4f810eSFerruh Yigit const struct rte_memzone *mz; 521*4b4f810eSFerruh Yigit int rc; 522*4b4f810eSFerruh Yigit 523*4b4f810eSFerruh Yigit rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 524*4b4f810eSFerruh Yigit queue_id, ring_name); 525*4b4f810eSFerruh Yigit if (rc >= RTE_MEMZONE_NAMESIZE) { 526*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, "ring name too long\n"); 527*4b4f810eSFerruh Yigit rte_errno = ENAMETOOLONG; 528*4b4f810eSFerruh Yigit return NULL; 529*4b4f810eSFerruh Yigit } 530*4b4f810eSFerruh Yigit 531*4b4f810eSFerruh Yigit mz = rte_memzone_lookup(z_name); 532*4b4f810eSFerruh Yigit if (mz) { 533*4b4f810eSFerruh Yigit if ((socket_id != SOCKET_ID_ANY && socket_id != mz->socket_id) || 534*4b4f810eSFerruh Yigit size > mz->len || 535*4b4f810eSFerruh Yigit ((uintptr_t)mz->addr & (align - 1)) != 0) { 536*4b4f810eSFerruh Yigit RTE_ETHDEV_LOG(ERR, 537*4b4f810eSFerruh Yigit "memzone %s does not justify the requested attributes\n", 538*4b4f810eSFerruh Yigit mz->name); 539*4b4f810eSFerruh Yigit return NULL; 540*4b4f810eSFerruh Yigit } 541*4b4f810eSFerruh Yigit 542*4b4f810eSFerruh Yigit return mz; 543*4b4f810eSFerruh Yigit } 544*4b4f810eSFerruh Yigit 545*4b4f810eSFerruh Yigit return rte_memzone_reserve_aligned(z_name, size, socket_id, 546*4b4f810eSFerruh Yigit RTE_MEMZONE_IOVA_CONTIG, align); 547*4b4f810eSFerruh Yigit } 548*4b4f810eSFerruh Yigit 549*4b4f810eSFerruh Yigit int 550*4b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, 551*4b4f810eSFerruh Yigit struct rte_hairpin_peer_info *peer_info, 552*4b4f810eSFerruh Yigit uint32_t direction) 553*4b4f810eSFerruh Yigit { 554*4b4f810eSFerruh Yigit struct rte_eth_dev *dev; 555*4b4f810eSFerruh Yigit 556*4b4f810eSFerruh Yigit if (peer_info == NULL) 557*4b4f810eSFerruh Yigit return -EINVAL; 558*4b4f810eSFerruh Yigit 559*4b4f810eSFerruh Yigit /* No need to check the validity again. */ 560*4b4f810eSFerruh Yigit dev = &rte_eth_devices[cur_port]; 561*4b4f810eSFerruh Yigit RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind, 562*4b4f810eSFerruh Yigit -ENOTSUP); 563*4b4f810eSFerruh Yigit 564*4b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue, 565*4b4f810eSFerruh Yigit peer_info, direction); 566*4b4f810eSFerruh Yigit } 567*4b4f810eSFerruh Yigit 568*4b4f810eSFerruh Yigit int 569*4b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, 570*4b4f810eSFerruh Yigit uint32_t direction) 571*4b4f810eSFerruh Yigit { 572*4b4f810eSFerruh Yigit struct rte_eth_dev *dev; 573*4b4f810eSFerruh Yigit 574*4b4f810eSFerruh Yigit /* No need to check the validity again. */ 575*4b4f810eSFerruh Yigit dev = &rte_eth_devices[cur_port]; 576*4b4f810eSFerruh Yigit RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind, 577*4b4f810eSFerruh Yigit -ENOTSUP); 578*4b4f810eSFerruh Yigit 579*4b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue, 580*4b4f810eSFerruh Yigit direction); 581*4b4f810eSFerruh Yigit } 582*4b4f810eSFerruh Yigit 583*4b4f810eSFerruh Yigit int 584*4b4f810eSFerruh Yigit rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, 585*4b4f810eSFerruh Yigit struct rte_hairpin_peer_info *cur_info, 586*4b4f810eSFerruh Yigit struct rte_hairpin_peer_info *peer_info, 587*4b4f810eSFerruh Yigit uint32_t direction) 588*4b4f810eSFerruh Yigit { 589*4b4f810eSFerruh Yigit struct rte_eth_dev *dev; 590*4b4f810eSFerruh Yigit 591*4b4f810eSFerruh Yigit /* Current queue information is not mandatory. */ 592*4b4f810eSFerruh Yigit if (peer_info == NULL) 593*4b4f810eSFerruh Yigit return -EINVAL; 594*4b4f810eSFerruh Yigit 595*4b4f810eSFerruh Yigit /* No need to check the validity again. */ 596*4b4f810eSFerruh Yigit dev = &rte_eth_devices[peer_port]; 597*4b4f810eSFerruh Yigit RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update, 598*4b4f810eSFerruh Yigit -ENOTSUP); 599*4b4f810eSFerruh Yigit 600*4b4f810eSFerruh Yigit return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue, 601*4b4f810eSFerruh Yigit cur_info, peer_info, direction); 602*4b4f810eSFerruh Yigit } 603*4b4f810eSFerruh Yigit 604*4b4f810eSFerruh Yigit int 605*4b4f810eSFerruh Yigit rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset) 606*4b4f810eSFerruh Yigit { 607*4b4f810eSFerruh Yigit static const struct rte_mbuf_dynfield field_desc = { 608*4b4f810eSFerruh Yigit .name = RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, 609*4b4f810eSFerruh Yigit .size = sizeof(rte_eth_ip_reassembly_dynfield_t), 610*4b4f810eSFerruh Yigit .align = __alignof__(rte_eth_ip_reassembly_dynfield_t), 611*4b4f810eSFerruh Yigit }; 612*4b4f810eSFerruh Yigit static const struct rte_mbuf_dynflag ip_reassembly_dynflag = { 613*4b4f810eSFerruh Yigit .name = RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, 614*4b4f810eSFerruh Yigit }; 615*4b4f810eSFerruh Yigit int offset; 616*4b4f810eSFerruh Yigit 617*4b4f810eSFerruh Yigit offset = rte_mbuf_dynfield_register(&field_desc); 618*4b4f810eSFerruh Yigit if (offset < 0) 619*4b4f810eSFerruh Yigit return -1; 620*4b4f810eSFerruh Yigit if (field_offset != NULL) 621*4b4f810eSFerruh Yigit *field_offset = offset; 622*4b4f810eSFerruh Yigit 623*4b4f810eSFerruh Yigit offset = rte_mbuf_dynflag_register(&ip_reassembly_dynflag); 624*4b4f810eSFerruh Yigit if (offset < 0) 625*4b4f810eSFerruh Yigit return -1; 626*4b4f810eSFerruh Yigit if (flag_offset != NULL) 627*4b4f810eSFerruh Yigit *flag_offset = offset; 628*4b4f810eSFerruh Yigit 629*4b4f810eSFerruh Yigit return 0; 630*4b4f810eSFerruh Yigit } 631a41f593fSFerruh Yigit 632a41f593fSFerruh Yigit uint16_t 633a41f593fSFerruh Yigit rte_eth_pkt_burst_dummy(void *queue __rte_unused, 634a41f593fSFerruh Yigit struct rte_mbuf **pkts __rte_unused, 635a41f593fSFerruh Yigit uint16_t nb_pkts __rte_unused) 636a41f593fSFerruh Yigit { 637a41f593fSFerruh Yigit return 0; 638a41f593fSFerruh Yigit } 639*4b4f810eSFerruh Yigit 640*4b4f810eSFerruh Yigit int 641*4b4f810eSFerruh Yigit rte_eth_representor_id_get(uint16_t port_id, 642*4b4f810eSFerruh Yigit enum rte_eth_representor_type type, 643*4b4f810eSFerruh Yigit int controller, int pf, int representor_port, 644*4b4f810eSFerruh Yigit uint16_t *repr_id) 645*4b4f810eSFerruh Yigit { 646*4b4f810eSFerruh Yigit int ret, n, count; 647*4b4f810eSFerruh Yigit uint32_t i; 648*4b4f810eSFerruh Yigit struct rte_eth_representor_info *info = NULL; 649*4b4f810eSFerruh Yigit size_t size; 650*4b4f810eSFerruh Yigit 651*4b4f810eSFerruh Yigit if (type == RTE_ETH_REPRESENTOR_NONE) 652*4b4f810eSFerruh Yigit return 0; 653*4b4f810eSFerruh Yigit if (repr_id == NULL) 654*4b4f810eSFerruh Yigit return -EINVAL; 655*4b4f810eSFerruh Yigit 656*4b4f810eSFerruh Yigit /* Get PMD representor range info. */ 657*4b4f810eSFerruh Yigit ret = rte_eth_representor_info_get(port_id, NULL); 658*4b4f810eSFerruh Yigit if (ret == -ENOTSUP && type == RTE_ETH_REPRESENTOR_VF && 659*4b4f810eSFerruh Yigit controller == -1 && pf == -1) { 660*4b4f810eSFerruh Yigit /* Direct mapping for legacy VF representor. */ 661*4b4f810eSFerruh Yigit *repr_id = representor_port; 662*4b4f810eSFerruh Yigit return 0; 663*4b4f810eSFerruh Yigit } else if (ret < 0) { 664*4b4f810eSFerruh Yigit return ret; 665*4b4f810eSFerruh Yigit } 666*4b4f810eSFerruh Yigit n = ret; 667*4b4f810eSFerruh Yigit size = sizeof(*info) + n * sizeof(info->ranges[0]); 668*4b4f810eSFerruh Yigit info = calloc(1, size); 669*4b4f810eSFerruh Yigit if (info == NULL) 670*4b4f810eSFerruh Yigit return -ENOMEM; 671*4b4f810eSFerruh Yigit info->nb_ranges_alloc = n; 672*4b4f810eSFerruh Yigit ret = rte_eth_representor_info_get(port_id, info); 673*4b4f810eSFerruh Yigit if (ret < 0) 674*4b4f810eSFerruh Yigit goto out; 675*4b4f810eSFerruh Yigit 676*4b4f810eSFerruh Yigit /* Default controller and pf to caller. */ 677*4b4f810eSFerruh Yigit if (controller == -1) 678*4b4f810eSFerruh Yigit controller = info->controller; 679*4b4f810eSFerruh Yigit if (pf == -1) 680*4b4f810eSFerruh Yigit pf = info->pf; 681*4b4f810eSFerruh Yigit 682*4b4f810eSFerruh Yigit /* Locate representor ID. */ 683*4b4f810eSFerruh Yigit ret = -ENOENT; 684*4b4f810eSFerruh Yigit for (i = 0; i < info->nb_ranges; ++i) { 685*4b4f810eSFerruh Yigit if (info->ranges[i].type != type) 686*4b4f810eSFerruh Yigit continue; 687*4b4f810eSFerruh Yigit if (info->ranges[i].controller != controller) 688*4b4f810eSFerruh Yigit continue; 689*4b4f810eSFerruh Yigit if (info->ranges[i].id_end < info->ranges[i].id_base) { 690*4b4f810eSFerruh Yigit RTE_LOG(WARNING, EAL, "Port %hu invalid representor ID Range %u - %u, entry %d\n", 691*4b4f810eSFerruh Yigit port_id, info->ranges[i].id_base, 692*4b4f810eSFerruh Yigit info->ranges[i].id_end, i); 693*4b4f810eSFerruh Yigit continue; 694*4b4f810eSFerruh Yigit 695*4b4f810eSFerruh Yigit } 696*4b4f810eSFerruh Yigit count = info->ranges[i].id_end - info->ranges[i].id_base + 1; 697*4b4f810eSFerruh Yigit switch (info->ranges[i].type) { 698*4b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_PF: 699*4b4f810eSFerruh Yigit if (pf < info->ranges[i].pf || 700*4b4f810eSFerruh Yigit pf >= info->ranges[i].pf + count) 701*4b4f810eSFerruh Yigit continue; 702*4b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 703*4b4f810eSFerruh Yigit (pf - info->ranges[i].pf); 704*4b4f810eSFerruh Yigit ret = 0; 705*4b4f810eSFerruh Yigit goto out; 706*4b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_VF: 707*4b4f810eSFerruh Yigit if (info->ranges[i].pf != pf) 708*4b4f810eSFerruh Yigit continue; 709*4b4f810eSFerruh Yigit if (representor_port < info->ranges[i].vf || 710*4b4f810eSFerruh Yigit representor_port >= info->ranges[i].vf + count) 711*4b4f810eSFerruh Yigit continue; 712*4b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 713*4b4f810eSFerruh Yigit (representor_port - info->ranges[i].vf); 714*4b4f810eSFerruh Yigit ret = 0; 715*4b4f810eSFerruh Yigit goto out; 716*4b4f810eSFerruh Yigit case RTE_ETH_REPRESENTOR_SF: 717*4b4f810eSFerruh Yigit if (info->ranges[i].pf != pf) 718*4b4f810eSFerruh Yigit continue; 719*4b4f810eSFerruh Yigit if (representor_port < info->ranges[i].sf || 720*4b4f810eSFerruh Yigit representor_port >= info->ranges[i].sf + count) 721*4b4f810eSFerruh Yigit continue; 722*4b4f810eSFerruh Yigit *repr_id = info->ranges[i].id_base + 723*4b4f810eSFerruh Yigit (representor_port - info->ranges[i].sf); 724*4b4f810eSFerruh Yigit ret = 0; 725*4b4f810eSFerruh Yigit goto out; 726*4b4f810eSFerruh Yigit default: 727*4b4f810eSFerruh Yigit break; 728*4b4f810eSFerruh Yigit } 729*4b4f810eSFerruh Yigit } 730*4b4f810eSFerruh Yigit out: 731*4b4f810eSFerruh Yigit free(info); 732*4b4f810eSFerruh Yigit return ret; 733*4b4f810eSFerruh Yigit } 734*4b4f810eSFerruh Yigit 735*4b4f810eSFerruh Yigit int 736*4b4f810eSFerruh Yigit rte_eth_switch_domain_alloc(uint16_t *domain_id) 737*4b4f810eSFerruh Yigit { 738*4b4f810eSFerruh Yigit uint16_t i; 739*4b4f810eSFerruh Yigit 740*4b4f810eSFerruh Yigit *domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 741*4b4f810eSFerruh Yigit 742*4b4f810eSFerruh Yigit for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 743*4b4f810eSFerruh Yigit if (eth_dev_switch_domains[i].state == 744*4b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_UNUSED) { 745*4b4f810eSFerruh Yigit eth_dev_switch_domains[i].state = 746*4b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED; 747*4b4f810eSFerruh Yigit *domain_id = i; 748*4b4f810eSFerruh Yigit return 0; 749*4b4f810eSFerruh Yigit } 750*4b4f810eSFerruh Yigit } 751*4b4f810eSFerruh Yigit 752*4b4f810eSFerruh Yigit return -ENOSPC; 753*4b4f810eSFerruh Yigit } 754*4b4f810eSFerruh Yigit 755*4b4f810eSFerruh Yigit int 756*4b4f810eSFerruh Yigit rte_eth_switch_domain_free(uint16_t domain_id) 757*4b4f810eSFerruh Yigit { 758*4b4f810eSFerruh Yigit if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID || 759*4b4f810eSFerruh Yigit domain_id >= RTE_MAX_ETHPORTS) 760*4b4f810eSFerruh Yigit return -EINVAL; 761*4b4f810eSFerruh Yigit 762*4b4f810eSFerruh Yigit if (eth_dev_switch_domains[domain_id].state != 763*4b4f810eSFerruh Yigit RTE_ETH_SWITCH_DOMAIN_ALLOCATED) 764*4b4f810eSFerruh Yigit return -EINVAL; 765*4b4f810eSFerruh Yigit 766*4b4f810eSFerruh Yigit eth_dev_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED; 767*4b4f810eSFerruh Yigit 768*4b4f810eSFerruh Yigit return 0; 769*4b4f810eSFerruh Yigit } 770*4b4f810eSFerruh Yigit 771