X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fethdev%2Frte_ethdev.c;h=1f63201024201b94bdec66555ba7500e93bbd8d6;hb=a75ab6e519431fcd00ba435fdb7de8dac516e081;hp=74de29c2e06bbaf81fc620f83acef9e63c5a78b1;hpb=295968d1740760337e16b0d7914875c5cac52850;p=dpdk.git diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 74de29c2e0..1f63201024 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -171,6 +171,8 @@ static const struct { {RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"}, {RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"}, {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, + {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, + {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, }; /** @@ -757,10 +759,13 @@ rte_eth_dev_owner_delete(const uint64_t owner_id) rte_spinlock_lock(ð_dev_shared_data->ownership_lock); if (eth_is_valid_owner_id(owner_id)) { - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - if (rte_eth_devices[port_id].data->owner.id == owner_id) - memset(&rte_eth_devices[port_id].data->owner, 0, + for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { + struct rte_eth_dev_data *data = + rte_eth_devices[port_id].data; + if (data != NULL && data->owner.id == owner_id) + memset(&data->owner, 0, sizeof(struct rte_eth_dev_owner)); + } RTE_ETHDEV_LOG(NOTICE, "All port owners owned by %016"PRIx64" identifier have removed\n", owner_id); @@ -889,6 +894,17 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) return -ENODEV; } +struct rte_eth_dev * +rte_eth_dev_get_by_name(const char *name) +{ + uint16_t pid; + + if (rte_eth_dev_get_port_by_name(name, &pid)) + return NULL; + + return &rte_eth_devices[pid]; +} + static int eth_err(uint16_t port_id, int ret) { @@ -4017,6 +4033,149 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id, return -ENOTSUP; } +static int +validate_rx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, + struct rte_eth_pfc_queue_conf *pfc_queue_conf) +{ + if ((pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) || + (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { + if (pfc_queue_conf->rx_pause.tx_qid >= dev_info->nb_tx_queues) { + RTE_ETHDEV_LOG(ERR, + "PFC Tx queue not in range for Rx pause requested:%d configured:%d\n", + pfc_queue_conf->rx_pause.tx_qid, + dev_info->nb_tx_queues); + return -EINVAL; + } + + if (pfc_queue_conf->rx_pause.tc >= tc_max) { + RTE_ETHDEV_LOG(ERR, + "PFC TC not in range for Rx pause requested:%d max:%d\n", + pfc_queue_conf->rx_pause.tc, tc_max); + return -EINVAL; + } + } + + return 0; +} + +static int +validate_tx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, + struct rte_eth_pfc_queue_conf *pfc_queue_conf) +{ + if ((pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) || + (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { + if (pfc_queue_conf->tx_pause.rx_qid >= dev_info->nb_rx_queues) { + RTE_ETHDEV_LOG(ERR, + "PFC Rx queue not in range for Tx pause requested:%d configured:%d\n", + pfc_queue_conf->tx_pause.rx_qid, + dev_info->nb_rx_queues); + return -EINVAL; + } + + if (pfc_queue_conf->tx_pause.tc >= tc_max) { + RTE_ETHDEV_LOG(ERR, + "PFC TC not in range for Tx pause requested:%d max:%d\n", + pfc_queue_conf->tx_pause.tc, tc_max); + return -EINVAL; + } + } + + return 0; +} + +int +rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id, + struct rte_eth_pfc_queue_info *pfc_queue_info) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (pfc_queue_info == NULL) { + RTE_ETHDEV_LOG(ERR, "PFC info param is NULL for port (%u)\n", + port_id); + return -EINVAL; + } + + if (*dev->dev_ops->priority_flow_ctrl_queue_info_get) + return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_queue_info_get) + (dev, pfc_queue_info)); + return -ENOTSUP; +} + +int +rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id, + struct rte_eth_pfc_queue_conf *pfc_queue_conf) +{ + struct rte_eth_pfc_queue_info pfc_info; + struct rte_eth_dev_info dev_info; + struct rte_eth_dev *dev; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (pfc_queue_conf == NULL) { + RTE_ETHDEV_LOG(ERR, "PFC parameters are NULL for port (%u)\n", + port_id); + return -EINVAL; + } + + ret = rte_eth_dev_info_get(port_id, &dev_info); + if (ret != 0) + return ret; + + ret = rte_eth_dev_priority_flow_ctrl_queue_info_get(port_id, &pfc_info); + if (ret != 0) + return ret; + + if (pfc_info.tc_max == 0) { + RTE_ETHDEV_LOG(ERR, "Ethdev port %u does not support PFC TC values\n", + port_id); + return -ENOTSUP; + } + + /* Check requested mode supported or not */ + if (pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE && + pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) { + RTE_ETHDEV_LOG(ERR, "PFC Tx pause unsupported for port (%d)\n", + port_id); + return -EINVAL; + } + + if (pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE && + pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) { + RTE_ETHDEV_LOG(ERR, "PFC Rx pause unsupported for port (%d)\n", + port_id); + return -EINVAL; + } + + /* Validate Rx pause parameters */ + if (pfc_info.mode_capa == RTE_ETH_FC_FULL || + pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE) { + ret = validate_rx_pause_config(&dev_info, pfc_info.tc_max, + pfc_queue_conf); + if (ret != 0) + return ret; + } + + /* Validate Tx pause parameters */ + if (pfc_info.mode_capa == RTE_ETH_FC_FULL || + pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE) { + ret = validate_tx_pause_config(&dev_info, pfc_info.tc_max, + pfc_queue_conf); + if (ret != 0) + return ret; + } + + if (*dev->dev_ops->priority_flow_ctrl_queue_config) + return eth_err(port_id, + (*dev->dev_ops->priority_flow_ctrl_queue_config)( + dev, pfc_queue_conf)); + return -ENOTSUP; +} + static int eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) @@ -4819,13 +4978,13 @@ rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data) } intr_handle = dev->intr_handle; - if (!intr_handle->intr_vec) { + if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); return -EPERM; } for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { - vec = intr_handle->intr_vec[qid]; + vec = rte_intr_vec_list_index_get(intr_handle, qid); rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); if (rc && rc != -EEXIST) { RTE_ETHDEV_LOG(ERR, @@ -4860,15 +5019,15 @@ rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id) } intr_handle = dev->intr_handle; - if (!intr_handle->intr_vec) { + if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); return -1; } - vec = intr_handle->intr_vec[queue_id]; + vec = rte_intr_vec_list_index_get(intr_handle, queue_id); efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ? (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec; - fd = intr_handle->efds[efd_idx]; + fd = rte_intr_efds_index_get(intr_handle, efd_idx); return fd; } @@ -5046,12 +5205,12 @@ rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id, } intr_handle = dev->intr_handle; - if (!intr_handle->intr_vec) { + if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); return -EPERM; } - vec = intr_handle->intr_vec[queue_id]; + vec = rte_intr_vec_list_index_get(intr_handle, queue_id); rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); if (rc && rc != -EEXIST) { RTE_ETHDEV_LOG(ERR, @@ -6031,8 +6190,7 @@ rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) } parse_cleanup: - if (args.str) - free(args.str); + free(args.str); return result; } @@ -6315,8 +6473,10 @@ eth_dev_handle_port_info(const char *cmd __rte_unused, return -ENOMEM; txq_state = rte_tel_data_alloc(); - if (!txq_state) + if (!txq_state) { + rte_tel_data_free(rxq_state); return -ENOMEM; + } rte_tel_data_start_dict(d); rte_tel_data_add_dict_string(d, "name", eth_dev->data->name); @@ -6467,6 +6627,102 @@ rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features) (*dev->dev_ops->rx_metadata_negotiate)(dev, features)); } +int +rte_eth_ip_reassembly_capability_get(uint16_t port_id, + struct rte_eth_ip_reassembly_params *reassembly_capa) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (dev->data->dev_configured == 0) { + RTE_ETHDEV_LOG(ERR, + "Device with port_id=%u is not configured.\n" + "Cannot get IP reassembly capability\n", + port_id); + return -EINVAL; + } + + if (reassembly_capa == NULL) { + RTE_ETHDEV_LOG(ERR, "Cannot get reassembly capability to NULL"); + return -EINVAL; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_capability_get, + -ENOTSUP); + memset(reassembly_capa, 0, sizeof(struct rte_eth_ip_reassembly_params)); + + return eth_err(port_id, (*dev->dev_ops->ip_reassembly_capability_get) + (dev, reassembly_capa)); +} + +int +rte_eth_ip_reassembly_conf_get(uint16_t port_id, + struct rte_eth_ip_reassembly_params *conf) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (dev->data->dev_configured == 0) { + RTE_ETHDEV_LOG(ERR, + "Device with port_id=%u is not configured.\n" + "Cannot get IP reassembly configuration\n", + port_id); + return -EINVAL; + } + + if (conf == NULL) { + RTE_ETHDEV_LOG(ERR, "Cannot get reassembly info to NULL"); + return -EINVAL; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_conf_get, + -ENOTSUP); + memset(conf, 0, sizeof(struct rte_eth_ip_reassembly_params)); + return eth_err(port_id, + (*dev->dev_ops->ip_reassembly_conf_get)(dev, conf)); +} + +int +rte_eth_ip_reassembly_conf_set(uint16_t port_id, + const struct rte_eth_ip_reassembly_params *conf) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (dev->data->dev_configured == 0) { + RTE_ETHDEV_LOG(ERR, + "Device with port_id=%u is not configured.\n" + "Cannot set IP reassembly configuration", + port_id); + return -EINVAL; + } + + if (dev->data->dev_started != 0) { + RTE_ETHDEV_LOG(ERR, + "Device with port_id=%u started,\n" + "cannot configure IP reassembly params.\n", + port_id); + return -EINVAL; + } + + if (conf == NULL) { + RTE_ETHDEV_LOG(ERR, + "Invalid IP reassembly configuration (NULL)\n"); + return -EINVAL; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_conf_set, + -ENOTSUP); + return eth_err(port_id, + (*dev->dev_ops->ip_reassembly_conf_set)(dev, conf)); +} + RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); RTE_INIT(ethdev_init_telemetry)