From: James Hershaw <james.hers...@corigine.com> The NFP PMD driver retrieves the linkspeed by reading the NFP_NET_CFG_STS_LINK register. This register is not set by all versions of the firmware. Changes in this patch include:
Addition of listener function to deal with control messages of type NFP_FLOWER_CMSG_TYPE_PORT_MOD being received by the PMD. This ensures that the up/down status of the port is updated when a version of firmware is being used that does not write the link status to the NFP_NET_CFG_STS register. Update the nfp_flower_repr_link_update() function to preferably read the linkspeed from the port table, while keeping the old lookup method as a fallback in case that is not supported. Signed-off-by: James Hershaw <james.hers...@corigine.com> Reviewed-by: Long Wu <long...@corigine.com> Reviewed-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> --- drivers/net/nfp/flower/nfp_flower_cmsg.h | 3 ++ drivers/net/nfp/flower/nfp_flower_ctrl.c | 40 +++++++++++++++++++ .../net/nfp/flower/nfp_flower_representor.c | 39 +++++++++++------- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h index 96e080a8e9..ec76e6cf9c 100644 --- a/drivers/net/nfp/flower/nfp_flower_cmsg.h +++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h @@ -132,6 +132,9 @@ struct nfp_flower_cmsg_port_mod { rte_be16_t mtu; }; +#define NFP_FLOWER_CMSG_PORT_MOD_INFO_LINK RTE_BIT32(0) +#define NFP_FLOWER_CMSG_PORT_MOD_MTU_CHANGE_ONLY RTE_BIT32(1) + struct nfp_flower_tun_neigh { uint8_t dst_mac[RTE_ETHER_ADDR_LEN]; uint8_t src_mac[RTE_ETHER_ADDR_LEN]; diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c index 72c0d5e7d9..de4e333aa9 100644 --- a/drivers/net/nfp/flower/nfp_flower_ctrl.c +++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c @@ -15,6 +15,7 @@ #include "nfp_flower.h" #include "nfp_flower_ctrl.h" #include "nfp_flower_cmsg.h" +#include "nfp_flower_representor.h" #define MAX_PKT_BURST 32 @@ -274,6 +275,42 @@ nfp_flower_cmsg_rx_qos_stats(struct nfp_mtr_priv *mtr_priv, rte_spinlock_unlock(&mtr_priv->mtr_stats_lock); } +static int +nfp_flower_cmsg_port_mod_rx(struct nfp_app_fw_flower *app_fw_flower, + struct rte_mbuf *pkt_burst) +{ + uint32_t port; + struct nfp_flower_representor *repr; + struct nfp_flower_cmsg_port_mod *msg; + + msg = rte_pktmbuf_mtod_offset(pkt_burst, struct nfp_flower_cmsg_port_mod *, + NFP_FLOWER_CMSG_HLEN); + port = rte_be_to_cpu_32(msg->portnum); + + switch (NFP_FLOWER_CMSG_PORT_TYPE(port)) { + case NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT: + repr = app_fw_flower->phy_reprs[NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM(port)]; + break; + case NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT: + if (NFP_FLOWER_CMSG_PORT_VNIC_TYPE(port) == NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF) + repr = app_fw_flower->vf_reprs[NFP_FLOWER_CMSG_PORT_VNIC(port)]; + else + repr = app_fw_flower->pf_repr; + break; + default: + PMD_DRV_LOG(ERR, "ctrl msg for unknown port %#x", port); + return -EINVAL; + } + + repr->link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX; + if ((msg->info & NFP_FLOWER_CMSG_PORT_MOD_INFO_LINK) != 0) + repr->link.link_status = RTE_ETH_LINK_UP; + else + repr->link.link_status = RTE_ETH_LINK_DOWN; + + return 0; +} + static void nfp_flower_cmsg_rx(struct nfp_app_fw_flower *app_fw_flower, struct rte_mbuf **pkts_burst, @@ -316,6 +353,9 @@ nfp_flower_cmsg_rx(struct nfp_app_fw_flower *app_fw_flower, } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_QOS_STATS) { /* Handle meter stats */ nfp_flower_cmsg_rx_qos_stats(mtr_priv, pkts_burst[i]); + } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_MOD) { + /* Handle changes to port configuration/status */ + nfp_flower_cmsg_port_mod_rx(app_fw_flower, pkts_burst[i]); } rte_pktmbuf_free(pkts_burst[i]); diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c index c3764b4de7..b4cf49c933 100644 --- a/drivers/net/nfp/flower/nfp_flower_representor.c +++ b/drivers/net/nfp/flower/nfp_flower_representor.c @@ -191,9 +191,11 @@ nfp_flower_repr_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) { int ret; + uint32_t i; uint32_t nn_link_status; struct nfp_net_hw *pf_hw; struct rte_eth_link *link; + struct nfp_eth_table *nfp_eth_table; struct nfp_flower_representor *repr; static const uint32_t ls_to_ethtool[] = { @@ -209,23 +211,30 @@ nfp_flower_repr_link_update(struct rte_eth_dev *dev, repr = dev->data->dev_private; link = &repr->link; + link->link_speed = RTE_ETH_SPEED_NUM_NONE; pf_hw = repr->app_fw_flower->pf_hw; - memset(link, 0, sizeof(struct rte_eth_link)); - nn_link_status = nn_cfg_readl(pf_hw, NFP_NET_CFG_STS); - - if (nn_link_status & NFP_NET_CFG_STS_LINK) - link->link_status = RTE_ETH_LINK_UP; - - link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX; - - nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) & - NFP_NET_CFG_STS_LINK_RATE_MASK; - - if (nn_link_status >= RTE_DIM(ls_to_ethtool)) - link->link_speed = RTE_ETH_SPEED_NUM_NONE; - else - link->link_speed = ls_to_ethtool[nn_link_status]; + if (link->link_status == RTE_ETH_LINK_UP) { + if (pf_hw->pf_dev != NULL) { + nfp_eth_table = pf_hw->pf_dev->nfp_eth_table; + if (nfp_eth_table != NULL) { + uint32_t speed = nfp_eth_table->ports[pf_hw->idx].speed; + for (i = 0; i < RTE_DIM(ls_to_ethtool); i++) { + if (ls_to_ethtool[i] == speed) { + link->link_speed = speed; + break; + } + } + } + } else { + nn_link_status = nn_cfg_readw(pf_hw, NFP_NET_CFG_STS); + nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) & + NFP_NET_CFG_STS_LINK_RATE_MASK; + + if (nn_link_status < RTE_DIM(ls_to_ethtool)) + link->link_speed = ls_to_ethtool[nn_link_status]; + } + } ret = rte_eth_linkstatus_set(dev, link); if (ret == 0) { -- 2.39.1