Commit 7715ec32 authored by Grishma Kotecha's avatar Grishma Kotecha Committed by Tony Nguyen

ice: implement low level recipes functions

Add code to manage recipes and profiles on admin queue layer.

Allow the driver to add a new recipe and update an existing one. Get a
recipe and get a recipe to profile association is mostly used in update
existing recipes code.

Only default recipes can be updated. An update is done by reading recipes
from HW, changing their params and calling add recipe command.

Support following admin queue commands:
- ice_aqc_opc_add_recipe (0x0290) - create a recipe with protocol
header information and other details that determine how this recipe
filter works
- ice_aqc_opc_recipe_to_profile (0x0291) - associate a switch recipe
to a profile
- ice_aqc_opc_get_recipe (0x0292) - get details of an existing recipe
- ice_aqc_opc_get_recipe_to_profile (0x0293) - get a recipe associated
with profile ID

Define ICE_AQC_RES_TYPE_RECIPE resource type to hold a switch
recipe. It is needed when a new switch recipe needs to be created.
Co-developed-by: default avatarDan Nowlin <dan.nowlin@intel.com>
Signed-off-by: default avatarDan Nowlin <dan.nowlin@intel.com>
Signed-off-by: default avatarGrishma Kotecha  <grishma.kotecha@intel.com>
Signed-off-by: default avatarWojciech Drewek <wojciech.drewek@intel.com>
Tested-by: default avatarSandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent ce8bd03c
......@@ -233,6 +233,7 @@ struct ice_aqc_get_sw_cfg_resp_elem {
*/
#define ICE_AQC_RES_TYPE_VSI_LIST_REP 0x03
#define ICE_AQC_RES_TYPE_VSI_LIST_PRUNE 0x04
#define ICE_AQC_RES_TYPE_RECIPE 0x05
#define ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK 0x21
#define ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES 0x22
#define ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES 0x23
......@@ -241,6 +242,7 @@ struct ice_aqc_get_sw_cfg_resp_elem {
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID 0x60
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM 0x61
#define ICE_AQC_RES_TYPE_FLAG_SHARED BIT(7)
#define ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM BIT(12)
#define ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX BIT(13)
......@@ -474,6 +476,53 @@ struct ice_aqc_vsi_props {
#define ICE_MAX_NUM_RECIPES 64
/* Add/Get Recipe (indirect 0x0290/0x0292) */
struct ice_aqc_add_get_recipe {
__le16 num_sub_recipes; /* Input in Add cmd, Output in Get cmd */
__le16 return_index; /* Input, used for Get cmd only */
u8 reserved[4];
__le32 addr_high;
__le32 addr_low;
};
struct ice_aqc_recipe_content {
u8 rid;
#define ICE_AQ_RECIPE_ID_IS_ROOT BIT(7)
#define ICE_AQ_SW_ID_LKUP_IDX 0
u8 lkup_indx[5];
#define ICE_AQ_RECIPE_LKUP_IGNORE BIT(7)
#define ICE_AQ_SW_ID_LKUP_MASK 0x00FF
__le16 mask[5];
u8 result_indx;
#define ICE_AQ_RECIPE_RESULT_DATA_S 0
#define ICE_AQ_RECIPE_RESULT_DATA_M (0x3F << ICE_AQ_RECIPE_RESULT_DATA_S)
#define ICE_AQ_RECIPE_RESULT_EN BIT(7)
u8 rsvd0[3];
u8 act_ctrl_join_priority;
u8 act_ctrl_fwd_priority;
u8 act_ctrl;
#define ICE_AQ_RECIPE_ACT_INV_ACT BIT(2)
u8 rsvd1;
__le32 dflt_act;
};
struct ice_aqc_recipe_data_elem {
u8 recipe_indx;
u8 resp_bits;
u8 rsvd0[2];
u8 recipe_bitmap[8];
u8 rsvd1[4];
struct ice_aqc_recipe_content content;
u8 rsvd2[20];
};
/* Set/Get Recipes to Profile Association (direct 0x0291/0x0293) */
struct ice_aqc_recipe_to_profile {
__le16 profile_id;
u8 rsvd[6];
DECLARE_BITMAP(recipe_assoc, ICE_MAX_NUM_RECIPES);
};
/* Add/Update/Remove/Get switch rules (indirect 0x02A0, 0x02A1, 0x02A2, 0x02A3)
*/
struct ice_aqc_sw_rules {
......@@ -1936,6 +1985,8 @@ struct ice_aq_desc {
struct ice_aqc_set_port_id_led set_port_id_led;
struct ice_aqc_get_sw_cfg get_sw_conf;
struct ice_aqc_sw_rules sw_rules;
struct ice_aqc_add_get_recipe add_get_recipe;
struct ice_aqc_recipe_to_profile recipe_to_profile;
struct ice_aqc_get_topo get_topo;
struct ice_aqc_sched_elem_cmd sched_elem_cmd;
struct ice_aqc_query_txsched_res query_sched_res;
......@@ -2044,6 +2095,12 @@ enum ice_adminq_opc {
ice_aqc_opc_update_vsi = 0x0211,
ice_aqc_opc_free_vsi = 0x0213,
/* recipe commands */
ice_aqc_opc_add_recipe = 0x0290,
ice_aqc_opc_recipe_to_profile = 0x0291,
ice_aqc_opc_get_recipe = 0x0292,
ice_aqc_opc_get_recipe_to_profile = 0x0293,
/* switch rules population commands */
ice_aqc_opc_add_sw_rules = 0x02A0,
ice_aqc_opc_update_sw_rules = 0x02A1,
......
......@@ -543,6 +543,161 @@ ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
return status;
}
/**
* ice_aq_add_recipe - add switch recipe
* @hw: pointer to the HW struct
* @s_recipe_list: pointer to switch rule population list
* @num_recipes: number of switch recipes in the list
* @cd: pointer to command details structure or NULL
*
* Add(0x0290)
*/
static enum ice_status __maybe_unused
ice_aq_add_recipe(struct ice_hw *hw,
struct ice_aqc_recipe_data_elem *s_recipe_list,
u16 num_recipes, struct ice_sq_cd *cd)
{
struct ice_aqc_add_get_recipe *cmd;
struct ice_aq_desc desc;
u16 buf_size;
cmd = &desc.params.add_get_recipe;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
cmd->num_sub_recipes = cpu_to_le16(num_recipes);
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
buf_size = num_recipes * sizeof(*s_recipe_list);
return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
}
/**
* ice_aq_get_recipe - get switch recipe
* @hw: pointer to the HW struct
* @s_recipe_list: pointer to switch rule population list
* @num_recipes: pointer to the number of recipes (input and output)
* @recipe_root: root recipe number of recipe(s) to retrieve
* @cd: pointer to command details structure or NULL
*
* Get(0x0292)
*
* On input, *num_recipes should equal the number of entries in s_recipe_list.
* On output, *num_recipes will equal the number of entries returned in
* s_recipe_list.
*
* The caller must supply enough space in s_recipe_list to hold all possible
* recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
*/
static enum ice_status __maybe_unused
ice_aq_get_recipe(struct ice_hw *hw,
struct ice_aqc_recipe_data_elem *s_recipe_list,
u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
{
struct ice_aqc_add_get_recipe *cmd;
struct ice_aq_desc desc;
enum ice_status status;
u16 buf_size;
if (*num_recipes != ICE_MAX_NUM_RECIPES)
return ICE_ERR_PARAM;
cmd = &desc.params.add_get_recipe;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
cmd->return_index = cpu_to_le16(recipe_root);
cmd->num_sub_recipes = 0;
buf_size = *num_recipes * sizeof(*s_recipe_list);
status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
*num_recipes = le16_to_cpu(cmd->num_sub_recipes);
return status;
}
/**
* ice_aq_map_recipe_to_profile - Map recipe to packet profile
* @hw: pointer to the HW struct
* @profile_id: package profile ID to associate the recipe with
* @r_bitmap: Recipe bitmap filled in and need to be returned as response
* @cd: pointer to command details structure or NULL
* Recipe to profile association (0x0291)
*/
static enum ice_status __maybe_unused
ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
struct ice_sq_cd *cd)
{
struct ice_aqc_recipe_to_profile *cmd;
struct ice_aq_desc desc;
cmd = &desc.params.recipe_to_profile;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
cmd->profile_id = cpu_to_le16(profile_id);
/* Set the recipe ID bit in the bitmask to let the device know which
* profile we are associating the recipe to
*/
memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc));
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
/**
* ice_aq_get_recipe_to_profile - Map recipe to packet profile
* @hw: pointer to the HW struct
* @profile_id: package profile ID to associate the recipe with
* @r_bitmap: Recipe bitmap filled in and need to be returned as response
* @cd: pointer to command details structure or NULL
* Associate profile ID with given recipe (0x0293)
*/
static enum ice_status __maybe_unused
ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
struct ice_sq_cd *cd)
{
struct ice_aqc_recipe_to_profile *cmd;
struct ice_aq_desc desc;
enum ice_status status;
cmd = &desc.params.recipe_to_profile;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
cmd->profile_id = cpu_to_le16(profile_id);
status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
if (!status)
memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc));
return status;
}
/**
* ice_alloc_recipe - add recipe resource
* @hw: pointer to the hardware structure
* @rid: recipe ID returned as response to AQ call
*/
static enum ice_status __maybe_unused ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
{
struct ice_aqc_alloc_free_res_elem *sw_buf;
enum ice_status status;
u16 buf_len;
buf_len = struct_size(sw_buf, elem, 1);
sw_buf = kzalloc(buf_len, GFP_KERNEL);
if (!sw_buf)
return ICE_ERR_NO_MEMORY;
sw_buf->num_elems = cpu_to_le16(1);
sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE <<
ICE_AQC_RES_TYPE_S) |
ICE_AQC_RES_TYPE_FLAG_SHARED);
status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
ice_aqc_opc_alloc_res, NULL);
if (!status)
*rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
kfree(sw_buf);
return status;
}
/* ice_init_port_info - Initialize port_info with switch configuration data
* @pi: pointer to port_info
* @vsi_port_num: VSI number or port number
......
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