[dpdk-dev] [PATCH 35/50] net/liquidio: add API for link update

Shijith Thotton shijith.thotton at caviumnetworks.com
Tue Feb 21 10:26:50 CET 2017


Signed-off-by: Shijith Thotton <shijith.thotton at caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob at caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles at caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula at caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda at oneconvergence.com>
---
 drivers/net/liquidio/lio_ethdev.c | 76 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/liquidio/lio_ethdev.h |  5 +++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index 256e6b8..299d28b 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -41,6 +41,32 @@
 #include "lio_ethdev.h"
 #include "lio_rxtx.h"
 
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param eth_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
+lio_dev_atomic_write_link_status(struct rte_eth_dev *eth_dev,
+				 struct rte_eth_link *link)
+{
+	struct rte_eth_link *dst = &eth_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 uint64_t
 lio_hweight64(uint64_t w)
 {
@@ -55,6 +81,49 @@
 	return (res + (res >> 32)) & 0x00000000000000FFul;
 }
 
+static int
+lio_dev_link_update(struct rte_eth_dev *eth_dev,
+		    int wait_to_complete __rte_unused)
+{
+	struct lio_device *lio_dev = LIO_DEV(eth_dev);
+	struct rte_eth_link link, old;
+
+	/* Initialize */
+	link.link_status = ETH_LINK_DOWN;
+	link.link_speed = ETH_SPEED_NUM_NONE;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
+	memset(&old, 0, sizeof(old));
+
+	/* Return what we found */
+	if (lio_dev->linfo.link.s.link_up == 0) {
+		/* Interface is down */
+		if (lio_dev_atomic_write_link_status(eth_dev, &link))
+			return -1;
+		if (link.link_status == old.link_status)
+			return -1;
+		return 0;
+	}
+
+	link.link_status = ETH_LINK_UP; /* Interface is up */
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	switch (lio_dev->linfo.link.s.speed) {
+	case LIO_LINK_SPEED_10000:
+		link.link_speed = ETH_SPEED_NUM_10G;
+		break;
+	default:
+		link.link_speed = ETH_SPEED_NUM_NONE;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+	}
+
+	if (lio_dev_atomic_write_link_status(eth_dev, &link))
+		return -1;
+
+	if (link.link_status == old.link_status)
+		return -1;
+
+	return 0;
+}
+
 /**
  * Setup our receive queue/ringbuffer. This is the
  * queue the Octeon uses to send us packets and
@@ -289,8 +358,10 @@
 
 	lio_swap_8B_data((uint64_t *)ls, sizeof(union octeon_link_status) >> 3);
 
-	if (lio_dev->linfo.link.link_status64 != ls->link_status64)
+	if (lio_dev->linfo.link.link_status64 != ls->link_status64) {
 		lio_dev->linfo.link.link_status64 = ls->link_status64;
+		lio_dev_link_update(eth_dev, 0);
+	}
 
 	lio_free_soft_command(sc);
 
@@ -495,6 +566,8 @@ static int lio_dev_configure(struct rte_eth_dev *eth_dev)
 		return -ENOMEM;
 	}
 
+	lio_dev_link_update(eth_dev, 0);
+
 	lio_dev->port_configured = 1;
 
 	lio_free_soft_command(sc);
@@ -522,6 +595,7 @@ static int lio_dev_configure(struct rte_eth_dev *eth_dev)
 static const struct eth_dev_ops liovf_eth_dev_ops = {
 	.dev_configure		= lio_dev_configure,
 	.dev_start		= lio_dev_start,
+	.link_update		= lio_dev_link_update,
 	.rx_queue_setup		= lio_dev_rx_queue_setup,
 	.rx_queue_release	= lio_dev_rx_queue_release,
 	.tx_queue_setup		= lio_dev_tx_queue_setup,
diff --git a/drivers/net/liquidio/lio_ethdev.h b/drivers/net/liquidio/lio_ethdev.h
index c7d3336..98ff493 100644
--- a/drivers/net/liquidio/lio_ethdev.h
+++ b/drivers/net/liquidio/lio_ethdev.h
@@ -44,6 +44,11 @@
 
 #define LIO_DEV(_eth_dev)		((_eth_dev)->data->dev_private)
 
+enum lio_bus_speed {
+	LIO_LINK_SPEED_UNKNOWN  = 0,
+	LIO_LINK_SPEED_10000    = 10000
+};
+
 struct octeon_if_cfg_info {
 	uint64_t iqmask;	/** mask for IQs enabled for the port */
 	uint64_t oqmask;	/** mask for OQs enabled for the port */
-- 
1.8.3.1



More information about the dev mailing list