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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -330,7 +330,7 @@ enum ice_pf_flags {
	ICE_FLAG_DCB_CAPABLE,
	ICE_FLAG_DCB_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_PF_FLAGS_NBITS		/* must be last */
};
+13 −3
Original line number Diff line number Diff line
@@ -82,12 +82,14 @@ ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,
 * @hw: pointer to the HW struct
 * @shutdown_lldp_agent: True if LLDP Agent needs to be Shutdown
 *			 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
 *
 * Stop or Shutdown the embedded LLDP Agent (0x0A05)
 */
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_aqc_lldp_stop *cmd;
@@ -100,17 +102,22 @@ ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent,
	if (shutdown_lldp_agent)
		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);
}

/**
 * ice_aq_start_lldp
 * @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
 *
 * 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_aq_desc desc;
@@ -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;

	if (persist)
		cmd->command |= ICE_AQ_LLDP_AGENT_PERSIST_ENA;

	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,
 *
 * 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;

+5 −3
Original line number Diff line number Diff line
@@ -120,7 +120,6 @@ struct ice_cee_app_prio {
	u8 prio_map;
} __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_get_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,
		   struct ice_sq_cd *cmd_details);
#ifdef CONFIG_DCB
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);
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
ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
		       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,
static inline enum ice_status
ice_aq_stop_lldp(struct ice_hw __always_unused *hw,
		 bool __always_unused shutdown_lldp_agent,
		 bool __always_unused persist,
		 struct ice_sq_cd __always_unused *cd)
{
	return 0;
@@ -151,6 +152,7 @@ ice_aq_stop_lldp(struct ice_hw __always_unused *hw,

static inline enum ice_status
ice_aq_start_lldp(struct ice_hw __always_unused *hw,
		  bool __always_unused persist,
		  struct ice_sq_cd __always_unused *cd)
{
	return 0;
+5 −25
Original line number Diff line number Diff line
@@ -360,33 +360,10 @@ int ice_init_pf_dcb(struct ice_pf *pf)

	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);
	if (err) {
		/* FW LLDP not in usable state, default to SW DCBx/LLDP */
		dev_info(&pf->pdev->dev, "FW LLDP not in usable state\n");
		/* FW LLDP is not active, default to SW DCBx/LLDP */
		dev_info(&pf->pdev->dev, "FW LLDP is not active\n");
		hw->port_info->dcbx_status = ICE_DCBX_STATUS_NOT_STARTED;
		hw->port_info->is_sw_lldp = true;
	}
@@ -398,6 +375,9 @@ int ice_init_pf_dcb(struct ice_pf *pf)
	if (port_info->is_sw_lldp) {
		sw_default = 1;
		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) {
+5 −5
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ struct ice_priv_flag {

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("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)
@@ -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);

	if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, change_flags)) {
		if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, pf->flags)) {
	if (test_bit(ICE_FLAG_ENABLE_FW_LLDP, change_flags)) {
		if (!test_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags)) {
			enum ice_status status;

			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)
			/* The AQ call to stop the FW LLDP agent will generate
			 * 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)
				dev_warn(&pf->pdev->dev,
					 "Fail to stop LLDP agent\n");
@@ -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
			 * 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)
				dev_warn(&pf->pdev->dev,
					 "Fail to start LLDP Agent\n");