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

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
...@@ -608,6 +608,11 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw) ...@@ -608,6 +608,11 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
hw->aq.api_min_ver >= 7)) hw->aq.api_min_ver >= 7))
hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE; 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) { if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
ret_code = I40E_ERR_FIRMWARE_API_VERSION; ret_code = I40E_ERR_FIRMWARE_API_VERSION;
goto init_adminq_free_arq; goto init_adminq_free_arq;
......
...@@ -261,6 +261,7 @@ enum i40e_admin_queue_opc { ...@@ -261,6 +261,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_get_cee_dcb_cfg = 0x0A07, i40e_aqc_opc_get_cee_dcb_cfg = 0x0A07,
i40e_aqc_opc_lldp_set_local_mib = 0x0A08, i40e_aqc_opc_lldp_set_local_mib = 0x0A08,
i40e_aqc_opc_lldp_stop_start_spec_agent = 0x0A09, i40e_aqc_opc_lldp_stop_start_spec_agent = 0x0A09,
i40e_aqc_opc_lldp_restore = 0x0A0A,
/* Tunnel commands */ /* Tunnel commands */
i40e_aqc_opc_add_udp_tunnel = 0x0B00, i40e_aqc_opc_add_udp_tunnel = 0x0B00,
...@@ -2498,18 +2499,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv); ...@@ -2498,18 +2499,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv);
/* Stop LLDP (direct 0x0A05) */ /* Stop LLDP (direct 0x0A05) */
struct i40e_aqc_lldp_stop { struct i40e_aqc_lldp_stop {
u8 command; u8 command;
#define I40E_AQ_LLDP_AGENT_STOP 0x0 #define I40E_AQ_LLDP_AGENT_STOP 0x0
#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 #define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1
#define I40E_AQ_LLDP_AGENT_STOP_PERSIST 0x2
u8 reserved[15]; u8 reserved[15];
}; };
I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop);
/* Start LLDP (direct 0x0A06) */ /* Start LLDP (direct 0x0A06) */
struct i40e_aqc_lldp_start { struct i40e_aqc_lldp_start {
u8 command; u8 command;
#define I40E_AQ_LLDP_AGENT_START 0x1 #define I40E_AQ_LLDP_AGENT_START 0x1
#define I40E_AQ_LLDP_AGENT_START_PERSIST 0x2
u8 reserved[15]; u8 reserved[15];
}; };
...@@ -2633,6 +2635,16 @@ struct i40e_aqc_lldp_stop_start_specific_agent { ...@@ -2633,6 +2635,16 @@ struct i40e_aqc_lldp_stop_start_specific_agent {
I40E_CHECK_CMD_LENGTH(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) */ /* Add Udp Tunnel command and completion (direct 0x0B00) */
struct i40e_aqc_add_udp_tunnel { struct i40e_aqc_add_udp_tunnel {
__le16 udp_port; __le16 udp_port;
......
...@@ -3623,15 +3623,55 @@ i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw, ...@@ -3623,15 +3623,55 @@ i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
return status; 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 * i40e_aq_stop_lldp
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
* @shutdown_agent: True if LLDP Agent needs to be Shutdown * @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 * @cmd_details: pointer to command details structure or NULL
* *
* Stop or Shutdown the embedded LLDP Agent * Stop or Shutdown the embedded LLDP Agent
**/ **/
i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_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_asq_cmd_details *cmd_details)
{ {
struct i40e_aq_desc desc; struct i40e_aq_desc desc;
...@@ -3644,6 +3684,14 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, ...@@ -3644,6 +3684,14 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
if (shutdown_agent) if (shutdown_agent)
cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN; 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); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status; return status;
...@@ -3653,13 +3701,14 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, ...@@ -3653,13 +3701,14 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
* i40e_aq_start_lldp * i40e_aq_start_lldp
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
* @buff: buffer for result * @buff: buffer for result
* @persist: True if start of LLDP should be persistent across power cycles
* @buff_size: buffer size * @buff_size: buffer size
* @cmd_details: pointer to command details structure or NULL * @cmd_details: pointer to command details structure or NULL
* *
* Start the embedded LLDP Agent on all ports. * 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_asq_cmd_details *cmd_details)
{ {
struct i40e_aq_desc desc; struct i40e_aq_desc desc;
struct i40e_aqc_lldp_start *cmd = struct i40e_aqc_lldp_start *cmd =
...@@ -3669,6 +3718,15 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, ...@@ -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); i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
cmd->command = I40E_AQ_LLDP_AGENT_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); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status; return status;
......
...@@ -1321,7 +1321,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, ...@@ -1321,7 +1321,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
if (strncmp(&cmd_buf[5], "stop", 4) == 0) { if (strncmp(&cmd_buf[5], "stop", 4) == 0) {
int ret; int ret;
ret = i40e_aq_stop_lldp(&pf->hw, false, NULL); ret = i40e_aq_stop_lldp(&pf->hw, false, false, NULL);
if (ret) { if (ret) {
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"Stop LLDP AQ command failed =0x%x\n", "Stop LLDP AQ command failed =0x%x\n",
...@@ -1358,7 +1358,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, ...@@ -1358,7 +1358,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
/* Continue and start FW LLDP anyways */ /* 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) { if (ret) {
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"Start LLDP AQ command failed =0x%x\n", "Start LLDP AQ command failed =0x%x\n",
......
...@@ -4958,7 +4958,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) ...@@ -4958,7 +4958,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) { if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
struct i40e_dcbx_config *dcbcfg; 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); i40e_aq_set_dcb_parameters(&pf->hw, true, NULL);
/* reset local_dcbx_config to default */ /* reset local_dcbx_config to default */
dcbcfg = &pf->hw.local_dcbx_config; dcbcfg = &pf->hw.local_dcbx_config;
...@@ -4973,7 +4973,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) ...@@ -4973,7 +4973,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
dcbcfg->pfc.willing = 1; dcbcfg->pfc.willing = 1;
dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS; dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
} else { } else {
i40e_aq_start_lldp(&pf->hw, NULL); i40e_aq_start_lldp(&pf->hw, false, NULL);
} }
} }
......
...@@ -14132,7 +14132,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -14132,7 +14132,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/ */
if (pf->hw_features & I40E_HW_STOP_FW_LLDP) { if (pf->hw_features & I40E_HW_STOP_FW_LLDP) {
dev_info(&pdev->dev, "Stopping firmware LLDP agent.\n"); dev_info(&pdev->dev, "Stopping firmware LLDP agent.\n");
i40e_aq_stop_lldp(hw, true, NULL); i40e_aq_stop_lldp(hw, true, false, NULL);
} }
/* allow a platform config to override the HW addr */ /* allow a platform config to override the HW addr */
......
...@@ -203,14 +203,18 @@ i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type, ...@@ -203,14 +203,18 @@ i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw, i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
bool enable_update, bool enable_update,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code
i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_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_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_dcb_parameters(struct i40e_hw *hw, i40e_status i40e_aq_set_dcb_parameters(struct i40e_hw *hw,
bool dcb_enable, bool dcb_enable,
struct i40e_asq_cmd_details struct i40e_asq_cmd_details
*cmd_details); *cmd_details);
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_asq_cmd_details *cmd_details);
i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw, i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
void *buff, u16 buff_size, void *buff, u16 buff_size,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
......
...@@ -616,6 +616,7 @@ struct i40e_hw { ...@@ -616,6 +616,7 @@ struct i40e_hw {
#define I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE BIT_ULL(2) #define I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE BIT_ULL(2)
#define I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3) #define I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3)
#define I40E_HW_FLAG_FW_LLDP_STOPPABLE BIT_ULL(4) #define I40E_HW_FLAG_FW_LLDP_STOPPABLE BIT_ULL(4)
#define I40E_HW_FLAG_FW_LLDP_PERSISTENT BIT_ULL(5)
u64 flags; u64 flags;
/* Used in set switch config AQ command */ /* Used in set switch config AQ command */
......
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