net/thunderx: add link status and update
authorJerin Jacob <jerin.jacob@caviumnetworks.com>
Fri, 17 Jun 2016 13:29:36 +0000 (18:59 +0530)
committerBruce Richardson <bruce.richardson@intel.com>
Mon, 20 Jun 2016 15:21:54 +0000 (17:21 +0200)
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@caviumnetworks.com>
Signed-off-by: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>
Signed-off-by: Kamil Rytarowski <kamil.rytarowski@caviumnetworks.com>
Signed-off-by: Zyta Szpak <zyta.szpak@semihalf.com>
Signed-off-by: Slawomir Rosek <slawomir.rosek@semihalf.com>
Signed-off-by: Radoslaw Biernacki <rad@semihalf.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/thunderx/nicvf_ethdev.c
drivers/net/thunderx/nicvf_ethdev.h

index ba78ff2..ec5407b 100644 (file)
 
 #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
index d4d2071..8189856 100644 (file)
 #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)