-static int
-mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct ethtool_cmd edata = {
- .cmd = ETHTOOL_GSET /* Deprecated since Linux v4.5. */
- };
- struct ifreq ifr;
- struct rte_eth_link dev_link;
- int link_speed = 0;
- int ret;
-
- ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link = (struct rte_eth_link) {
- .link_status = ((ifr.ifr_flags & IFF_UP) &&
- (ifr.ifr_flags & IFF_RUNNING)),
- };
- ifr = (struct ifreq) {
- .ifr_data = (void *)&edata,
- };
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- if (ret == -ENOTSUP && priv->representor) {
- struct rte_eth_dev *master;
-
- /*
- * For representors we can try to inherit link
- * settings from the master device. Actually
- * link settings do not make a lot of sense
- * for representors due to missing physical
- * link. The old kernel drivers supported
- * emulated settings query for representors,
- * the new ones do not, so we have to add
- * this code for compatibility issues.
- */
- master = mlx5_find_master_dev(dev);
- if (master) {
- ifr = (struct ifreq) {
- .ifr_data = (void *)&edata,
- };
- ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
- }
- }
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL,"
- " ETHTOOL_GSET) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- }
- link_speed = ethtool_cmd_speed(&edata);
- if (link_speed == -1)
- dev_link.link_speed = ETH_SPEED_NUM_NONE;
- else
- dev_link.link_speed = link_speed;
- priv->link_speed_capa = 0;
- if (edata.supported & SUPPORTED_Autoneg)
- priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
- if (edata.supported & (SUPPORTED_1000baseT_Full |
- SUPPORTED_1000baseKX_Full))
- priv->link_speed_capa |= ETH_LINK_SPEED_1G;
- if (edata.supported & SUPPORTED_10000baseKR_Full)
- priv->link_speed_capa |= ETH_LINK_SPEED_10G;
- if (edata.supported & (SUPPORTED_40000baseKR4_Full |
- SUPPORTED_40000baseCR4_Full |
- SUPPORTED_40000baseSR4_Full |
- SUPPORTED_40000baseLR4_Full))
- priv->link_speed_capa |= ETH_LINK_SPEED_40G;
- dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
- ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_FIXED);
- if (((dev_link.link_speed && !dev_link.link_status) ||
- (!dev_link.link_speed && dev_link.link_status))) {
- rte_errno = EAGAIN;
- return -rte_errno;
- }
- *link = dev_link;
- return 0;
-}
-
-/**
- * Retrieve physical link information (unlocked version using new ioctl).
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] link
- * Storage for current link status.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
-
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct ethtool_link_settings gcmd = { .cmd = ETHTOOL_GLINKSETTINGS };
- struct ifreq ifr;
- struct rte_eth_link dev_link;
- struct rte_eth_dev *master = NULL;
- uint64_t sc;
- int ret;
-
- ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link = (struct rte_eth_link) {
- .link_status = ((ifr.ifr_flags & IFF_UP) &&
- (ifr.ifr_flags & IFF_RUNNING)),
- };
- ifr = (struct ifreq) {
- .ifr_data = (void *)&gcmd,
- };
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- if (ret == -ENOTSUP && priv->representor) {
- /*
- * For representors we can try to inherit link
- * settings from the master device. Actually
- * link settings do not make a lot of sense
- * for representors due to missing physical
- * link. The old kernel drivers supported
- * emulated settings query for representors,
- * the new ones do not, so we have to add
- * this code for compatibility issues.
- */
- master = mlx5_find_master_dev(dev);
- if (master) {
- ifr = (struct ifreq) {
- .ifr_data = (void *)&gcmd,
- };
- ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
- }
- }
- if (ret) {
- DRV_LOG(DEBUG,
- "port %u ioctl(SIOCETHTOOL,"
- " ETHTOOL_GLINKSETTINGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
-
- }
- gcmd.link_mode_masks_nwords = -gcmd.link_mode_masks_nwords;
-
- alignas(struct ethtool_link_settings)
- uint8_t data[offsetof(struct ethtool_link_settings, link_mode_masks) +
- sizeof(uint32_t) * gcmd.link_mode_masks_nwords * 3];
- struct ethtool_link_settings *ecmd = (void *)data;
-
- *ecmd = gcmd;
- ifr.ifr_data = (void *)ecmd;
- ret = mlx5_ifreq(master ? master : dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(DEBUG,
- "port %u ioctl(SIOCETHTOOL,"
- "ETHTOOL_GLINKSETTINGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link.link_speed = ecmd->speed;
- sc = ecmd->link_mode_masks[0] |
- ((uint64_t)ecmd->link_mode_masks[1] << 32);
- priv->link_speed_capa = 0;
- if (sc & MLX5_BITSHIFT(ETHTOOL_LINK_MODE_Autoneg_BIT))
- priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_1G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_10G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_20G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_40G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_56G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_25G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_50G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_100G;
- dev_link.link_duplex = ((ecmd->duplex == DUPLEX_HALF) ?
- ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_FIXED);
- if (((dev_link.link_speed && !dev_link.link_status) ||
- (!dev_link.link_speed && dev_link.link_status))) {
- rte_errno = EAGAIN;
- return -rte_errno;
- }
- *link = dev_link;
- return 0;
-}
-
-/**
- * DPDK callback to retrieve physical link information.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param wait_to_complete
- * Wait for request completion.
- *
- * @return
- * 0 if link status was not updated, positive if it was, a negative errno
- * value otherwise and rte_errno is set.
- */
-int
-mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
-{
- int ret;
- struct rte_eth_link dev_link;
- time_t start_time = time(NULL);
-
- do {
- ret = mlx5_link_update_unlocked_gs(dev, &dev_link);
- if (ret)
- ret = mlx5_link_update_unlocked_gset(dev, &dev_link);
- if (ret == 0)
- break;
- /* Handle wait to complete situation. */
- if (wait_to_complete && ret == -EAGAIN) {
- if (abs((int)difftime(time(NULL), start_time)) <
- MLX5_LINK_STATUS_TIMEOUT) {
- usleep(0);
- continue;
- } else {
- rte_errno = EBUSY;
- return -rte_errno;
- }
- } else if (ret < 0) {
- return ret;
- }
- } while (wait_to_complete);
- ret = !!memcmp(&dev->data->dev_link, &dev_link,
- sizeof(struct rte_eth_link));
- dev->data->dev_link = dev_link;
- return ret;
-}
-
-/**
- * DPDK callback to change the MTU.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param in_mtu
- * New MTU.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- uint16_t kern_mtu = 0;
- int ret;
-
- ret = mlx5_get_mtu(dev, &kern_mtu);
- if (ret)
- return ret;
- /* Set kernel interface MTU first. */
- ret = mlx5_set_mtu(dev, mtu);
- if (ret)
- return ret;
- ret = mlx5_get_mtu(dev, &kern_mtu);
- if (ret)
- return ret;
- if (kern_mtu == mtu) {
- priv->mtu = mtu;
- DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
- dev->data->port_id, mtu);
- return 0;
- }
- rte_errno = EAGAIN;
- return -rte_errno;
-}
-
-/**
- * DPDK callback to get flow control status.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] fc_conf
- * Flow control output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
-{
- struct ifreq ifr;
- struct ethtool_pauseparam ethpause = {
- .cmd = ETHTOOL_GPAUSEPARAM
- };
- int ret;
-
- ifr.ifr_data = (void *)ðpause;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM) failed:"
- " %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- fc_conf->autoneg = ethpause.autoneg;
- if (ethpause.rx_pause && ethpause.tx_pause)
- fc_conf->mode = RTE_FC_FULL;
- else if (ethpause.rx_pause)
- fc_conf->mode = RTE_FC_RX_PAUSE;
- else if (ethpause.tx_pause)
- fc_conf->mode = RTE_FC_TX_PAUSE;
- else
- fc_conf->mode = RTE_FC_NONE;
- return 0;
-}
-
-/**
- * DPDK callback to modify flow control parameters.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[in] fc_conf
- * Flow control parameters.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
-{
- struct ifreq ifr;
- struct ethtool_pauseparam ethpause = {
- .cmd = ETHTOOL_SPAUSEPARAM
- };
- int ret;
-
- ifr.ifr_data = (void *)ðpause;
- ethpause.autoneg = fc_conf->autoneg;
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_RX_PAUSE))
- ethpause.rx_pause = 1;
- else
- ethpause.rx_pause = 0;
-
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_TX_PAUSE))
- ethpause.tx_pause = 1;
- else
- ethpause.tx_pause = 0;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
- " failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- return 0;
-}
-
-/**
- * Get PCI information from struct ibv_device.
- *
- * @param device
- * Pointer to Ethernet device structure.
- * @param[out] pci_addr
- * PCI bus address output buffer.
- *
- * @return
- * 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)
-{
- FILE *file;
- char line[32];
- MKSTR(path, "%s/device/uevent", device->ibdev_path);
-
- file = fopen(path, "rb");
- if (file == NULL) {
- rte_errno = errno;
- return -rte_errno;
- }
- while (fgets(line, sizeof(line), file) == line) {
- size_t len = strlen(line);
- int ret;
-
- /* Truncate long lines. */
- if (len == (sizeof(line) - 1))
- while (line[(len - 1)] != '\n') {
- ret = fgetc(file);
- if (ret == EOF)
- break;
- line[(len - 1)] = ret;
- }
- /* Extract information. */
- if (sscanf(line,
- "PCI_SLOT_NAME="
- "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n",
- &pci_addr->domain,
- &pci_addr->bus,
- &pci_addr->devid,
- &pci_addr->function) == 4) {
- ret = 0;
- break;
- }
- }
- fclose(file);
- return 0;
-}
-
-/**
- * Handle asynchronous removal event for entire multiport device.
- *
- * @param sh
- * Infiniband device shared context.
- */
-static void
-mlx5_dev_interrupt_device_fatal(struct mlx5_ibv_shared *sh)
-{
- uint32_t i;
-
- for (i = 0; i < sh->max_port; ++i) {
- struct rte_eth_dev *dev;
-
- if (sh->port[i].ih_port_id >= RTE_MAX_ETHPORTS) {
- /*
- * Or not existing port either no
- * handler installed for this port.
- */
- continue;
- }
- dev = &rte_eth_devices[sh->port[i].ih_port_id];
- assert(dev);
- if (dev->data->dev_conf.intr_conf.rmv)
- _rte_eth_dev_callback_process
- (dev, RTE_ETH_EVENT_INTR_RMV, NULL);
- }
-}
-
-/**
- * Handle shared asynchronous events the NIC (removal event
- * and link status change). Supports multiport IB device.
- *
- * @param cb_arg
- * Callback argument.
- */
-void
-mlx5_dev_interrupt_handler(void *cb_arg)
-{
- struct mlx5_ibv_shared *sh = cb_arg;
- struct ibv_async_event event;
-
- /* Read all message from the IB device and acknowledge them. */
- for (;;) {
- struct rte_eth_dev *dev;
- uint32_t tmp;
-
- if (mlx5_glue->get_async_event(sh->ctx, &event))
- break;
- /* Retrieve and check IB port index. */
- tmp = (uint32_t)event.element.port_num;
- if (!tmp && event.event_type == IBV_EVENT_DEVICE_FATAL) {
- /*
- * The DEVICE_FATAL event is called once for
- * entire device without port specifying.
- * We should notify all existing ports.
- */
- mlx5_glue->ack_async_event(&event);
- mlx5_dev_interrupt_device_fatal(sh);
- continue;
- }
- assert(tmp && (tmp <= sh->max_port));
- if (!tmp) {
- /* Unsupported devive level event. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "unsupported common event (type %d)",
- event.event_type);
- continue;
- }
- if (tmp > sh->max_port) {
- /* Invalid IB port index. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "cannot handle an event (type %d)"
- "due to invalid IB port index (%u)",
- event.event_type, tmp);
- continue;
- }
- if (sh->port[tmp - 1].ih_port_id >= RTE_MAX_ETHPORTS) {
- /* No handler installed. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "cannot handle an event (type %d)"
- "due to no handler installed for port %u",
- event.event_type, tmp);
- continue;
- }
- /* Retrieve ethernet device descriptor. */
- tmp = sh->port[tmp - 1].ih_port_id;
- dev = &rte_eth_devices[tmp];
- assert(dev);
- if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
- event.event_type == IBV_EVENT_PORT_ERR) &&
- dev->data->dev_conf.intr_conf.lsc) {
- mlx5_glue->ack_async_event(&event);
- if (mlx5_link_update(dev, 0) == -EAGAIN) {
- usleep(0);
- continue;
- }
- _rte_eth_dev_callback_process
- (dev, RTE_ETH_EVENT_INTR_LSC, NULL);
- continue;
- }
- DRV_LOG(DEBUG,
- "port %u cannot handle an unknown event (type %d)",
- dev->data->port_id, event.event_type);
- mlx5_glue->ack_async_event(&event);
- }
-}
-
-/**
- * Uninstall shared asynchronous device events handler.
- * This function is implemeted to support event sharing
- * between multiple ports of single IB device.
- *
- * @param dev
- * Pointer to Ethernet device.
- */
-static void
-mlx5_dev_shared_handler_uninstall(struct rte_eth_dev *dev)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_ibv_shared *sh = priv->sh;
-
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return;
- pthread_mutex_lock(&sh->intr_mutex);
- assert(priv->ibv_port);
- assert(priv->ibv_port <= sh->max_port);
- assert(dev->data->port_id < RTE_MAX_ETHPORTS);
- if (sh->port[priv->ibv_port - 1].ih_port_id >= RTE_MAX_ETHPORTS)
- goto exit;
- assert(sh->port[priv->ibv_port - 1].ih_port_id ==
- (uint32_t)dev->data->port_id);
- assert(sh->intr_cnt);
- sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS;
- if (!sh->intr_cnt || --sh->intr_cnt)
- goto exit;
- rte_intr_callback_unregister(&sh->intr_handle,
- mlx5_dev_interrupt_handler, sh);
- sh->intr_handle.fd = 0;
- sh->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-exit:
- pthread_mutex_unlock(&sh->intr_mutex);
-}
-
-/**
- * Install shared asyncronous device events handler.
- * This function is implemeted to support event sharing
- * between multiple ports of single IB device.
- *
- * @param dev
- * Pointer to Ethernet device.
- */
-static void
-mlx5_dev_shared_handler_install(struct rte_eth_dev *dev)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_ibv_shared *sh = priv->sh;
- int ret;
- int flags;
-
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return;
- pthread_mutex_lock(&sh->intr_mutex);
- assert(priv->ibv_port);
- assert(priv->ibv_port <= sh->max_port);
- assert(dev->data->port_id < RTE_MAX_ETHPORTS);
- if (sh->port[priv->ibv_port - 1].ih_port_id < RTE_MAX_ETHPORTS) {
- /* The handler is already installed for this port. */
- assert(sh->intr_cnt);
- goto exit;
- }
- sh->port[priv->ibv_port - 1].ih_port_id = (uint32_t)dev->data->port_id;
- if (sh->intr_cnt) {
- sh->intr_cnt++;
- goto exit;
- }
- /* No shared handler installed. */
- assert(sh->ctx->async_fd > 0);
- flags = fcntl(sh->ctx->async_fd, F_GETFL);
- ret = fcntl(sh->ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
- if (ret) {
- DRV_LOG(INFO, "failed to change file descriptor"
- " async event queue");
- /* Indicate there will be no interrupts. */
- dev->data->dev_conf.intr_conf.lsc = 0;
- dev->data->dev_conf.intr_conf.rmv = 0;
- sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS;
- goto exit;
- }
- sh->intr_handle.fd = sh->ctx->async_fd;
- sh->intr_handle.type = RTE_INTR_HANDLE_EXT;
- rte_intr_callback_register(&sh->intr_handle,
- mlx5_dev_interrupt_handler, sh);
- sh->intr_cnt++;
-exit:
- pthread_mutex_unlock(&sh->intr_mutex);
-}
-
-/**
- * Uninstall interrupt handler.
- *
- * @param dev
- * Pointer to Ethernet device.
- */
-void
-mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev)
-{
- mlx5_dev_shared_handler_uninstall(dev);
-}
-
-/**
- * Install interrupt handler.
- *
- * @param dev
- * Pointer to Ethernet device.
- */
-void
-mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev)
-{
- mlx5_dev_shared_handler_install(dev);
-}
-
-/**
- * DPDK callback to bring the link DOWN.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_set_link_down(struct rte_eth_dev *dev)
-{
- return mlx5_set_flags(dev, ~IFF_UP, ~IFF_UP);
-}
-
-/**
- * DPDK callback to bring the link UP.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_set_link_up(struct rte_eth_dev *dev)
-{
- return mlx5_set_flags(dev, ~IFF_UP, IFF_UP);
-}
-
-/**
- * Configure the TX function to use.
- *
- * @param dev
- * Pointer to private data structure.
- *
- * @return
- * Pointer to selected Tx burst function.
- */
-eth_tx_burst_t
-mlx5_select_tx_function(struct rte_eth_dev *dev)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- eth_tx_burst_t tx_pkt_burst = mlx5_tx_burst;
- struct mlx5_dev_config *config = &priv->config;
- uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
- int tso = !!(tx_offloads & (DEV_TX_OFFLOAD_TCP_TSO |
- DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
- DEV_TX_OFFLOAD_GRE_TNL_TSO |
- DEV_TX_OFFLOAD_IP_TNL_TSO |
- DEV_TX_OFFLOAD_UDP_TNL_TSO));
- int swp = !!(tx_offloads & (DEV_TX_OFFLOAD_IP_TNL_TSO |
- DEV_TX_OFFLOAD_UDP_TNL_TSO |
- DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM));
- int vlan_insert = !!(tx_offloads & DEV_TX_OFFLOAD_VLAN_INSERT);
-
- assert(priv != NULL);
- /* Select appropriate TX function. */
- if (vlan_insert || tso || swp)
- return tx_pkt_burst;
- if (config->mps == MLX5_MPW_ENHANCED) {
- if (mlx5_check_vec_tx_support(dev) > 0) {
- if (mlx5_check_raw_vec_tx_support(dev) > 0)
- tx_pkt_burst = mlx5_tx_burst_raw_vec;
- else
- tx_pkt_burst = mlx5_tx_burst_vec;
- DRV_LOG(DEBUG,
- "port %u selected enhanced MPW Tx vectorized"
- " function",
- dev->data->port_id);
- } else {
- tx_pkt_burst = mlx5_tx_burst_empw;
- DRV_LOG(DEBUG,
- "port %u selected enhanced MPW Tx function",
- dev->data->port_id);
- }
- } else if (config->mps && (config->txq_inline > 0)) {
- tx_pkt_burst = mlx5_tx_burst_mpw_inline;
- DRV_LOG(DEBUG, "port %u selected MPW inline Tx function",
- dev->data->port_id);
- } else if (config->mps) {
- tx_pkt_burst = mlx5_tx_burst_mpw;
- DRV_LOG(DEBUG, "port %u selected MPW Tx function",
- dev->data->port_id);
- }
- return tx_pkt_burst;
-}
-
-/**
- * Configure the RX function to use.
- *
- * @param dev
- * Pointer to private data structure.
- *
- * @return
- * Pointer to selected Rx burst function.
- */
-eth_rx_burst_t
-mlx5_select_rx_function(struct rte_eth_dev *dev)