[dpdk-dev] [PATCH 11/16] mlx4: improve accuracy of link status information

Adrien Mazarguil adrien.mazarguil at 6wind.com
Sat Jun 6 01:15:15 CEST 2015


From: Olga Shern <olgas at mellanox.com>

Query interface properties using the ethtool API instead of Verbs
through ibv_query_port(). The returned information is more accurate for
Ethernet links since several link speeds cannot be mapped to Verbs
semantics.

Signed-off-by: Olga Shern <olgas at mellanox.com>
Signed-off-by: Alex Rosenbaum <Alexr at mellanox.com>
Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
---
 drivers/net/mlx4/mlx4.c | 44 +++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index cc16e8c..f9faeb0 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -264,7 +264,6 @@ struct priv {
 	struct rte_eth_dev *dev; /* Ethernet device. */
 	struct ibv_context *ctx; /* Verbs context. */
 	struct ibv_device_attr device_attr; /* Device properties. */
-	struct ibv_port_attr port_attr; /* Physical port properties. */
 	struct ibv_pd *pd; /* Protection Domain. */
 	/*
 	 * MAC addresses array and configuration bit-field.
@@ -3912,29 +3911,37 @@ static int
 mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 {
 	struct priv *priv = dev->data->dev_private;
-	struct ibv_port_attr port_attr;
-	static const uint8_t width_mult[] = {
-		/* Multiplier values taken from devinfo.c in libibverbs. */
-		0, 1, 4, 0, 8, 0, 0, 0, 12, 0
+	struct ethtool_cmd edata = {
+		.cmd = ETHTOOL_GSET
 	};
+	struct ifreq ifr;
+	struct rte_eth_link dev_link;
+	int link_speed = 0;
 
 	(void)wait_to_complete;
-	errno = ibv_query_port(priv->ctx, priv->port, &port_attr);
-	if (errno) {
-		WARN("port query failed: %s", strerror(errno));
+	if (priv_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
+		WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
 		return -1;
 	}
-	dev->data->dev_link = (struct rte_eth_link){
-		.link_speed = (ibv_rate_to_mbps(mult_to_ibv_rate
-						(port_attr.active_speed)) *
-			       width_mult[(port_attr.active_width %
-					   sizeof(width_mult))]),
-		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = (port_attr.state == IBV_PORT_ACTIVE)
-	};
-	if (memcmp(&port_attr, &priv->port_attr, sizeof(port_attr))) {
+	memset(&dev_link, 0, sizeof(dev_link));
+	dev_link.link_status = ((ifr.ifr_flags & IFF_UP) &&
+				(ifr.ifr_flags & IFF_RUNNING));
+	ifr.ifr_data = &edata;
+	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
+		WARN("ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: %s",
+		     strerror(errno));
+		return -1;
+	}
+	link_speed = ethtool_cmd_speed(&edata);
+	if (link_speed == -1)
+		dev_link.link_speed = 0;
+	else
+		dev_link.link_speed = link_speed;
+	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
+				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
-		priv->port_attr = port_attr;
+		dev->data->dev_link = dev_link;
 		return 0;
 	}
 	/* Link status is still the same. */
@@ -4581,7 +4588,6 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 		priv->ctx = ctx;
 		priv->device_attr = device_attr;
-		priv->port_attr = port_attr;
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-- 
2.1.0



More information about the dev mailing list