Commit c65e78f8 authored by Aleksandr Loktionov's avatar Aleksandr Loktionov Committed by Jeff Kirsher
Browse files

i40e: Further implementation of LLDP



This code implements driver code changes necessary for LLDP
Agent support. Modified i40e_aq_start_lldp() and
i40e_aq_stop_lldp() adding false parameter whether LLDP state
should be persistent across power cycles.

Signed-off-by: default avatarAleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent b3212f35
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -608,6 +608,11 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
	     hw->aq.api_min_ver >= 7))
		hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE;

	if (hw->aq.api_maj_ver > 1 ||
	    (hw->aq.api_maj_ver == 1 &&
	     hw->aq.api_min_ver >= 8))
		hw->flags |= I40E_HW_FLAG_FW_LLDP_PERSISTENT;

	if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
		goto init_adminq_free_arq;
+16 −4
Original line number Diff line number Diff line
@@ -261,6 +261,7 @@ enum i40e_admin_queue_opc {
	i40e_aqc_opc_get_cee_dcb_cfg	= 0x0A07,
	i40e_aqc_opc_lldp_set_local_mib	= 0x0A08,
	i40e_aqc_opc_lldp_stop_start_spec_agent	= 0x0A09,
	i40e_aqc_opc_lldp_restore		= 0x0A0A,

	/* Tunnel commands */
	i40e_aqc_opc_add_udp_tunnel	= 0x0B00,
@@ -2500,16 +2501,17 @@ struct i40e_aqc_lldp_stop {
	u8	command;
#define I40E_AQ_LLDP_AGENT_STOP			0x0
#define I40E_AQ_LLDP_AGENT_SHUTDOWN		0x1
#define I40E_AQ_LLDP_AGENT_STOP_PERSIST		0x2
	u8	reserved[15];
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop);

/* Start LLDP (direct 0x0A06) */

struct i40e_aqc_lldp_start {
	u8	command;
#define I40E_AQ_LLDP_AGENT_START		0x1
#define I40E_AQ_LLDP_AGENT_START_PERSIST	0x2
	u8	reserved[15];
};

@@ -2633,6 +2635,16 @@ struct i40e_aqc_lldp_stop_start_specific_agent {

I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop_start_specific_agent);

/* Restore LLDP Agent factory settings (direct 0x0A0A) */
struct i40e_aqc_lldp_restore {
	u8	command;
#define I40E_AQ_LLDP_AGENT_RESTORE_NOT		0x0
#define I40E_AQ_LLDP_AGENT_RESTORE		0x1
	u8	reserved[15];
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_restore);

/* Add Udp Tunnel command and completion (direct 0x0B00) */
struct i40e_aqc_add_udp_tunnel {
	__le16	udp_port;
+60 −2
Original line number Diff line number Diff line
@@ -3623,15 +3623,55 @@ i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
	return status;
}

/**
 * i40e_aq_restore_lldp
 * @hw: pointer to the hw struct
 * @setting: pointer to factory setting variable or NULL
 * @restore: True if factory settings should be restored
 * @cmd_details: pointer to command details structure or NULL
 *
 * Restore LLDP Agent factory settings if @restore set to True. In other case
 * only returns factory setting in AQ response.
 **/
enum i40e_status_code
i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
		     struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_lldp_restore *cmd =
		(struct i40e_aqc_lldp_restore *)&desc.params.raw;
	i40e_status status;

	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
		i40e_debug(hw, I40E_DEBUG_ALL,
			   "Restore LLDP not supported by current FW version.\n");
		return I40E_ERR_DEVICE_NOT_SUPPORTED;
	}

	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);

	if (restore)
		cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	if (setting)
		*setting = cmd->command & 1;

	return status;
}

/**
 * i40e_aq_stop_lldp
 * @hw: pointer to the hw struct
 * @shutdown_agent: True if LLDP Agent needs to be Shutdown
 * @persist: True if stop of LLDP should be persistent across power cycles
 * @cmd_details: pointer to command details structure or NULL
 *
 * Stop or Shutdown the embedded LLDP Agent
 **/
i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
				bool persist,
				struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
@@ -3644,6 +3684,14 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
	if (shutdown_agent)
		cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;

	if (persist) {
		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
			cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
		else
			i40e_debug(hw, I40E_DEBUG_ALL,
				   "Persistent Stop LLDP not supported by current FW version.\n");
	}

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
@@ -3653,12 +3701,13 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
 * i40e_aq_start_lldp
 * @hw: pointer to the hw struct
 * @buff: buffer for result
 * @persist: True if start of LLDP should be persistent across power cycles
 * @buff_size: buffer size
 * @cmd_details: pointer to command details structure or NULL
 *
 * Start the embedded LLDP Agent on all ports.
 **/
i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
			       struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
@@ -3669,6 +3718,15 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);

	cmd->command = I40E_AQ_LLDP_AGENT_START;

	if (persist) {
		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
			cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
		else
			i40e_debug(hw, I40E_DEBUG_ALL,
				   "Persistent Start LLDP not supported by current FW version.\n");
	}

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
+2 −2
Original line number Diff line number Diff line
@@ -1321,7 +1321,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
		if (strncmp(&cmd_buf[5], "stop", 4) == 0) {
			int ret;

			ret = i40e_aq_stop_lldp(&pf->hw, false, NULL);
			ret = i40e_aq_stop_lldp(&pf->hw, false, false, NULL);
			if (ret) {
				dev_info(&pf->pdev->dev,
					 "Stop LLDP AQ command failed =0x%x\n",
@@ -1358,7 +1358,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
				/* Continue and start FW LLDP anyways */
			}

			ret = i40e_aq_start_lldp(&pf->hw, NULL);
			ret = i40e_aq_start_lldp(&pf->hw, false, NULL);
			if (ret) {
				dev_info(&pf->pdev->dev,
					 "Start LLDP AQ command failed =0x%x\n",
+2 −2
Original line number Diff line number Diff line
@@ -4958,7 +4958,7 @@ flags_complete:
		if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
			struct i40e_dcbx_config *dcbcfg;

			i40e_aq_stop_lldp(&pf->hw, true, NULL);
			i40e_aq_stop_lldp(&pf->hw, true, false, NULL);
			i40e_aq_set_dcb_parameters(&pf->hw, true, NULL);
			/* reset local_dcbx_config to default */
			dcbcfg = &pf->hw.local_dcbx_config;
@@ -4973,7 +4973,7 @@ flags_complete:
			dcbcfg->pfc.willing = 1;
			dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
		} else {
			i40e_aq_start_lldp(&pf->hw, NULL);
			i40e_aq_start_lldp(&pf->hw, false, NULL);
		}
	}

Loading