X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_ethdev%2Frte_ethdev.c;h=8ac301608b9c69f1675bcfff2ef03689669cebc1;hb=51781c706f409f28aa1240289b7394dc413ee565;hp=b6859907aab07c1ed6e437f31cc76553d4a95bc0;hpb=c9cce42876f5a45c4fb71eddb328562cf7fe315e;p=dpdk.git diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index b6859907aa..8ac301608b 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -48,7 +48,6 @@ int rte_eth_dev_logtype; static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data"; struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; -static uint16_t eth_dev_last_created_port; /* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER; @@ -187,7 +186,7 @@ enum { STAT_QMAP_RX }; -int __rte_experimental +int rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) { int ret; @@ -288,7 +287,7 @@ error: return ret; } -uint16_t __rte_experimental +uint16_t rte_eth_iterator_next(struct rte_dev_iterator *iter) { if (iter->cls == NULL) /* invalid ethdev iterator */ @@ -317,7 +316,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter) return RTE_MAX_ETHPORTS; } -void __rte_experimental +void rte_eth_iterator_cleanup(struct rte_dev_iterator *iter) { if (iter->bus_str == NULL) @@ -331,8 +330,7 @@ uint16_t rte_eth_find_next(uint16_t port_id) { while (port_id < RTE_MAX_ETHPORTS && - rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED && - rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) + rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED) port_id++; if (port_id >= RTE_MAX_ETHPORTS) @@ -341,6 +339,34 @@ rte_eth_find_next(uint16_t port_id) return port_id; } +/* + * Macro to iterate over all valid ports for internal usage. + * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports. + */ +#define RTE_ETH_FOREACH_VALID_DEV(port_id) \ + for (port_id = rte_eth_find_next(0); \ + port_id < RTE_MAX_ETHPORTS; \ + port_id = rte_eth_find_next(port_id + 1)) + +uint16_t +rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent) +{ + port_id = rte_eth_find_next(port_id); + while (port_id < RTE_MAX_ETHPORTS && + rte_eth_devices[port_id].device != parent) + port_id = rte_eth_find_next(port_id + 1); + + return port_id; +} + +uint16_t +rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id) +{ + RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS); + return rte_eth_find_next_of(port_id, + rte_eth_devices[ref_port_id].device); +} + static void rte_eth_dev_shared_data_prepare(void) { @@ -431,8 +457,6 @@ eth_dev_get(uint16_t port_id) eth_dev->data = &rte_eth_dev_shared_data->data[port_id]; - eth_dev_last_created_port = port_id; - return eth_dev; } @@ -441,6 +465,18 @@ rte_eth_dev_allocate(const char *name) { uint16_t port_id; struct rte_eth_dev *eth_dev = NULL; + size_t name_len; + + name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN); + if (name_len == 0) { + RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n"); + return NULL; + } + + if (name_len >= RTE_ETH_NAME_MAX_LEN) { + RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n"); + return NULL; + } rte_eth_dev_shared_data_prepare(); @@ -462,9 +498,9 @@ rte_eth_dev_allocate(const char *name) } eth_dev = eth_dev_get(port_id); - snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); + strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name)); eth_dev->data->port_id = port_id; - eth_dev->data->mtu = ETHER_MTU; + eth_dev->data->mtu = RTE_ETHER_MTU; unlock: rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); @@ -513,7 +549,9 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) rte_eth_dev_shared_data_prepare(); - _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_DESTROY, NULL); + if (eth_dev->state != RTE_ETH_DEV_UNUSED) + _rte_eth_dev_callback_process(eth_dev, + RTE_ETH_EVENT_DESTROY, NULL); rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); @@ -555,14 +593,10 @@ rte_eth_is_valid_owner_id(uint64_t owner_id) uint64_t rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id) { + port_id = rte_eth_find_next(port_id); while (port_id < RTE_MAX_ETHPORTS && - ((rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED && - rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) || - rte_eth_devices[port_id].data->owner.id != owner_id)) - port_id++; - - if (port_id >= RTE_MAX_ETHPORTS) - return RTE_MAX_ETHPORTS; + rte_eth_devices[port_id].data->owner.id != owner_id) + port_id = rte_eth_find_next(port_id + 1); return port_id; } @@ -586,7 +620,6 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, { struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; struct rte_eth_dev_owner *port_owner; - int sret; if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) { RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n", @@ -610,11 +643,8 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, return -EPERM; } - sret = snprintf(port_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN, "%s", - new_owner->name); - if (sret < 0 || sret >= RTE_ETH_MAX_OWNER_NAME_LEN) - RTE_ETHDEV_LOG(ERR, "Port %u owner name was truncated\n", - port_id); + /* can not truncate (same structure) */ + strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN); port_owner->id = new_owner->id; @@ -739,14 +769,13 @@ rte_eth_dev_count_avail(void) return count; } -uint16_t __rte_experimental +uint16_t rte_eth_dev_count_total(void) { uint16_t port, count = 0; - for (port = 0; port < RTE_MAX_ETHPORTS; port++) - if (rte_eth_devices[port].state != RTE_ETH_DEV_UNUSED) - count++; + RTE_ETH_FOREACH_VALID_DEV(port) + count++; return count; } @@ -780,13 +809,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) return -EINVAL; } - for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { - if (rte_eth_devices[pid].state != RTE_ETH_DEV_UNUSED && - !strcmp(name, rte_eth_dev_shared_data->data[pid].name)) { + RTE_ETH_FOREACH_VALID_DEV(pid) + if (!strcmp(name, rte_eth_dev_shared_data->data[pid].name)) { *port_id = pid; return 0; } - } return -ENODEV; } @@ -1052,7 +1079,7 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex) } } -const char * __rte_experimental +const char * rte_eth_dev_rx_offload_name(uint64_t offload) { const char *name = "UNKNOWN"; @@ -1068,7 +1095,7 @@ rte_eth_dev_rx_offload_name(uint64_t offload) return name; } -const char * __rte_experimental +const char * rte_eth_dev_tx_offload_name(uint64_t offload) { const char *name = "UNKNOWN"; @@ -1090,8 +1117,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, { struct rte_eth_dev *dev; struct rte_eth_dev_info dev_info; - struct rte_eth_conf local_conf = *dev_conf; + struct rte_eth_conf orig_conf; int diag; + int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); @@ -1100,6 +1128,22 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); + if (dev->data->dev_started) { + RTE_ETHDEV_LOG(ERR, + "Port %u must be stopped to allow configuration\n", + port_id); + return -EBUSY; + } + + /* Store original config, as rollback required on failure */ + memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf)); + + /* + * Copy the dev_conf parameter into the dev structure. + * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get + */ + memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf)); + rte_eth_dev_info_get(port_id, &dev_info); /* If number of queues specified by application for both Rx and Tx is @@ -1121,26 +1165,18 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, RTE_ETHDEV_LOG(ERR, "Number of RX queues requested (%u) is greater than max supported(%d)\n", nb_rx_q, RTE_MAX_QUEUES_PER_PORT); - return -EINVAL; + ret = -EINVAL; + goto rollback; } if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) { RTE_ETHDEV_LOG(ERR, "Number of TX queues requested (%u) is greater than max supported(%d)\n", nb_tx_q, RTE_MAX_QUEUES_PER_PORT); - return -EINVAL; - } - - if (dev->data->dev_started) { - RTE_ETHDEV_LOG(ERR, - "Port %u must be stopped to allow configuration\n", - port_id); - return -EBUSY; + ret = -EINVAL; + goto rollback; } - /* Copy the dev_conf parameter into the dev structure */ - memcpy(&dev->data->dev_conf, &local_conf, sizeof(dev->data->dev_conf)); - /* * Check that the numbers of RX and TX queues are not greater * than the maximum number of RX and TX queues supported by the @@ -1149,13 +1185,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, if (nb_rx_q > dev_info.max_rx_queues) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n", port_id, nb_rx_q, dev_info.max_rx_queues); - return -EINVAL; + ret = -EINVAL; + goto rollback; } if (nb_tx_q > dev_info.max_tx_queues) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n", port_id, nb_tx_q, dev_info.max_tx_queues); - return -EINVAL; + ret = -EINVAL; + goto rollback; } /* Check that the device supports requested interrupts */ @@ -1163,61 +1201,67 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) { RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n", dev->device->driver->name); - return -EINVAL; + ret = -EINVAL; + goto rollback; } if ((dev_conf->intr_conf.rmv == 1) && (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) { RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n", dev->device->driver->name); - return -EINVAL; + ret = -EINVAL; + goto rollback; } /* * If jumbo frames are enabled, check that the maximum RX packet * length is supported by the configured device. */ - if (local_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { + if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { if (dev_conf->rxmode.max_rx_pkt_len > dev_info.max_rx_pktlen) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u max_rx_pkt_len %u > max valid value %u\n", port_id, dev_conf->rxmode.max_rx_pkt_len, dev_info.max_rx_pktlen); - return -EINVAL; - } else if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN) { + ret = -EINVAL; + goto rollback; + } else if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u max_rx_pkt_len %u < min valid value %u\n", port_id, dev_conf->rxmode.max_rx_pkt_len, - (unsigned)ETHER_MIN_LEN); - return -EINVAL; + (unsigned int)RTE_ETHER_MIN_LEN); + ret = -EINVAL; + goto rollback; } } else { - if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN || - dev_conf->rxmode.max_rx_pkt_len > ETHER_MAX_LEN) + if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN || + dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN) /* Use default value */ dev->data->dev_conf.rxmode.max_rx_pkt_len = - ETHER_MAX_LEN; + RTE_ETHER_MAX_LEN; } /* Any requested offloading must be within its device capabilities */ - if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) != - local_conf.rxmode.offloads) { + if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) != + dev_conf->rxmode.offloads) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads " "capabilities 0x%"PRIx64" in %s()\n", - port_id, local_conf.rxmode.offloads, + port_id, dev_conf->rxmode.offloads, dev_info.rx_offload_capa, __func__); - return -EINVAL; + ret = -EINVAL; + goto rollback; } - if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) != - local_conf.txmode.offloads) { + if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) != + dev_conf->txmode.offloads) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads " "capabilities 0x%"PRIx64" in %s()\n", - port_id, local_conf.txmode.offloads, + port_id, dev_conf->txmode.offloads, dev_info.tx_offload_capa, __func__); - return -EINVAL; + ret = -EINVAL; + goto rollback; } /* Check that device supports requested rss hash functions. */ @@ -1228,7 +1272,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf, dev_info.flow_type_rss_offloads); - return -EINVAL; + ret = -EINVAL; + goto rollback; } /* @@ -1239,7 +1284,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, RTE_ETHDEV_LOG(ERR, "Port%u rte_eth_dev_rx_queue_config = %d\n", port_id, diag); - return diag; + ret = diag; + goto rollback; } diag = rte_eth_dev_tx_queue_config(dev, nb_tx_q); @@ -1248,7 +1294,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, "Port%u rte_eth_dev_tx_queue_config = %d\n", port_id, diag); rte_eth_dev_rx_queue_config(dev, 0); - return diag; + ret = diag; + goto rollback; } diag = (*dev->dev_ops->dev_configure)(dev); @@ -1257,7 +1304,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, port_id, diag); rte_eth_dev_rx_queue_config(dev, 0); rte_eth_dev_tx_queue_config(dev, 0); - return eth_err(port_id, diag); + ret = eth_err(port_id, diag); + goto rollback; } /* Initialize Rx profiling if enabled at compilation time. */ @@ -1267,10 +1315,16 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, port_id, diag); rte_eth_dev_rx_queue_config(dev, 0); rte_eth_dev_tx_queue_config(dev, 0); - return eth_err(port_id, diag); + ret = eth_err(port_id, diag); + goto rollback; } return 0; + +rollback: + memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); + + return ret; } void @@ -1292,7 +1346,7 @@ static void rte_eth_dev_mac_restore(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { - struct ether_addr *addr; + struct rte_ether_addr *addr; uint16_t i; uint32_t pool = 0; uint64_t pool_mask; @@ -1309,7 +1363,7 @@ rte_eth_dev_mac_restore(struct rte_eth_dev *dev, addr = &dev->data->mac_addrs[i]; /* skip zero address */ - if (is_zero_ether_addr(addr)) + if (rte_is_zero_ether_addr(addr)) continue; pool = 0; @@ -1525,6 +1579,11 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, return -EINVAL; } + if (mp == NULL) { + RTE_ETHDEV_LOG(ERR, "Invalid null mempool pointer\n"); + return -EINVAL; + } + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP); @@ -1565,7 +1624,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) { RTE_ETHDEV_LOG(ERR, - "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, = %hu, and a product of %hu\n", + "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", nb_rx_desc, dev_info.rx_desc_lim.nb_max, dev_info.rx_desc_lim.nb_min, dev_info.rx_desc_lim.nb_align); @@ -1617,7 +1676,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, local_conf.offloads) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be " - "within pre-queue offload capabilities 0x%"PRIx64" in %s()\n", + "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", port_id, rx_queue_id, local_conf.offloads, dev_info.rx_queue_offload_capa, __func__); @@ -1669,7 +1728,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, nb_tx_desc < dev_info.tx_desc_lim.nb_min || nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) { RTE_ETHDEV_LOG(ERR, - "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, = %hu, and a product of %hu\n", + "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", nb_tx_desc, dev_info.tx_desc_lim.nb_max, dev_info.tx_desc_lim.nb_min, dev_info.tx_desc_lim.nb_align); @@ -1721,7 +1780,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, local_conf.offloads) { RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be " - "within pre-queue offload capabilities 0x%"PRIx64" in %s()\n", + "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", port_id, tx_queue_id, local_conf.offloads, dev_info.tx_queue_offload_capa, __func__); @@ -2034,9 +2093,9 @@ rte_eth_basic_stats_get_names(struct rte_eth_dev *dev, uint16_t num_q; for (idx = 0; idx < RTE_NB_STATS; idx++) { - snprintf(xstats_names[cnt_used_entries].name, - sizeof(xstats_names[0].name), - "%s", rte_stats_strings[idx].name); + strlcpy(xstats_names[cnt_used_entries].name, + rte_stats_strings[idx].name, + sizeof(xstats_names[0].name)); cnt_used_entries++; } num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); @@ -2489,6 +2548,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) .nb_max = UINT16_MAX, .nb_min = 0, .nb_align = 1, + .nb_seg_max = UINT16_MAX, + .nb_mtu_seg_max = UINT16_MAX, }; RTE_ETH_VALID_PORTID_OR_RET(port_id); @@ -2498,6 +2559,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) dev_info->rx_desc_lim = lim; dev_info->tx_desc_lim = lim; dev_info->device = dev->device; + dev_info->min_mtu = RTE_ETHER_MIN_MTU; + dev_info->max_mtu = UINT16_MAX; RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); (*dev->dev_ops->dev_infos_get)(dev, dev_info); @@ -2535,13 +2598,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask, } void -rte_eth_macaddr_get(uint16_t port_id, struct ether_addr *mac_addr) +rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr) { struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_RET(port_id); dev = &rte_eth_devices[port_id]; - ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); + rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); } @@ -2561,12 +2624,25 @@ int rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu) { int ret; + struct rte_eth_dev_info dev_info; struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP); + /* + * Check if the device supports dev_infos_get, if it does not + * skip min_mtu/max_mtu validation here as this requires values + * that are populated within the call to rte_eth_dev_info_get() + * which relies on dev->dev_ops->dev_infos_get. + */ + if (*dev->dev_ops->dev_infos_get != NULL) { + rte_eth_dev_info_get(port_id, &dev_info); + if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu) + return -EINVAL; + } + ret = (*dev->dev_ops->mtu_set)(dev, mtu); if (!ret) dev->data->mtu = mtu; @@ -3009,7 +3085,7 @@ rte_eth_led_off(uint16_t port_id) * an empty spot. */ static int -get_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) +get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr) { struct rte_eth_dev_info dev_info; struct rte_eth_dev *dev = &rte_eth_devices[port_id]; @@ -3019,16 +3095,17 @@ get_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) rte_eth_dev_info_get(port_id, &dev_info); for (i = 0; i < dev_info.max_mac_addrs; i++) - if (memcmp(addr, &dev->data->mac_addrs[i], ETHER_ADDR_LEN) == 0) + if (memcmp(addr, &dev->data->mac_addrs[i], + RTE_ETHER_ADDR_LEN) == 0) return i; return -1; } -static const struct ether_addr null_mac_addr; +static const struct rte_ether_addr null_mac_addr; int -rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr, +rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, uint32_t pool) { struct rte_eth_dev *dev; @@ -3040,7 +3117,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr, dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP); - if (is_zero_ether_addr(addr)) { + if (rte_is_zero_ether_addr(addr)) { RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", port_id); return -EINVAL; @@ -3071,7 +3148,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr, if (ret == 0) { /* Update address in NIC data structure */ - ether_addr_copy(addr, &dev->data->mac_addrs[index]); + rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); /* Update pool bitmap in NIC data structure */ dev->data->mac_pool_sel[index] |= (1ULL << pool); @@ -3081,7 +3158,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr, } int -rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr) +rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) { struct rte_eth_dev *dev; int index; @@ -3103,7 +3180,7 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr) (*dev->dev_ops->mac_addr_remove)(dev, index); /* Update address in NIC data structure */ - ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); + rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); /* reset pool bitmap */ dev->data->mac_pool_sel[index] = 0; @@ -3112,14 +3189,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr) } int -rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr) +rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { struct rte_eth_dev *dev; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); - if (!is_valid_assigned_ether_addr(addr)) + if (!rte_is_valid_assigned_ether_addr(addr)) return -EINVAL; dev = &rte_eth_devices[port_id]; @@ -3130,7 +3207,7 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr) return ret; /* Update default address in NIC data structure */ - ether_addr_copy(addr, &dev->data->mac_addrs[0]); + rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; } @@ -3141,7 +3218,7 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr) * an empty spot. */ static int -get_hash_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) +get_hash_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr) { struct rte_eth_dev_info dev_info; struct rte_eth_dev *dev = &rte_eth_devices[port_id]; @@ -3153,14 +3230,14 @@ get_hash_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) for (i = 0; i < dev_info.max_hash_mac_addrs; i++) if (memcmp(addr, &dev->data->hash_mac_addrs[i], - ETHER_ADDR_LEN) == 0) + RTE_ETHER_ADDR_LEN) == 0) return i; return -1; } int -rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr, +rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr, uint8_t on) { int index; @@ -3170,7 +3247,7 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr, RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); dev = &rte_eth_devices[port_id]; - if (is_zero_ether_addr(addr)) { + if (rte_is_zero_ether_addr(addr)) { RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", port_id); return -EINVAL; @@ -3202,10 +3279,10 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr, if (ret == 0) { /* Update address in NIC data structure */ if (on) - ether_addr_copy(addr, + rte_ether_addr_copy(addr, &dev->data->hash_mac_addrs[index]); else - ether_addr_copy(&null_mac_addr, + rte_ether_addr_copy(&null_mac_addr, &dev->data->hash_mac_addrs[index]); } @@ -3559,9 +3636,15 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, { char z_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; + int rc; - snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", - dev->data->port_id, queue_id, ring_name); + rc = snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", + dev->data->port_id, queue_id, ring_name); + if (rc >= RTE_MEMZONE_NAMESIZE) { + RTE_ETHDEV_LOG(ERR, "ring name too long\n"); + rte_errno = ENAMETOOLONG; + return NULL; + } mz = rte_memzone_lookup(z_name); if (mz) @@ -3645,11 +3728,10 @@ rte_eth_dev_destroy(struct rte_eth_dev *ethdev, return -ENODEV; RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL); - if (ethdev_uninit) { - ret = ethdev_uninit(ethdev); - if (ret) - return ret; - } + + ret = ethdev_uninit(ethdev); + if (ret) + return ret; return rte_eth_dev_release_port(ethdev); } @@ -3992,7 +4074,7 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, int rte_eth_dev_set_mc_addr_list(uint16_t port_id, - struct ether_addr *mc_addr_set, + struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr) { struct rte_eth_dev *dev; @@ -4096,6 +4178,18 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) timestamp)); } +int +rte_eth_read_clock(uint16_t port_id, uint64_t *clock) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP); + return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock)); +} + int rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) { @@ -4309,7 +4403,7 @@ enum rte_eth_switch_domain_state { * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than * ethdev ports in a single process. */ -struct rte_eth_dev_switch { +static struct rte_eth_dev_switch { enum rte_eth_switch_domain_state state; } rte_eth_switch_domains[RTE_MAX_ETHPORTS]; @@ -4350,8 +4444,6 @@ rte_eth_switch_domain_free(uint16_t domain_id) return 0; } -typedef int (*rte_eth_devargs_callback_t)(char *str, void *data); - static int rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) { @@ -4416,89 +4508,6 @@ rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) } } -static int -rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback, - void *data) -{ - char *str_start; - int state; - int result; - - if (*str != '[') - /* Single element, not a list */ - return callback(str, data); - - /* Sanity check, then strip the brackets */ - str_start = &str[strlen(str) - 1]; - if (*str_start != ']') { - RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str); - return -EINVAL; - } - str++; - *str_start = '\0'; - - /* Process list elements */ - state = 0; - while (1) { - if (state == 0) { - if (*str == '\0') - break; - if (*str != ',') { - str_start = str; - state = 1; - } - } else if (state == 1) { - if (*str == ',' || *str == '\0') { - if (str > str_start) { - /* Non-empty string fragment */ - *str = '\0'; - result = callback(str_start, data); - if (result < 0) - return result; - } - state = 0; - } - } - str++; - } - return 0; -} - -static int -rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list, - const uint16_t max_list) -{ - uint16_t lo, hi, val; - int result; - - result = sscanf(str, "%hu-%hu", &lo, &hi); - if (result == 1) { - if (*len_list >= max_list) - return -ENOMEM; - list[(*len_list)++] = lo; - } else if (result == 2) { - if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS) - return -EINVAL; - for (val = lo; val <= hi; val++) { - if (*len_list >= max_list) - return -ENOMEM; - list[(*len_list)++] = val; - } - } else - return -EINVAL; - return 0; -} - - -static int -rte_eth_devargs_parse_representor_ports(char *str, void *data) -{ - struct rte_eth_devargs *eth_da = data; - - return rte_eth_devargs_process_range(str, eth_da->representor_ports, - ð_da->nb_representor_ports, RTE_MAX_ETHPORTS); -} - int __rte_experimental rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) {