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