Implement the necessary functions to allow user to visually identify a physical port associated with a netdev by blinking an LED on that port.
Signed-off-by: James Hershaw <james.hers...@corigine.com> Signed-off-by: Chaoyong He <chaoyong...@corigine.com> --- .../net/nfp/flower/nfp_flower_representor.c | 30 ++++++++++++++++ drivers/net/nfp/nfp_ethdev.c | 2 ++ drivers/net/nfp/nfp_net_common.c | 32 +++++++++++++++++ drivers/net/nfp/nfp_net_common.h | 2 ++ drivers/net/nfp/nfpcore/nfp_nsp.h | 1 + drivers/net/nfp/nfpcore/nfp_nsp_eth.c | 36 +++++++++++++++++++ 6 files changed, 103 insertions(+) diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c index 3d043e052a..01ca8a6768 100644 --- a/drivers/net/nfp/flower/nfp_flower_representor.c +++ b/drivers/net/nfp/flower/nfp_flower_representor.c @@ -88,6 +88,30 @@ nfp_repr_get_module_eeprom(struct rte_eth_dev *dev, return nfp_net_get_module_eeprom(dev, info); } +static int +nfp_flower_repr_led_on(struct rte_eth_dev *dev) +{ + struct nfp_flower_representor *repr; + + repr = dev->data->dev_private; + if (!nfp_flower_repr_is_phy(repr)) + return -EOPNOTSUPP; + + return nfp_net_led_on(dev); +} + +static int +nfp_flower_repr_led_off(struct rte_eth_dev *dev) +{ + struct nfp_flower_representor *repr; + + repr = dev->data->dev_private; + if (!nfp_flower_repr_is_phy(repr)) + return -EOPNOTSUPP; + + return nfp_net_led_off(dev); +} + static int nfp_flower_repr_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) @@ -623,6 +647,9 @@ static const struct eth_dev_ops nfp_flower_multiple_pf_repr_dev_ops = { .set_eeprom = nfp_repr_set_eeprom, .get_module_info = nfp_repr_get_module_info, .get_module_eeprom = nfp_repr_get_module_eeprom, + + .dev_led_on = nfp_flower_repr_led_on, + .dev_led_off = nfp_flower_repr_led_off, }; static const struct eth_dev_ops nfp_flower_repr_dev_ops = { @@ -661,6 +688,9 @@ static const struct eth_dev_ops nfp_flower_repr_dev_ops = { .set_eeprom = nfp_repr_set_eeprom, .get_module_info = nfp_repr_get_module_info, .get_module_eeprom = nfp_repr_get_module_eeprom, + + .dev_led_on = nfp_flower_repr_led_on, + .dev_led_off = nfp_flower_repr_led_off, }; static uint32_t diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index 2ee76d309c..f54483822f 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -983,6 +983,8 @@ static const struct eth_dev_ops nfp_net_eth_dev_ops = { .set_eeprom = nfp_net_set_eeprom, .get_module_info = nfp_net_get_module_info, .get_module_eeprom = nfp_net_get_module_eeprom, + .dev_led_on = nfp_net_led_on, + .dev_led_off = nfp_net_led_off, }; static inline void diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c index a45837353a..e68ce68229 100644 --- a/drivers/net/nfp/nfp_net_common.c +++ b/drivers/net/nfp/nfp_net_common.c @@ -3181,3 +3181,35 @@ nfp_net_get_module_eeprom(struct rte_eth_dev *dev, nfp_nsp_close(nsp); return ret; } + +static int +nfp_net_led_control(struct rte_eth_dev *dev, + bool is_on) +{ + int ret; + uint32_t nfp_idx; + struct nfp_net_hw_priv *hw_priv; + + hw_priv = dev->process_private; + nfp_idx = nfp_net_get_nfp_index(dev); + + ret = nfp_eth_set_idmode(hw_priv->pf_dev->cpp, nfp_idx, is_on); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Set nfp idmode failed."); + return ret; + } + + return 0; +} + +int +nfp_net_led_on(struct rte_eth_dev *dev) +{ + return nfp_net_led_control(dev, true); +} + +int +nfp_net_led_off(struct rte_eth_dev *dev) +{ + return nfp_net_led_control(dev, false); +} diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h index 5ad698cad2..d85a00a75e 100644 --- a/drivers/net/nfp/nfp_net_common.h +++ b/drivers/net/nfp/nfp_net_common.h @@ -399,6 +399,8 @@ int nfp_net_get_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eepr int nfp_net_set_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom); int nfp_net_get_module_info(struct rte_eth_dev *dev, struct rte_eth_dev_module_info *info); int nfp_net_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info); +int nfp_net_led_on(struct rte_eth_dev *dev); +int nfp_net_led_off(struct rte_eth_dev *dev); #define NFP_PRIV_TO_APP_FW_NIC(app_fw_priv)\ ((struct nfp_app_fw_nic *)app_fw_priv) diff --git a/drivers/net/nfp/nfpcore/nfp_nsp.h b/drivers/net/nfp/nfpcore/nfp_nsp.h index 0ae10dabfb..6230a84e34 100644 --- a/drivers/net/nfp/nfpcore/nfp_nsp.h +++ b/drivers/net/nfp/nfpcore/nfp_nsp.h @@ -216,6 +216,7 @@ int nfp_eth_set_speed(struct nfp_nsp *nsp, uint32_t speed); int nfp_eth_set_split(struct nfp_nsp *nsp, uint32_t lanes); int nfp_eth_set_tx_pause(struct nfp_nsp *nsp, bool tx_pause); int nfp_eth_set_rx_pause(struct nfp_nsp *nsp, bool rx_pause); +int nfp_eth_set_idmode(struct nfp_cpp *cpp, uint32_t idx, bool is_on); /* NSP static information */ struct nfp_nsp_identify { diff --git a/drivers/net/nfp/nfpcore/nfp_nsp_eth.c b/drivers/net/nfp/nfpcore/nfp_nsp_eth.c index 1fcd54656a..404690d05f 100644 --- a/drivers/net/nfp/nfpcore/nfp_nsp_eth.c +++ b/drivers/net/nfp/nfpcore/nfp_nsp_eth.c @@ -44,6 +44,7 @@ #define NSP_ETH_CTRL_SET_LANES RTE_BIT64(5) #define NSP_ETH_CTRL_SET_ANEG RTE_BIT64(6) #define NSP_ETH_CTRL_SET_FEC RTE_BIT64(7) +#define NSP_ETH_CTRL_SET_IDMODE RTE_BIT64(8) #define NSP_ETH_CTRL_SET_TX_PAUSE RTE_BIT64(10) #define NSP_ETH_CTRL_SET_RX_PAUSE RTE_BIT64(11) @@ -736,3 +737,38 @@ nfp_eth_set_rx_pause(struct nfp_nsp *nsp, return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE, NSP_ETH_STATE_RX_PAUSE, rx_pause, NSP_ETH_CTRL_SET_RX_PAUSE); } + +int +nfp_eth_set_idmode(struct nfp_cpp *cpp, + uint32_t idx, + bool is_on) +{ + uint64_t reg; + struct nfp_nsp *nsp; + union eth_table_entry *entries; + + nsp = nfp_eth_config_start(cpp, idx); + if (nsp == NULL) + return -EIO; + + /* + * Older ABI versions did support this feature, however this has only + * been reliable since ABI 32. + */ + if (nfp_nsp_get_abi_ver_minor(nsp) < 32) { + PMD_DRV_LOG(ERR, "Operation only supported on ABI 32 or newer."); + nfp_eth_config_cleanup_end(nsp); + return -ENOTSUP; + } + + entries = nfp_nsp_config_entries(nsp); + + reg = rte_le_to_cpu_64(entries[idx].control); + reg &= ~NSP_ETH_CTRL_SET_IDMODE; + reg |= FIELD_PREP(NSP_ETH_CTRL_SET_IDMODE, is_on); + entries[idx].control = rte_cpu_to_le_64(reg); + + nfp_nsp_config_set_modified(nsp, 1); + + return nfp_eth_config_commit_end(nsp); +} -- 2.43.5