Commit 31eafa40 authored by Anirudh Venkataramanan's avatar Anirudh Venkataramanan Committed by Jeff Kirsher

ice: Implement LLDP persistence

Implement LLDP persistence across reboots, start and stop of LLDP agent.
Add additional parameter to ice_aq_start_lldp and ice_aq_stop_lldp.

Also change the ethtool private flag from "disable-fw-lldp" to
"enable-fw-lldp". This change will flip the boolean logic of the
functionality of the flag (on = enable, off = disable). The change
in name and functionality is to differentiate between the
pre-persistence and post-persistence states.
Signed-off-by: default avatarAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent b4603dbf
...@@ -330,7 +330,7 @@ enum ice_pf_flags { ...@@ -330,7 +330,7 @@ enum ice_pf_flags {
ICE_FLAG_DCB_CAPABLE, ICE_FLAG_DCB_CAPABLE,
ICE_FLAG_DCB_ENA, ICE_FLAG_DCB_ENA,
ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
ICE_FLAG_DISABLE_FW_LLDP, ICE_FLAG_ENABLE_FW_LLDP,
ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */ ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */
ICE_PF_FLAGS_NBITS /* must be last */ ICE_PF_FLAGS_NBITS /* must be last */
}; };
......
...@@ -82,12 +82,14 @@ ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update, ...@@ -82,12 +82,14 @@ ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,
* @hw: pointer to the HW struct * @hw: pointer to the HW struct
* @shutdown_lldp_agent: True if LLDP Agent needs to be Shutdown * @shutdown_lldp_agent: True if LLDP Agent needs to be Shutdown
* False if LLDP Agent needs to be Stopped * False if LLDP Agent needs to be Stopped
* @persist: True if Stop/Shutdown of LLDP Agent needs to be persistent across
* reboots
* @cd: pointer to command details structure or NULL * @cd: pointer to command details structure or NULL
* *
* Stop or Shutdown the embedded LLDP Agent (0x0A05) * Stop or Shutdown the embedded LLDP Agent (0x0A05)
*/ */
enum ice_status enum ice_status
ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, bool persist,
struct ice_sq_cd *cd) struct ice_sq_cd *cd)
{ {
struct ice_aqc_lldp_stop *cmd; struct ice_aqc_lldp_stop *cmd;
...@@ -100,17 +102,22 @@ ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, ...@@ -100,17 +102,22 @@ ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent,
if (shutdown_lldp_agent) if (shutdown_lldp_agent)
cmd->command |= ICE_AQ_LLDP_AGENT_SHUTDOWN; cmd->command |= ICE_AQ_LLDP_AGENT_SHUTDOWN;
if (persist)
cmd->command |= ICE_AQ_LLDP_AGENT_PERSIST_DIS;
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
} }
/** /**
* ice_aq_start_lldp * ice_aq_start_lldp
* @hw: pointer to the HW struct * @hw: pointer to the HW struct
* @persist: True if Start of LLDP Agent needs to be persistent across reboots
* @cd: pointer to command details structure or NULL * @cd: pointer to command details structure or NULL
* *
* Start the embedded LLDP Agent on all ports. (0x0A06) * Start the embedded LLDP Agent on all ports. (0x0A06)
*/ */
enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd) enum ice_status
ice_aq_start_lldp(struct ice_hw *hw, bool persist, struct ice_sq_cd *cd)
{ {
struct ice_aqc_lldp_start *cmd; struct ice_aqc_lldp_start *cmd;
struct ice_aq_desc desc; struct ice_aq_desc desc;
...@@ -121,6 +128,9 @@ enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd) ...@@ -121,6 +128,9 @@ enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd)
cmd->command = ICE_AQ_LLDP_AGENT_START; cmd->command = ICE_AQ_LLDP_AGENT_START;
if (persist)
cmd->command |= ICE_AQ_LLDP_AGENT_PERSIST_ENA;
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
} }
...@@ -163,7 +173,7 @@ ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size, ...@@ -163,7 +173,7 @@ ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
* *
* Get the DCBX status from the Firmware * Get the DCBX status from the Firmware
*/ */
u8 ice_get_dcbx_status(struct ice_hw *hw) static u8 ice_get_dcbx_status(struct ice_hw *hw)
{ {
u32 reg; u32 reg;
......
...@@ -120,7 +120,6 @@ struct ice_cee_app_prio { ...@@ -120,7 +120,6 @@ struct ice_cee_app_prio {
u8 prio_map; u8 prio_map;
} __packed; } __packed;
u8 ice_get_dcbx_status(struct ice_hw *hw);
enum ice_status ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg); enum ice_status ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg);
enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi); enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi);
enum ice_status ice_set_dcb_cfg(struct ice_port_info *pi); enum ice_status ice_set_dcb_cfg(struct ice_port_info *pi);
...@@ -131,9 +130,10 @@ ice_query_port_ets(struct ice_port_info *pi, ...@@ -131,9 +130,10 @@ ice_query_port_ets(struct ice_port_info *pi,
struct ice_sq_cd *cmd_details); struct ice_sq_cd *cmd_details);
#ifdef CONFIG_DCB #ifdef CONFIG_DCB
enum ice_status enum ice_status
ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, bool persist,
struct ice_sq_cd *cd); struct ice_sq_cd *cd);
enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd); enum ice_status
ice_aq_start_lldp(struct ice_hw *hw, bool persist, struct ice_sq_cd *cd);
enum ice_status enum ice_status
ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent, ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
bool *dcbx_agent_status, struct ice_sq_cd *cd); bool *dcbx_agent_status, struct ice_sq_cd *cd);
...@@ -144,6 +144,7 @@ ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update, ...@@ -144,6 +144,7 @@ ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,
static inline enum ice_status static inline enum ice_status
ice_aq_stop_lldp(struct ice_hw __always_unused *hw, ice_aq_stop_lldp(struct ice_hw __always_unused *hw,
bool __always_unused shutdown_lldp_agent, bool __always_unused shutdown_lldp_agent,
bool __always_unused persist,
struct ice_sq_cd __always_unused *cd) struct ice_sq_cd __always_unused *cd)
{ {
return 0; return 0;
...@@ -151,6 +152,7 @@ ice_aq_stop_lldp(struct ice_hw __always_unused *hw, ...@@ -151,6 +152,7 @@ ice_aq_stop_lldp(struct ice_hw __always_unused *hw,
static inline enum ice_status static inline enum ice_status
ice_aq_start_lldp(struct ice_hw __always_unused *hw, ice_aq_start_lldp(struct ice_hw __always_unused *hw,
bool __always_unused persist,
struct ice_sq_cd __always_unused *cd) struct ice_sq_cd __always_unused *cd)
{ {
return 0; return 0;
......
...@@ -360,33 +360,10 @@ int ice_init_pf_dcb(struct ice_pf *pf) ...@@ -360,33 +360,10 @@ int ice_init_pf_dcb(struct ice_pf *pf)
port_info = hw->port_info; port_info = hw->port_info;
/* check if device is DCB capable */
if (!hw->func_caps.common_cap.dcb) {
dev_dbg(dev, "DCB not supported\n");
return -EOPNOTSUPP;
}
/* Best effort to put DCBx and LLDP into a good state */
port_info->dcbx_status = ice_get_dcbx_status(hw);
if (port_info->dcbx_status != ICE_DCBX_STATUS_DONE &&
port_info->dcbx_status != ICE_DCBX_STATUS_IN_PROGRESS) {
bool dcbx_status;
/* Attempt to start LLDP engine. Ignore errors
* as this will error if it is already started
*/
ice_aq_start_lldp(hw, NULL);
/* Attempt to start DCBX. Ignore errors as this
* will error if it is already started
*/
ice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL);
}
err = ice_init_dcb(hw); err = ice_init_dcb(hw);
if (err) { if (err) {
/* FW LLDP not in usable state, default to SW DCBx/LLDP */ /* FW LLDP is not active, default to SW DCBx/LLDP */
dev_info(&pf->pdev->dev, "FW LLDP not in usable state\n"); dev_info(&pf->pdev->dev, "FW LLDP is not active\n");
hw->port_info->dcbx_status = ICE_DCBX_STATUS_NOT_STARTED; hw->port_info->dcbx_status = ICE_DCBX_STATUS_NOT_STARTED;
hw->port_info->is_sw_lldp = true; hw->port_info->is_sw_lldp = true;
} }
...@@ -398,6 +375,9 @@ int ice_init_pf_dcb(struct ice_pf *pf) ...@@ -398,6 +375,9 @@ int ice_init_pf_dcb(struct ice_pf *pf)
if (port_info->is_sw_lldp) { if (port_info->is_sw_lldp) {
sw_default = 1; sw_default = 1;
dev_info(&pf->pdev->dev, "DCBx/LLDP in SW mode.\n"); dev_info(&pf->pdev->dev, "DCBx/LLDP in SW mode.\n");
clear_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags);
} else {
set_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags);
} }
if (port_info->dcbx_status == ICE_DCBX_STATUS_NOT_STARTED) { if (port_info->dcbx_status == ICE_DCBX_STATUS_NOT_STARTED) {
......
...@@ -134,7 +134,7 @@ struct ice_priv_flag { ...@@ -134,7 +134,7 @@ struct ice_priv_flag {
static const struct ice_priv_flag ice_gstrings_priv_flags[] = { static const struct ice_priv_flag ice_gstrings_priv_flags[] = {
ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA), ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA),
ICE_PRIV_FLAG("disable-fw-lldp", ICE_FLAG_DISABLE_FW_LLDP), ICE_PRIV_FLAG("enable-fw-lldp", ICE_FLAG_ENABLE_FW_LLDP),
}; };
#define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags) #define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags)
...@@ -433,8 +433,8 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags) ...@@ -433,8 +433,8 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS); bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS);
if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, change_flags)) { if (test_bit(ICE_FLAG_ENABLE_FW_LLDP, change_flags)) {
if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, pf->flags)) { if (!test_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags)) {
enum ice_status status; enum ice_status status;
status = ice_aq_cfg_lldp_mib_change(&pf->hw, false, status = ice_aq_cfg_lldp_mib_change(&pf->hw, false,
...@@ -450,7 +450,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags) ...@@ -450,7 +450,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
/* The AQ call to stop the FW LLDP agent will generate /* The AQ call to stop the FW LLDP agent will generate
* an error if the agent is already stopped. * an error if the agent is already stopped.
*/ */
status = ice_aq_stop_lldp(&pf->hw, true, NULL); status = ice_aq_stop_lldp(&pf->hw, true, true, NULL);
if (status) if (status)
dev_warn(&pf->pdev->dev, dev_warn(&pf->pdev->dev,
"Fail to stop LLDP agent\n"); "Fail to stop LLDP agent\n");
...@@ -468,7 +468,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags) ...@@ -468,7 +468,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
/* AQ command to start FW LLDP agent will return an /* AQ command to start FW LLDP agent will return an
* error if the agent is already started * error if the agent is already started
*/ */
status = ice_aq_start_lldp(&pf->hw, NULL); status = ice_aq_start_lldp(&pf->hw, true, NULL);
if (status) if (status)
dev_warn(&pf->pdev->dev, dev_warn(&pf->pdev->dev,
"Fail to start LLDP Agent\n"); "Fail to start LLDP Agent\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment