Skip to content

Commit 7715ec3

Browse files
Grishma Kotechaanguy11
authored andcommitted
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: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Grishma Kotecha <grishma.kotecha@intel.com> Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent ce8bd03 commit 7715ec3

File tree

2 files changed

+212
-0
lines changed

2 files changed

+212
-0
lines changed

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ struct ice_aqc_get_sw_cfg_resp_elem {
233233
*/
234234
#define ICE_AQC_RES_TYPE_VSI_LIST_REP 0x03
235235
#define ICE_AQC_RES_TYPE_VSI_LIST_PRUNE 0x04
236+
#define ICE_AQC_RES_TYPE_RECIPE 0x05
236237
#define ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK 0x21
237238
#define ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES 0x22
238239
#define ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES 0x23
@@ -241,6 +242,7 @@ struct ice_aqc_get_sw_cfg_resp_elem {
241242
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID 0x60
242243
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM 0x61
243244

245+
#define ICE_AQC_RES_TYPE_FLAG_SHARED BIT(7)
244246
#define ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM BIT(12)
245247
#define ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX BIT(13)
246248

@@ -474,6 +476,53 @@ struct ice_aqc_vsi_props {
474476

475477
#define ICE_MAX_NUM_RECIPES 64
476478

479+
/* Add/Get Recipe (indirect 0x0290/0x0292) */
480+
struct ice_aqc_add_get_recipe {
481+
__le16 num_sub_recipes; /* Input in Add cmd, Output in Get cmd */
482+
__le16 return_index; /* Input, used for Get cmd only */
483+
u8 reserved[4];
484+
__le32 addr_high;
485+
__le32 addr_low;
486+
};
487+
488+
struct ice_aqc_recipe_content {
489+
u8 rid;
490+
#define ICE_AQ_RECIPE_ID_IS_ROOT BIT(7)
491+
#define ICE_AQ_SW_ID_LKUP_IDX 0
492+
u8 lkup_indx[5];
493+
#define ICE_AQ_RECIPE_LKUP_IGNORE BIT(7)
494+
#define ICE_AQ_SW_ID_LKUP_MASK 0x00FF
495+
__le16 mask[5];
496+
u8 result_indx;
497+
#define ICE_AQ_RECIPE_RESULT_DATA_S 0
498+
#define ICE_AQ_RECIPE_RESULT_DATA_M (0x3F << ICE_AQ_RECIPE_RESULT_DATA_S)
499+
#define ICE_AQ_RECIPE_RESULT_EN BIT(7)
500+
u8 rsvd0[3];
501+
u8 act_ctrl_join_priority;
502+
u8 act_ctrl_fwd_priority;
503+
u8 act_ctrl;
504+
#define ICE_AQ_RECIPE_ACT_INV_ACT BIT(2)
505+
u8 rsvd1;
506+
__le32 dflt_act;
507+
};
508+
509+
struct ice_aqc_recipe_data_elem {
510+
u8 recipe_indx;
511+
u8 resp_bits;
512+
u8 rsvd0[2];
513+
u8 recipe_bitmap[8];
514+
u8 rsvd1[4];
515+
struct ice_aqc_recipe_content content;
516+
u8 rsvd2[20];
517+
};
518+
519+
/* Set/Get Recipes to Profile Association (direct 0x0291/0x0293) */
520+
struct ice_aqc_recipe_to_profile {
521+
__le16 profile_id;
522+
u8 rsvd[6];
523+
DECLARE_BITMAP(recipe_assoc, ICE_MAX_NUM_RECIPES);
524+
};
525+
477526
/* Add/Update/Remove/Get switch rules (indirect 0x02A0, 0x02A1, 0x02A2, 0x02A3)
478527
*/
479528
struct ice_aqc_sw_rules {
@@ -1936,6 +1985,8 @@ struct ice_aq_desc {
19361985
struct ice_aqc_set_port_id_led set_port_id_led;
19371986
struct ice_aqc_get_sw_cfg get_sw_conf;
19381987
struct ice_aqc_sw_rules sw_rules;
1988+
struct ice_aqc_add_get_recipe add_get_recipe;
1989+
struct ice_aqc_recipe_to_profile recipe_to_profile;
19391990
struct ice_aqc_get_topo get_topo;
19401991
struct ice_aqc_sched_elem_cmd sched_elem_cmd;
19411992
struct ice_aqc_query_txsched_res query_sched_res;
@@ -2044,6 +2095,12 @@ enum ice_adminq_opc {
20442095
ice_aqc_opc_update_vsi = 0x0211,
20452096
ice_aqc_opc_free_vsi = 0x0213,
20462097

2098+
/* recipe commands */
2099+
ice_aqc_opc_add_recipe = 0x0290,
2100+
ice_aqc_opc_recipe_to_profile = 0x0291,
2101+
ice_aqc_opc_get_recipe = 0x0292,
2102+
ice_aqc_opc_get_recipe_to_profile = 0x0293,
2103+
20472104
/* switch rules population commands */
20482105
ice_aqc_opc_add_sw_rules = 0x02A0,
20492106
ice_aqc_opc_update_sw_rules = 0x02A1,

drivers/net/ethernet/intel/ice/ice_switch.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,161 @@ ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
543543
return status;
544544
}
545545

546+
/**
547+
* ice_aq_add_recipe - add switch recipe
548+
* @hw: pointer to the HW struct
549+
* @s_recipe_list: pointer to switch rule population list
550+
* @num_recipes: number of switch recipes in the list
551+
* @cd: pointer to command details structure or NULL
552+
*
553+
* Add(0x0290)
554+
*/
555+
static enum ice_status __maybe_unused
556+
ice_aq_add_recipe(struct ice_hw *hw,
557+
struct ice_aqc_recipe_data_elem *s_recipe_list,
558+
u16 num_recipes, struct ice_sq_cd *cd)
559+
{
560+
struct ice_aqc_add_get_recipe *cmd;
561+
struct ice_aq_desc desc;
562+
u16 buf_size;
563+
564+
cmd = &desc.params.add_get_recipe;
565+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
566+
567+
cmd->num_sub_recipes = cpu_to_le16(num_recipes);
568+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
569+
570+
buf_size = num_recipes * sizeof(*s_recipe_list);
571+
572+
return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
573+
}
574+
575+
/**
576+
* ice_aq_get_recipe - get switch recipe
577+
* @hw: pointer to the HW struct
578+
* @s_recipe_list: pointer to switch rule population list
579+
* @num_recipes: pointer to the number of recipes (input and output)
580+
* @recipe_root: root recipe number of recipe(s) to retrieve
581+
* @cd: pointer to command details structure or NULL
582+
*
583+
* Get(0x0292)
584+
*
585+
* On input, *num_recipes should equal the number of entries in s_recipe_list.
586+
* On output, *num_recipes will equal the number of entries returned in
587+
* s_recipe_list.
588+
*
589+
* The caller must supply enough space in s_recipe_list to hold all possible
590+
* recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
591+
*/
592+
static enum ice_status __maybe_unused
593+
ice_aq_get_recipe(struct ice_hw *hw,
594+
struct ice_aqc_recipe_data_elem *s_recipe_list,
595+
u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
596+
{
597+
struct ice_aqc_add_get_recipe *cmd;
598+
struct ice_aq_desc desc;
599+
enum ice_status status;
600+
u16 buf_size;
601+
602+
if (*num_recipes != ICE_MAX_NUM_RECIPES)
603+
return ICE_ERR_PARAM;
604+
605+
cmd = &desc.params.add_get_recipe;
606+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
607+
608+
cmd->return_index = cpu_to_le16(recipe_root);
609+
cmd->num_sub_recipes = 0;
610+
611+
buf_size = *num_recipes * sizeof(*s_recipe_list);
612+
613+
status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
614+
*num_recipes = le16_to_cpu(cmd->num_sub_recipes);
615+
616+
return status;
617+
}
618+
619+
/**
620+
* ice_aq_map_recipe_to_profile - Map recipe to packet profile
621+
* @hw: pointer to the HW struct
622+
* @profile_id: package profile ID to associate the recipe with
623+
* @r_bitmap: Recipe bitmap filled in and need to be returned as response
624+
* @cd: pointer to command details structure or NULL
625+
* Recipe to profile association (0x0291)
626+
*/
627+
static enum ice_status __maybe_unused
628+
ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
629+
struct ice_sq_cd *cd)
630+
{
631+
struct ice_aqc_recipe_to_profile *cmd;
632+
struct ice_aq_desc desc;
633+
634+
cmd = &desc.params.recipe_to_profile;
635+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
636+
cmd->profile_id = cpu_to_le16(profile_id);
637+
/* Set the recipe ID bit in the bitmask to let the device know which
638+
* profile we are associating the recipe to
639+
*/
640+
memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc));
641+
642+
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
643+
}
644+
645+
/**
646+
* ice_aq_get_recipe_to_profile - Map recipe to packet profile
647+
* @hw: pointer to the HW struct
648+
* @profile_id: package profile ID to associate the recipe with
649+
* @r_bitmap: Recipe bitmap filled in and need to be returned as response
650+
* @cd: pointer to command details structure or NULL
651+
* Associate profile ID with given recipe (0x0293)
652+
*/
653+
static enum ice_status __maybe_unused
654+
ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
655+
struct ice_sq_cd *cd)
656+
{
657+
struct ice_aqc_recipe_to_profile *cmd;
658+
struct ice_aq_desc desc;
659+
enum ice_status status;
660+
661+
cmd = &desc.params.recipe_to_profile;
662+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
663+
cmd->profile_id = cpu_to_le16(profile_id);
664+
665+
status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
666+
if (!status)
667+
memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc));
668+
669+
return status;
670+
}
671+
672+
/**
673+
* ice_alloc_recipe - add recipe resource
674+
* @hw: pointer to the hardware structure
675+
* @rid: recipe ID returned as response to AQ call
676+
*/
677+
static enum ice_status __maybe_unused ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
678+
{
679+
struct ice_aqc_alloc_free_res_elem *sw_buf;
680+
enum ice_status status;
681+
u16 buf_len;
682+
683+
buf_len = struct_size(sw_buf, elem, 1);
684+
sw_buf = kzalloc(buf_len, GFP_KERNEL);
685+
if (!sw_buf)
686+
return ICE_ERR_NO_MEMORY;
687+
688+
sw_buf->num_elems = cpu_to_le16(1);
689+
sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE <<
690+
ICE_AQC_RES_TYPE_S) |
691+
ICE_AQC_RES_TYPE_FLAG_SHARED);
692+
status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
693+
ice_aqc_opc_alloc_res, NULL);
694+
if (!status)
695+
*rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
696+
kfree(sw_buf);
697+
698+
return status;
699+
}
700+
546701
/* ice_init_port_info - Initialize port_info with switch configuration data
547702
* @pi: pointer to port_info
548703
* @vsi_port_num: VSI number or port number

0 commit comments

Comments
 (0)