From: "Alejandro.Lucero" <alejandro.luc...@netronome.com> Signed-off-by: Alejandro.Lucero <alejandro.lucero at netronome.com> Signed-off-by: Rolf.Neugebauer <rolf.neugebauer at netronome.com> --- drivers/net/nfp/nfp_net.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index e1badc3..9cc7776 100644 --- a/drivers/net/nfp/nfp_net.c +++ b/drivers/net/nfp/nfp_net.c @@ -232,6 +232,57 @@ ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name, NFP_MEMZONE_ALIGN); } +/* + * Atomically reads link status information from global structure rte_eth_dev. + * + * @param 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 +nfp_net_dev_atomic_read_link_status(struct rte_eth_dev *dev, + struct rte_eth_link *link) +{ + struct rte_eth_link *dst = link; + struct rte_eth_link *src = &dev->data->dev_link; + + if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, + *(uint64_t *)src) == 0) + return -1; + + return 0; +} + +/* + * Atomically writes the link status information into global + * structure rte_eth_dev. + * + * @param 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 +nfp_net_dev_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 void nfp_net_rx_queue_release_mbufs(struct nfp_net_rxq *rxq) { @@ -688,6 +739,49 @@ nfp_net_close(struct rte_eth_dev *dev) */ } +/* + * return 0 means link status changed, -1 means not changed + * + * Wait to complete is needed as it can take up to 9 seconds to get the Link + * status. + */ +static int +nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) +{ + struct nfp_net_hw *hw; + struct rte_eth_link link, old; + uint32_t nn_link_status; + + PMD_DRV_LOG(DEBUG, "Link update\n"); + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + memset(&old, 0, sizeof(old)); + nfp_net_dev_atomic_read_link_status(dev, &old); + + nn_link_status = nn_cfg_readl(hw, NFP_NET_CFG_STS); + + memset(&link, 0, sizeof(struct rte_eth_link)); + + if (nn_link_status & NFP_NET_CFG_STS_LINK) + link.link_status = 1; + + link.link_duplex = ETH_LINK_FULL_DUPLEX; + /* Other cards can limit the tx and rx rate per VF */ + link.link_speed = ETH_LINK_SPEED_40G; + + if (old.link_status != link.link_status) { + nfp_net_dev_atomic_write_link_status(dev, &link); + if (link.link_status) + PMD_DRV_LOG(INFO, "NIC Link is Up\n"); + else + PMD_DRV_LOG(INFO, "NIC Link is Down\n"); + return 0; + } + + return -1; +} + static void nfp_net_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) { -- 1.7.9.5