summaryrefslogtreecommitdiffstats
path: root/src/dpdk/drivers/net/mlx5/mlx5_ethdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dpdk/drivers/net/mlx5/mlx5_ethdev.c')
-rw-r--r--src/dpdk/drivers/net/mlx5/mlx5_ethdev.c151
1 files changed, 85 insertions, 66 deletions
diff --git a/src/dpdk/drivers/net/mlx5/mlx5_ethdev.c b/src/dpdk/drivers/net/mlx5/mlx5_ethdev.c
index 85b81360..2145965f 100644
--- a/src/dpdk/drivers/net/mlx5/mlx5_ethdev.c
+++ b/src/dpdk/drivers/net/mlx5/mlx5_ethdev.c
@@ -43,9 +43,11 @@
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/utsname.h>
#include <netinet/in.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
+#include <linux/version.h>
#include <fcntl.h>
/* DPDK headers don't like -pedantic. */
@@ -67,6 +69,57 @@
#include "mlx5_rxtx.h"
#include "mlx5_utils.h"
+/* Add defines in case the running kernel is not the same as user headers. */
+#ifndef ETHTOOL_GLINKSETTINGS
+struct ethtool_link_settings {
+ uint32_t cmd;
+ uint32_t speed;
+ uint8_t duplex;
+ uint8_t port;
+ uint8_t phy_address;
+ uint8_t autoneg;
+ uint8_t mdio_support;
+ uint8_t eth_to_mdix;
+ uint8_t eth_tp_mdix_ctrl;
+ int8_t link_mode_masks_nwords;
+ uint32_t reserved[8];
+ uint32_t link_mode_masks[];
+};
+
+#define ETHTOOL_GLINKSETTINGS 0x0000004c
+#define ETHTOOL_LINK_MODE_1000baseT_Full_BIT 5
+#define ETHTOOL_LINK_MODE_Autoneg_BIT 6
+#define ETHTOOL_LINK_MODE_1000baseKX_Full_BIT 17
+#define ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT 18
+#define ETHTOOL_LINK_MODE_10000baseKR_Full_BIT 19
+#define ETHTOOL_LINK_MODE_10000baseR_FEC_BIT 20
+#define ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT 21
+#define ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT 22
+#define ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT 23
+#define ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT 24
+#define ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT 25
+#define ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT 26
+#define ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT 27
+#define ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT 28
+#define ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT 29
+#define ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT 30
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_25G
+#define ETHTOOL_LINK_MODE_25000baseCR_Full_BIT 31
+#define ETHTOOL_LINK_MODE_25000baseKR_Full_BIT 32
+#define ETHTOOL_LINK_MODE_25000baseSR_Full_BIT 33
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_50G
+#define ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT 34
+#define ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT 35
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_100G
+#define ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT 36
+#define ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT 37
+#define ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT 38
+#define ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT 39
+#endif
+
/**
* Return private structure associated with an Ethernet device.
*
@@ -562,6 +615,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
unsigned int max;
char ifname[IF_NAMESIZE];
+ info->pci_dev = RTE_DEV_TO_PCI(dev->device);
+
priv_lock(priv);
/* FIXME: we should ask the device for these values. */
info->min_rx_bufsize = 32;
@@ -626,7 +681,7 @@ mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
}
/**
- * Retrieve physical link information (unlocked version using legacy ioctl).
+ * DPDK callback to retrieve physical link information.
*
* @param dev
* Pointer to Ethernet device structure.
@@ -644,6 +699,8 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, int wait_to_complete)
struct rte_eth_link dev_link;
int link_speed = 0;
+ /* priv_lock() is not taken to allow concurrent calls. */
+
(void)wait_to_complete;
if (priv_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
@@ -690,8 +747,7 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, int wait_to_complete)
}
/**
- * Retrieve physical link information (unlocked version using new ioctl from
- * Linux 4.5).
+ * Retrieve physical link information (unlocked version using new ioctl).
*
* @param dev
* Pointer to Ethernet device structure.
@@ -701,7 +757,6 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, int wait_to_complete)
static int
mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete)
{
-#ifdef ETHTOOL_GLINKSETTINGS
struct priv *priv = mlx5_get_priv(dev);
struct ethtool_link_settings edata = {
.cmd = ETHTOOL_GLINKSETTINGS,
@@ -728,7 +783,6 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete)
sc = edata.link_mode_masks[0] |
((uint64_t)edata.link_mode_masks[1] << 32);
priv->link_speed_capa = 0;
- /* Link speeds available in kernel v4.5. */
if (sc & ETHTOOL_LINK_MODE_Autoneg_BIT)
priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
if (sc & (ETHTOOL_LINK_MODE_1000baseT_Full_BIT |
@@ -751,25 +805,18 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete)
ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT |
ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT))
priv->link_speed_capa |= ETH_LINK_SPEED_56G;
- /* Link speeds available in kernel v4.6. */
-#ifdef HAVE_ETHTOOL_LINK_MODE_25G
if (sc & (ETHTOOL_LINK_MODE_25000baseCR_Full_BIT |
ETHTOOL_LINK_MODE_25000baseKR_Full_BIT |
ETHTOOL_LINK_MODE_25000baseSR_Full_BIT))
priv->link_speed_capa |= ETH_LINK_SPEED_25G;
-#endif
-#ifdef HAVE_ETHTOOL_LINK_MODE_50G
if (sc & (ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT |
ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT))
priv->link_speed_capa |= ETH_LINK_SPEED_50G;
-#endif
-#ifdef HAVE_ETHTOOL_LINK_MODE_100G
if (sc & (ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT |
ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT |
ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT |
ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT))
priv->link_speed_capa |= ETH_LINK_SPEED_100G;
-#endif
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 &
@@ -779,34 +826,11 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete)
dev->data->dev_link = dev_link;
return 0;
}
-#else
- (void)dev;
- (void)wait_to_complete;
-#endif
/* Link status is still the same. */
return -1;
}
/**
- * DPDK callback to retrieve physical link information (unlocked version).
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param wait_to_complete
- * Wait for request completion (ignored).
- */
-int
-mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
-{
- int ret;
-
- ret = mlx5_link_update_unlocked_gs(dev, wait_to_complete);
- if (ret < 0)
- ret = mlx5_link_update_unlocked_gset(dev, wait_to_complete);
- return ret;
-}
-
-/**
* DPDK callback to retrieve physical link information.
*
* @param dev
@@ -817,13 +841,15 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
int
mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
{
- struct priv *priv = mlx5_get_priv(dev);
- int ret;
-
- priv_lock(priv);
- ret = mlx5_link_update_unlocked(dev, wait_to_complete);
- priv_unlock(priv);
- return ret;
+ struct utsname utsname;
+ int ver[3];
+
+ if (uname(&utsname) == -1 ||
+ sscanf(utsname.release, "%d.%d.%d",
+ &ver[0], &ver[1], &ver[2]) != 3 ||
+ KERNEL_VERSION(ver[0], ver[1], ver[2]) < KERNEL_VERSION(4, 9, 0))
+ return mlx5_link_update_unlocked_gset(dev, wait_to_complete);
+ return mlx5_link_update_unlocked_gs(dev, wait_to_complete);
}
/**
@@ -1141,7 +1167,7 @@ static int
priv_dev_link_status_handler(struct priv *priv, struct rte_eth_dev *dev)
{
struct ibv_async_event event;
- int port_change = 0;
+ struct rte_eth_link *link = &dev->data->dev_link;
int ret = 0;
/* Read all message and acknowledge them. */
@@ -1149,29 +1175,24 @@ priv_dev_link_status_handler(struct priv *priv, struct rte_eth_dev *dev)
if (ibv_get_async_event(priv->ctx, &event))
break;
- if (event.event_type == IBV_EVENT_PORT_ACTIVE ||
- event.event_type == IBV_EVENT_PORT_ERR)
- port_change = 1;
- else
+ if (event.event_type != IBV_EVENT_PORT_ACTIVE &&
+ event.event_type != IBV_EVENT_PORT_ERR)
DEBUG("event type %d on port %d not handled",
event.event_type, event.element.port_num);
ibv_ack_async_event(&event);
}
-
- if (port_change ^ priv->pending_alarm) {
- struct rte_eth_link *link = &dev->data->dev_link;
-
- priv->pending_alarm = 0;
- mlx5_link_update_unlocked(dev, 0);
- if (((link->link_speed == 0) && link->link_status) ||
- ((link->link_speed != 0) && !link->link_status)) {
+ mlx5_link_update(dev, 0);
+ if (((link->link_speed == 0) && link->link_status) ||
+ ((link->link_speed != 0) && !link->link_status)) {
+ if (!priv->pending_alarm) {
/* Inconsistent status, check again later. */
priv->pending_alarm = 1;
rte_eal_alarm_set(MLX5_ALARM_TIMEOUT_US,
mlx5_dev_link_status_handler,
dev);
- } else
- ret = 1;
+ }
+ } else {
+ ret = 1;
}
return ret;
}
@@ -1191,10 +1212,11 @@ mlx5_dev_link_status_handler(void *arg)
priv_lock(priv);
assert(priv->pending_alarm == 1);
+ priv->pending_alarm = 0;
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
- //if (ret)
- // _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+ if (ret)
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
/**
@@ -1216,8 +1238,8 @@ mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
priv_lock(priv);
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
- //if (ret)
- // _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+ if (ret)
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
/**
@@ -1515,14 +1537,11 @@ void
priv_select_tx_function(struct priv *priv)
{
priv->dev->tx_pkt_burst = mlx5_tx_burst;
- /* Display warning for unsupported configurations. */
- if (priv->sriov && priv->mps)
- WARN("multi-packet send WQE cannot be used on a SR-IOV setup");
/* Select appropriate TX function. */
- if ((priv->sriov == 0) && priv->mps && priv->txq_inline) {
+ if (priv->mps && priv->txq_inline) {
priv->dev->tx_pkt_burst = mlx5_tx_burst_mpw_inline;
DEBUG("selected MPW inline TX function");
- } else if ((priv->sriov == 0) && priv->mps) {
+ } else if (priv->mps) {
priv->dev->tx_pkt_burst = mlx5_tx_burst_mpw;
DEBUG("selected MPW TX function");
}