Extended the nicvf_interrupt function to respond
NIC_MBOX_MSG_BGX_LINK_CHANGE mbox message from PF and update
struct rte_eth_link accordingly.

Signed-off-by: Jerin Jacob <jerin.jacob at caviumnetworks.com>
Signed-off-by: Maciej Czekaj <maciej.czekaj at caviumnetworks.com>
Signed-off-by: Kamil Rytarowski <Kamil.Rytarowski at caviumnetworks.com>
Signed-off-by: Zyta Szpak <zyta.szpak at semihalf.com>
Signed-off-by: Slawomir Rosek <slawomir.rosek at semihalf.com>
Signed-off-by: Radoslaw Biernacki <rad at semihalf.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit at intel.com>
---
 drivers/net/thunderx/nicvf_ethdev.c | 53 ++++++++++++++++++++++++++++++++++++-
 drivers/net/thunderx/nicvf_ethdev.h |  4 +++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/net/thunderx/nicvf_ethdev.c 
b/drivers/net/thunderx/nicvf_ethdev.c
index ba78ff2..ec5407b 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -69,12 +69,45 @@

 #include "nicvf_logs.h"

+static inline int
+nicvf_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 inline void
+nicvf_set_eth_link_status(struct nicvf *nic, struct rte_eth_link *link)
+{
+       link->link_status = nic->link_up;
+       link->link_duplex = ETH_LINK_AUTONEG;
+       if (nic->duplex == NICVF_HALF_DUPLEX)
+               link->link_duplex = ETH_LINK_HALF_DUPLEX;
+       else if (nic->duplex == NICVF_FULL_DUPLEX)
+               link->link_duplex = ETH_LINK_FULL_DUPLEX;
+       link->link_speed = nic->speed;
+       link->link_autoneg = ETH_LINK_SPEED_AUTONEG;
+}
+
 static void
 nicvf_interrupt(void *arg)
 {
        struct nicvf *nic = arg;

-       nicvf_reg_poll_interrupts(nic);
+       if (nicvf_reg_poll_interrupts(nic) == NIC_MBOX_MSG_BGX_LINK_CHANGE) {
+               if (nic->eth_dev->data->dev_conf.intr_conf.lsc)
+                       nicvf_set_eth_link_status(nic,
+                                       &nic->eth_dev->data->dev_link);
+               _rte_eth_dev_callback_process(nic->eth_dev,
+                               RTE_ETH_EVENT_INTR_LSC);
+       }

        rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
                                nicvf_interrupt, nic);
@@ -93,8 +126,26 @@ nicvf_periodic_alarm_stop(struct nicvf *nic)
        return rte_eal_alarm_cancel(nicvf_interrupt, nic);
 }

+/*
+ * Return 0 means link status changed, -1 means not changed
+ */
+static int
+nicvf_dev_link_update(struct rte_eth_dev *dev,
+                     int wait_to_complete __rte_unused)
+{
+       struct rte_eth_link link;
+       struct nicvf *nic = nicvf_pmd_priv(dev);
+
+       PMD_INIT_FUNC_TRACE();
+
+       memset(&link, 0, sizeof(link));
+       nicvf_set_eth_link_status(nic, &link);
+       return nicvf_atomic_write_link_status(dev, &link);
+}
+
 /* Initialize and register driver with DPDK Application */
 static const struct eth_dev_ops nicvf_eth_dev_ops = {
+       .link_update              = nicvf_dev_link_update,
 };

 static int
diff --git a/drivers/net/thunderx/nicvf_ethdev.h 
b/drivers/net/thunderx/nicvf_ethdev.h
index d4d2071..8189856 100644
--- a/drivers/net/thunderx/nicvf_ethdev.h
+++ b/drivers/net/thunderx/nicvf_ethdev.h
@@ -38,6 +38,10 @@
 #define THUNDERX_NICVF_PMD_VERSION      "1.0"

 #define NICVF_INTR_POLL_INTERVAL_MS    50
+#define NICVF_HALF_DUPLEX              0x00
+#define NICVF_FULL_DUPLEX              0x01
+#define NICVF_UNKNOWN_DUPLEX           0xff
+

 static inline struct nicvf *
 nicvf_pmd_priv(struct rte_eth_dev *eth_dev)
-- 
2.5.5

Reply via email to