From: Qin Ke <qin.ke@corigine.com>
For representor port link speed, the original logic finally calls
'nfp_net_speed_aneg_update()' to update it. But the reference of
'hw->idx' in this function is invalid for representor port devices,
the logic has problem.
Fix it by getting correct 'idx' for all type of deives including
representor port and make reference to it.
Fixes: 8412feed3f26 ("net/nfp: modify link update function")
Cc: zerun.fu@corigine.com
Cc: stable@dpdk.org
Signed-off-by: Qin Ke <qin.ke@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
.../net/nfp/flower/nfp_flower_representor.c | 2 +-
drivers/net/nfp/nfp_net_common.c | 32 +++++++++++++++----
drivers/net/nfp/nfp_net_common.h | 2 +-
3 files changed, 27 insertions(+), 9 deletions(-)
@@ -40,7 +40,7 @@ nfp_flower_repr_link_update(struct rte_eth_dev *dev,
pf_hw = repr->app_fw_flower->pf_hw;
nn_link_status = nn_cfg_readw(&pf_hw->super, NFP_NET_CFG_STS);
- ret = nfp_net_link_update_common(dev, pf_hw, link, nn_link_status);
+ ret = nfp_net_link_update_common(dev, link, nn_link_status);
return ret;
}
@@ -311,6 +311,24 @@ nfp_net_get_hw(const struct rte_eth_dev *dev)
return hw;
}
+uint8_t
+nfp_net_get_idx(const struct rte_eth_dev *dev)
+{
+ uint8_t idx;
+
+ if (rte_eth_dev_is_repr(dev)) {
+ struct nfp_flower_representor *repr;
+ repr = dev->data->dev_private;
+ idx = repr->idx;
+ } else {
+ struct nfp_net_hw *hw;
+ hw = dev->data->dev_private;
+ idx = hw->idx;
+ }
+
+ return idx;
+}
+
/*
* Configure an Ethernet device.
*
@@ -743,17 +761,18 @@ nfp_net_allmulticast_disable(struct rte_eth_dev *dev)
static void
nfp_net_pf_speed_update(struct rte_eth_dev *dev,
- struct nfp_net_hw *hw,
struct nfp_net_hw_priv *hw_priv,
struct rte_eth_link *link)
{
+ uint8_t idx;
enum nfp_eth_aneg aneg;
struct nfp_pf_dev *pf_dev;
struct nfp_eth_table *nfp_eth_table;
struct nfp_eth_table_port *eth_port;
pf_dev = hw_priv->pf_dev;
- aneg = pf_dev->nfp_eth_table->ports[hw->idx].aneg;
+ idx = nfp_net_get_idx(dev);
+ aneg = pf_dev->nfp_eth_table->ports[idx].aneg;
/* Compare whether the current status has changed. */
if (pf_dev->speed_updated || aneg == NFP_ANEG_AUTO) {
@@ -761,14 +780,14 @@ nfp_net_pf_speed_update(struct rte_eth_dev *dev,
if (nfp_eth_table == NULL) {
PMD_DRV_LOG(WARNING, "Failed to update port speed.");
} else {
- pf_dev->nfp_eth_table->ports[hw->idx] = nfp_eth_table->ports[hw->idx];
+ pf_dev->nfp_eth_table->ports[idx] = nfp_eth_table->ports[idx];
free(nfp_eth_table);
pf_dev->speed_updated = false;
}
}
nfp_eth_table = pf_dev->nfp_eth_table;
- eth_port = &nfp_eth_table->ports[hw->idx];
+ eth_port = &nfp_eth_table->ports[idx];
link->link_speed = nfp_net_link_speed_nfp2rte_check(eth_port->speed);
@@ -797,7 +816,6 @@ nfp_net_vf_speed_update(struct rte_eth_link *link,
int
nfp_net_link_update_common(struct rte_eth_dev *dev,
- struct nfp_net_hw *hw,
struct rte_eth_link *link,
uint32_t link_status)
{
@@ -807,7 +825,7 @@ nfp_net_link_update_common(struct rte_eth_dev *dev,
hw_priv = dev->process_private;
if (link->link_status == RTE_ETH_LINK_UP) {
if (hw_priv->is_pf)
- nfp_net_pf_speed_update(dev, hw, hw_priv, link);
+ nfp_net_pf_speed_update(dev, hw_priv, link);
else
nfp_net_vf_speed_update(link, link_status);
}
@@ -851,7 +869,7 @@ nfp_net_link_update(struct rte_eth_dev *dev,
link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
- ret = nfp_net_link_update_common(dev, hw, &link, nn_link_status);
+ ret = nfp_net_link_update_common(dev, &link, nn_link_status);
if (ret == -EIO)
return ret;
@@ -293,7 +293,6 @@ int nfp_net_promisc_disable(struct rte_eth_dev *dev);
int nfp_net_allmulticast_enable(struct rte_eth_dev *dev);
int nfp_net_allmulticast_disable(struct rte_eth_dev *dev);
int nfp_net_link_update_common(struct rte_eth_dev *dev,
- struct nfp_net_hw *hw,
struct rte_eth_link *link,
uint32_t link_status);
int nfp_net_link_update(struct rte_eth_dev *dev,
@@ -356,6 +355,7 @@ int nfp_net_firmware_version_get(struct rte_eth_dev *dev, char *fw_version, size
bool nfp_net_is_valid_nfd_version(struct nfp_net_fw_ver version);
bool nfp_net_is_valid_version_class(struct nfp_net_fw_ver version);
struct nfp_net_hw *nfp_net_get_hw(const struct rte_eth_dev *dev);
+uint8_t nfp_net_get_idx(const struct rte_eth_dev *dev);
int nfp_net_stop(struct rte_eth_dev *dev);
int nfp_net_flow_ctrl_get(struct rte_eth_dev *dev,
struct rte_eth_fc_conf *fc_conf);