X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_ethdev.c;h=f2b17522cd15b34aa3a2c15a060f8bb0baad2aa5;hb=c345c7d1acf43b4d30e1ecdd5a8cd3402234a6aa;hp=e627909abeb8266b14d6809c7883aa4ec32dd619;hpb=175f1c21d0334e96d959fbe88a614a4bcc1b1e99;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index e627909abe..f2b17522cd 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -389,7 +389,6 @@ mlx5_dev_configure(struct rte_eth_dev *dev) const uint8_t use_app_rss_key = !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; int ret = 0; - unsigned int lro_on = mlx5_lro_on(dev); if (use_app_rss_key && (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len != @@ -432,12 +431,6 @@ mlx5_dev_configure(struct rte_eth_dev *dev) DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u", dev->data->port_id, priv->rxqs_n, rxqs_n); priv->rxqs_n = rxqs_n; - /* - * WHen using LRO, MPRQ is implicitly enabled. - * Adjust threshold value to ensure MPRQ can be enabled. - */ - if (lro_on && priv->config.mprq.min_rxqs_num > priv->rxqs_n) - priv->config.mprq.min_rxqs_num = priv->rxqs_n; /* * If the requested number of RX queues is not a power of two, * use the maximum indirection table size for better balancing. @@ -460,11 +453,6 @@ mlx5_dev_configure(struct rte_eth_dev *dev) j = 0; } } - if (lro_on && priv->config.cqe_comp) { - /* CQE compressing is not supported for LRO CQEs. */ - DRV_LOG(WARNING, "Rx CQE compression isn't supported with LRO"); - priv->config.cqe_comp = 0; - } ret = mlx5_proc_priv_init(dev); if (ret) return ret; @@ -554,7 +542,7 @@ mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) * @param[out] info * Info structure output buffer. */ -void +int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) { struct mlx5_priv *priv = dev->data->dev_private; @@ -577,7 +565,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->max_tx_queues = max; info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES; info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev); - info->rx_offload_capa = (mlx5_get_rx_port_offloads(dev) | + info->rx_offload_capa = (mlx5_get_rx_port_offloads() | info->rx_queue_offload_capa); info->tx_offload_capa = mlx5_get_tx_port_offloads(dev); info->if_index = mlx5_ifindex(dev); @@ -592,16 +580,34 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->switch_info.domain_id = priv->domain_id; info->switch_info.port_id = priv->representor_id; if (priv->representor) { - unsigned int i = mlx5_dev_to_port_id(dev->device, NULL, 0); - uint16_t port_id[i]; + uint16_t port_id; - i = RTE_MIN(mlx5_dev_to_port_id(dev->device, port_id, i), i); - while (i--) { + if (priv->pf_bond >= 0) { + /* + * Switch port ID is opaque value with driver defined + * format. Push the PF index in bonding configurations + * in upper four bits of port ID. If we get too many + * representors (more than 4K) or PFs (more than 15) + * this approach must be reconsidered. + */ + if ((info->switch_info.port_id >> + MLX5_PORT_ID_BONDING_PF_SHIFT) || + priv->pf_bond > MLX5_PORT_ID_BONDING_PF_MASK) { + DRV_LOG(ERR, "can't update switch port ID" + " for bonding device"); + assert(false); + return -ENODEV; + } + info->switch_info.port_id |= + priv->pf_bond << MLX5_PORT_ID_BONDING_PF_SHIFT; + } + MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) { struct mlx5_priv *opriv = - rte_eth_devices[port_id[i]].data->dev_private; + rte_eth_devices[port_id].data->dev_private; if (!opriv || opriv->representor || + opriv->sh != priv->sh || opriv->domain_id != priv->domain_id) continue; /* @@ -612,6 +618,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) break; } } + return 0; } /** @@ -727,11 +734,13 @@ mlx5_find_master_dev(struct rte_eth_dev *dev) priv = dev->data->dev_private; domain_id = priv->domain_id; assert(priv->representor); - RTE_ETH_FOREACH_DEV_OF(port_id, dev->device) { - priv = rte_eth_devices[port_id].data->dev_private; - if (priv && - priv->master && - priv->domain_id == domain_id) + MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) { + struct mlx5_priv *opriv = + rte_eth_devices[port_id].data->dev_private; + if (opriv && + opriv->master && + opriv->domain_id == domain_id && + opriv->sh == priv->sh) return &rte_eth_devices[port_id]; } return NULL; @@ -920,7 +929,8 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, dev->data->port_id, strerror(rte_errno)); return ret; } - dev_link.link_speed = ecmd->speed; + dev_link.link_speed = (ecmd->speed == UINT32_MAX) ? ETH_SPEED_NUM_NONE : + ecmd->speed; sc = ecmd->link_mode_masks[0] | ((uint64_t)ecmd->link_mode_masks[1] << 32); priv->link_speed_capa = 0; @@ -1140,10 +1150,10 @@ mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) } /** - * Get PCI information from struct ibv_device. + * Get PCI information by sysfs device path. * - * @param device - * Pointer to Ethernet device structure. + * @param dev_path + * Pointer to device sysfs folder name. * @param[out] pci_addr * PCI bus address output buffer. * @@ -1151,12 +1161,12 @@ mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_ibv_device_to_pci_addr(const struct ibv_device *device, - struct rte_pci_addr *pci_addr) +mlx5_dev_to_pci_addr(const char *dev_path, + struct rte_pci_addr *pci_addr) { FILE *file; char line[32]; - MKSTR(path, "%s/device/uevent", device->ibdev_path); + MKSTR(path, "%s/device/uevent", dev_path); file = fopen(path, "rb"); if (file == NULL) { @@ -1639,37 +1649,44 @@ mlx5_is_removed(struct rte_eth_dev *dev) } /** - * Get port ID list of mlx5 instances sharing a common device. + * Get the E-Switch parameters by port id. * - * @param[in] dev - * Device to look for. - * @param[out] port_list - * Result buffer for collected port IDs. - * @param port_list_n - * Maximum number of entries in result buffer. If 0, @p port_list can be - * NULL. + * @param[in] port + * Device port id. + * @param[out] es_domain_id + * E-Switch domain id. + * @param[out] es_port_id + * The port id of the port in the E-Switch. * * @return - * Number of matching instances regardless of the @p port_list_n - * parameter, 0 if none were found. + * pointer to device private data structure containing data needed + * on success, NULL otherwise and rte_errno is set. */ -unsigned int -mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list, - unsigned int port_list_n) +struct mlx5_priv * +mlx5_port_to_eswitch_info(uint16_t port) { - uint16_t id; - unsigned int n = 0; + struct rte_eth_dev *dev; + struct mlx5_priv *priv; - RTE_ETH_FOREACH_DEV_OF(id, dev) { - if (n < port_list_n) - port_list[n] = id; - n++; + if (port >= RTE_MAX_ETHPORTS) { + rte_errno = EINVAL; + return NULL; } - return n; + if (!rte_eth_dev_is_valid_port(port)) { + rte_errno = ENODEV; + return NULL; + } + dev = &rte_eth_devices[port]; + priv = dev->data->dev_private; + if (!(priv->representor || priv->master)) { + rte_errno = EINVAL; + return NULL; + } + return priv; } /** - * Get the E-Switch domain id this port belongs to. + * Get the E-Switch parameters by device instance. * * @param[in] port * Device port id. @@ -1679,34 +1696,20 @@ mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list, * The port id of the port in the E-Switch. * * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. + * pointer to device private data structure containing data needed + * on success, NULL otherwise and rte_errno is set. */ -int -mlx5_port_to_eswitch_info(uint16_t port, - uint16_t *es_domain_id, uint16_t *es_port_id) +struct mlx5_priv * +mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev) { - struct rte_eth_dev *dev; struct mlx5_priv *priv; - if (port >= RTE_MAX_ETHPORTS) { - rte_errno = EINVAL; - return -rte_errno; - } - if (!rte_eth_dev_is_valid_port(port)) { - rte_errno = ENODEV; - return -rte_errno; - } - dev = &rte_eth_devices[port]; priv = dev->data->dev_private; if (!(priv->representor || priv->master)) { rte_errno = EINVAL; - return -rte_errno; + return NULL; } - if (es_domain_id) - *es_domain_id = priv->domain_id; - if (es_port_id) - *es_port_id = priv->vport_id; - return 0; + return priv; } /** @@ -1939,3 +1942,89 @@ mlx5_translate_port_name(const char *port_name_in, port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; return; } + +/** + * DPDK callback to retrieve plug-in module EEPROM information (type and size). + * + * @param dev + * Pointer to Ethernet device structure. + * @param[out] modinfo + * Storage for plug-in module EEPROM information. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_get_module_info(struct rte_eth_dev *dev, + struct rte_eth_dev_module_info *modinfo) +{ + struct ethtool_modinfo info = { + .cmd = ETHTOOL_GMODULEINFO, + }; + struct ifreq ifr = (struct ifreq) { + .ifr_data = (void *)&info, + }; + int ret = 0; + + if (!dev || !modinfo) { + DRV_LOG(WARNING, "missing argument, cannot get module info"); + rte_errno = EINVAL; + return -rte_errno; + } + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (ret) { + DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s", + dev->data->port_id, strerror(rte_errno)); + return ret; + } + modinfo->type = info.type; + modinfo->eeprom_len = info.eeprom_len; + return ret; +} + +/** + * DPDK callback to retrieve plug-in module EEPROM data. + * + * @param dev + * Pointer to Ethernet device structure. + * @param[out] info + * Storage for plug-in module EEPROM data. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int mlx5_get_module_eeprom(struct rte_eth_dev *dev, + struct rte_dev_eeprom_info *info) +{ + struct ethtool_eeprom *eeprom; + struct ifreq ifr; + int ret = 0; + + if (!dev || !info) { + DRV_LOG(WARNING, "missing argument, cannot get module eeprom"); + rte_errno = EINVAL; + return -rte_errno; + } + eeprom = rte_calloc(__func__, 1, + (sizeof(struct ethtool_eeprom) + info->length), 0); + if (!eeprom) { + DRV_LOG(WARNING, "port %u cannot allocate memory for " + "eeprom data", dev->data->port_id); + rte_errno = ENOMEM; + return -rte_errno; + } + eeprom->cmd = ETHTOOL_GMODULEEEPROM; + eeprom->offset = info->offset; + eeprom->len = info->length; + ifr = (struct ifreq) { + .ifr_data = (void *)eeprom, + }; + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (ret) + DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s", + dev->data->port_id, strerror(rte_errno)); + else + rte_memcpy(info->data, eeprom->data, info->length); + rte_free(eeprom); + return ret; +}