[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 = ð_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