[dpdk-stable] [PATCH] net/bnx2x: fix to set device link status

Rasesh Mody rasesh.mody at cavium.com
Wed Aug 22 20:56:54 CEST 2018


As rte_eth_linkstatus_set() is not available in DPDK 17.11.x,
add/use APIs to get/set the device link status. This fixes the
compilation error originally reported.

In 17.11.x, testpmd doesn't call link_update() as part "port stop
all". Add an explicit call in dev_stop(). Without this change, on
"port stop all" command, peer correctly reflects the link status as
down, however, the testpmd incorrectly reports the link status as up
with "show port info all".

Fixes: 5bc1ab14417b ("net/bnx2x: fix poll link status")

Reported-by: Marco Varlese <mvarlese at suse.de>
Signed-off-by: Rasesh Mody <rasesh.mody at cavium.com>
---
 drivers/net/bnx2x/bnx2x.c        |    2 +-
 drivers/net/bnx2x/bnx2x_ethdev.c |  117 +++++++++++++++++++++++++++++---------
 2 files changed, 91 insertions(+), 28 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index 01035fb..e58684d 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -7062,7 +7062,7 @@ void bnx2x_periodic_callout(struct bnx2x_softc *sc)
 {
 	if ((sc->state != BNX2X_STATE_OPEN) ||
 	    (atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_STOP)) {
-		PMD_DRV_LOG(WARNING, "periodic callout exit (state=0x%x)",
+		PMD_DRV_LOG(INFO, "periodic callout exit (state=0x%x)",
 			    sc->state);
 		return;
 	}
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index d3f2efb..a2eb538 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -14,6 +14,7 @@
 #include <rte_dev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_alarm.h>
+#include <rte_atomic.h>
 
 /*
  * The set of PCI devices this driver supports
@@ -79,16 +80,71 @@ struct rte_bnx2x_xstats_name_off {
 		offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
 };
 
+/**
+ * Atomically reads the link status information from global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+				  struct rte_eth_link *link)
+{
+	struct rte_eth_link *dst = link;
+	struct rte_eth_link *src = &(dev->data->dev_link);
+
+	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+					*(uint64_t *)src) == 0)
+		return -1;
+
+	return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+				   struct rte_eth_link *link)
+{
+	struct rte_eth_link *dst = &(dev->data->dev_link);
+	struct rte_eth_link *src = link;
+
+	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+					*(uint64_t *)src) == 0)
+		return -1;
+
+	return 0;
+}
+
 static int
 bnx2x_link_update(struct rte_eth_dev *dev)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
+	struct rte_eth_link orig;
 	struct rte_eth_link link;
 
 	PMD_INIT_FUNC_TRACE();
 
 	bnx2x_link_status_update(sc);
+	memset(&orig, 0, sizeof(orig));
 	memset(&link, 0, sizeof(link));
+	bnx2x_dev_atomic_read_link_status(dev, &orig);
 	mb();
 	link.link_speed = sc->link_vars.line_speed;
 	switch (sc->link_vars.duplex) {
@@ -102,8 +158,9 @@ struct rte_bnx2x_xstats_name_off {
 	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
 			ETH_LINK_SPEED_FIXED);
 	link.link_status = sc->link_vars.link_up;
+	bnx2x_dev_atomic_write_link_status(dev, &link);
 
-	return rte_eth_linkstatus_set(dev, &link);
+	return (link.link_status == orig.link_status) ? -1 : 0;
 }
 
 static void
@@ -169,6 +226,32 @@ void bnx2x_periodic_stop(void *param)
  */
 
 static int
+bnx2x_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
+{
+	PMD_INIT_FUNC_TRACE();
+
+	return bnx2x_link_update(dev);
+}
+
+static int
+bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
+{
+	struct bnx2x_softc *sc = dev->data->dev_private;
+	int ret = 0;
+
+	ret = bnx2x_link_update(dev);
+
+	bnx2x_check_bull(sc);
+	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
+		PMD_DRV_LOG(ERR, "PF indicated channel is down."
+				"VF device is no longer operational");
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	}
+
+	return ret;
+}
+
+static int
 bnx2x_dev_configure(struct rte_eth_dev *dev)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
@@ -270,6 +353,12 @@ void bnx2x_periodic_stop(void *param)
 		return;
 	}
 
+	/* Update device link status */
+	if (IS_PF(sc))
+		bnx2x_dev_link_update(dev, 0);
+	else
+		bnx2xvf_dev_link_update(dev, 0);
+
 	return;
 }
 
@@ -342,32 +431,6 @@ void bnx2x_periodic_stop(void *param)
 }
 
 static int
-bnx2x_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return bnx2x_link_update(dev);
-}
-
-static int
-bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
-	struct bnx2x_softc *sc = dev->data->dev_private;
-	int ret = 0;
-
-	ret = bnx2x_link_update(dev);
-
-	bnx2x_check_bull(sc);
-	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
-		PMD_DRV_LOG(ERR, "PF indicated channel is down."
-				"VF device is no longer operational");
-		dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	}
-
-	return ret;
-}
-
-static int
 bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
-- 
1.7.10.3



More information about the stable mailing list