Commit b3237df9 authored by Jedrzej Jagielski's avatar Jedrzej Jagielski Committed by Tony Nguyen

i40e: Add new version of i40e_aq_add_macvlan function

ASQ send command functions are returning only i40e status codes
yet some calling functions also need Admin Queue status
that is stored in hw->aq.asq_last_status. Since hw object
is stored on a heap it introduces a possibility for
a race condition in access to hw if calling function is not
fast enough to read hw->aq.asq_last_status before next
send ASQ command is executed.

Add new _v2 version of i40e_aq_add_macvlan that is using
new _v2 versions of ASQ send command functions and returns
the Admin Queue status on the stack.
Signed-off-by: default avatarSylwester Dziedziuch <sylwesterx.dziedziuch@intel.com>
Signed-off-by: default avatarJedrzej Jagielski <jedrzej.jagielski@intel.com>
Tested-by: default avatarGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 74073848
...@@ -2634,33 +2634,28 @@ i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw, ...@@ -2634,33 +2634,28 @@ i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
} }
/** /**
* i40e_aq_add_macvlan * i40e_prepare_add_macvlan
* @hw: pointer to the hw struct
* @seid: VSI for the mac address
* @mv_list: list of macvlans to be added * @mv_list: list of macvlans to be added
* @desc: pointer to AQ descriptor structure
* @count: length of the list * @count: length of the list
* @cmd_details: pointer to command details structure or NULL * @seid: VSI for the mac address
* *
* Add MAC/VLAN addresses to the HW filtering * Internal helper function that prepares the add macvlan request
* and returns the buffer size.
**/ **/
i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, static u16
struct i40e_aqc_add_macvlan_element_data *mv_list, i40e_prepare_add_macvlan(struct i40e_aqc_add_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details) struct i40e_aq_desc *desc, u16 count, u16 seid)
{ {
struct i40e_aq_desc desc;
struct i40e_aqc_macvlan *cmd = struct i40e_aqc_macvlan *cmd =
(struct i40e_aqc_macvlan *)&desc.params.raw; (struct i40e_aqc_macvlan *)&desc->params.raw;
i40e_status status;
u16 buf_size; u16 buf_size;
int i; int i;
if (count == 0 || !mv_list || !hw)
return I40E_ERR_PARAM;
buf_size = count * sizeof(*mv_list); buf_size = count * sizeof(*mv_list);
/* prep the rest of the request */ /* prep the rest of the request */
i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan); i40e_fill_default_direct_cmd_desc(desc, i40e_aqc_opc_add_macvlan);
cmd->num_addresses = cpu_to_le16(count); cmd->num_addresses = cpu_to_le16(count);
cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid); cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
cmd->seid[1] = 0; cmd->seid[1] = 0;
...@@ -2671,14 +2666,71 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, ...@@ -2671,14 +2666,71 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
mv_list[i].flags |= mv_list[i].flags |=
cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC); cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); desc->flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
if (buf_size > I40E_AQ_LARGE_BUF) if (buf_size > I40E_AQ_LARGE_BUF)
desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB); desc->flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
status = i40e_asq_send_command_atomic(hw, &desc, mv_list, buf_size, return buf_size;
cmd_details, true); }
return status; /**
* i40e_aq_add_macvlan
* @hw: pointer to the hw struct
* @seid: VSI for the mac address
* @mv_list: list of macvlans to be added
* @count: length of the list
* @cmd_details: pointer to command details structure or NULL
*
* Add MAC/VLAN addresses to the HW filtering
**/
i40e_status
i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_add_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
u16 buf_size;
if (count == 0 || !mv_list || !hw)
return I40E_ERR_PARAM;
buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid);
return i40e_asq_send_command_atomic(hw, &desc, mv_list, buf_size,
cmd_details, true);
}
/**
* i40e_aq_add_macvlan_v2
* @hw: pointer to the hw struct
* @seid: VSI for the mac address
* @mv_list: list of macvlans to be added
* @count: length of the list
* @cmd_details: pointer to command details structure or NULL
* @aq_status: pointer to Admin Queue status return value
*
* Add MAC/VLAN addresses to the HW filtering.
* The _v2 version returns the last Admin Queue status in aq_status
* to avoid race conditions in access to hw->aq.asq_last_status.
* It also calls _v2 versions of asq_send_command functions to
* get the aq_status on the stack.
**/
i40e_status
i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_add_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details,
enum i40e_admin_queue_err *aq_status)
{
struct i40e_aq_desc desc;
u16 buf_size;
if (count == 0 || !mv_list || !hw)
return I40E_ERR_PARAM;
buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid);
return i40e_asq_send_command_atomic_v2(hw, &desc, mv_list, buf_size,
cmd_details, true, aq_status);
} }
/** /**
......
...@@ -165,6 +165,11 @@ i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw, ...@@ -165,6 +165,11 @@ i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 vsi_id, i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 vsi_id,
struct i40e_aqc_add_macvlan_element_data *mv_list, struct i40e_aqc_add_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details); u16 count, struct i40e_asq_cmd_details *cmd_details);
i40e_status
i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_add_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details,
enum i40e_admin_queue_err *aq_status);
i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id, i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id,
struct i40e_aqc_remove_macvlan_element_data *mv_list, struct i40e_aqc_remove_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details); u16 count, struct i40e_asq_cmd_details *cmd_details);
......
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