Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
ice: Switch API optimizations

Marcin Szycik says:

Optimize the process of creating a recipe in the switch block by removing
duplicate switch ID words and changing how result indexes are fitted into
recipes. In many cases this can decrease the number of recipes required to
add a certain set of rules, potentially allowing a more varied set of rules
to be created. Total rule count will also increase, since less words will
be left unused/wasted. There are only 64 rules available in total, so every
one counts.

After this modification, many fields and some structs became unused or were
simplified, resulting in overall simpler implementation.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
ice: Add tracepoint for adding and removing switch rules
ice: Remove unused members from switch API
ice: Optimize switch recipe creation
ice: remove unused recipe bookkeeping data
ice: Simplify bitmap setting in adding recipe
ice: Remove reading all recipes before adding a new one
ice: Remove unused struct ice_prot_lkup_ext members
====================

Link: https://patch.msgid.link/20240711181312.2019606-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+283 -507
+3 -8
drivers/net/ethernet/intel/ice/ice_common.c
··· 934 934 INIT_LIST_HEAD(&sw->vsi_list_map_head); 935 935 sw->prof_res_bm_init = 0; 936 936 937 + /* Initialize recipe count with default recipes read from NVM */ 938 + sw->recp_cnt = ICE_SW_LKUP_LAST; 939 + 937 940 status = ice_init_def_sw_recp(hw); 938 941 if (status) { 939 942 devm_kfree(ice_hw_to_dev(hw), hw->switch_info); ··· 964 961 } 965 962 recps = sw->recp_list; 966 963 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 967 - struct ice_recp_grp_entry *rg_entry, *tmprg_entry; 968 - 969 964 recps[i].root_rid = i; 970 - list_for_each_entry_safe(rg_entry, tmprg_entry, 971 - &recps[i].rg_list, l_entry) { 972 - list_del(&rg_entry->l_entry); 973 - devm_kfree(ice_hw_to_dev(hw), rg_entry); 974 - } 975 965 976 966 if (recps[i].adv_rule) { 977 967 struct ice_adv_fltr_mgmt_list_entry *tmp_entry; ··· 989 993 devm_kfree(ice_hw_to_dev(hw), lst_itr); 990 994 } 991 995 } 992 - devm_kfree(ice_hw_to_dev(hw), recps[i].root_buf); 993 996 } 994 997 ice_rm_all_sw_replay_rule_info(hw); 995 998 devm_kfree(ice_hw_to_dev(hw), sw->recp_list);
+14 -29
drivers/net/ethernet/intel/ice/ice_protocol_type.h
··· 7 7 8 8 /* Each recipe can match up to 5 different fields. Fields to match can be meta- 9 9 * data, values extracted from packet headers, or results from other recipes. 10 - * One of the 5 fields is reserved for matching the switch ID. So, up to 4 11 - * recipes can provide intermediate results to another one through chaining, 12 - * e.g. recipes 0, 1, 2, and 3 can provide intermediate results to recipe 4. 10 + * Therefore, up to 5 recipes can provide intermediate results to another one 11 + * through chaining, e.g. recipes 0, 1, 2, 3 and 4 can provide intermediate 12 + * results to recipe 5. Note that one of the fields in one of the recipes must 13 + * always be reserved for matching the switch ID. 13 14 */ 14 - #define ICE_NUM_WORDS_RECIPE 4 15 + #define ICE_NUM_WORDS_RECIPE 5 15 16 16 - /* Max recipes that can be chained */ 17 + /* Max recipes that can be chained, not including the last one, which combines 18 + * intermediate results. 19 + */ 17 20 #define ICE_MAX_CHAIN_RECIPE 5 18 21 19 - /* 1 word reserved for switch ID from allowed 5 words. 20 - * So a recipe can have max 4 words. And you can chain 5 such recipes 21 - * together. So maximum words that can be programmed for look up is 5 * 4. 22 + /* Total max recipes in chain recipe (including intermediate results) */ 23 + #define ICE_MAX_CHAIN_RECIPE_RES (ICE_MAX_CHAIN_RECIPE + 1) 24 + 25 + /* A recipe can have max 5 words, and 5 recipes can be chained together (using 26 + * the 6th one, which would contain only result indexes). So maximum words that 27 + * can be programmed for lookup is 5 * 5 (not including intermediate results). 22 28 */ 23 29 #define ICE_MAX_CHAIN_WORDS (ICE_NUM_WORDS_RECIPE * ICE_MAX_CHAIN_RECIPE) 24 30 ··· 455 449 456 450 /* Extractions to be looked up for a given recipe */ 457 451 struct ice_prot_lkup_ext { 458 - u16 prot_type; 459 452 u8 n_val_words; 460 453 /* create a buffer to hold max words per recipe */ 461 - u16 field_off[ICE_MAX_CHAIN_WORDS]; 462 454 u16 field_mask[ICE_MAX_CHAIN_WORDS]; 463 455 464 456 struct ice_fv_word fv_words[ICE_MAX_CHAIN_WORDS]; 465 - 466 - /* Indicate field offsets that have field vector indices assigned */ 467 - DECLARE_BITMAP(done, ICE_MAX_CHAIN_WORDS); 468 457 }; 469 458 470 - struct ice_pref_recipe_group { 471 - u8 n_val_pairs; /* Number of valid pairs */ 472 - struct ice_fv_word pairs[ICE_NUM_WORDS_RECIPE]; 473 - u16 mask[ICE_NUM_WORDS_RECIPE]; 474 - }; 475 - 476 - struct ice_recp_grp_entry { 477 - struct list_head l_entry; 478 - 479 - #define ICE_INVAL_CHAIN_IND 0xFF 480 - u16 rid; 481 - u8 chain_idx; 482 - u16 fv_idx[ICE_NUM_WORDS_RECIPE]; 483 - u16 fv_mask[ICE_NUM_WORDS_RECIPE]; 484 - struct ice_pref_recipe_group r_group; 485 - }; 486 459 #endif /* _ICE_PROTOCOL_TYPE_H_ */
+244 -452
drivers/net/ethernet/intel/ice/ice_switch.c
··· 3 3 4 4 #include "ice_lib.h" 5 5 #include "ice_switch.h" 6 + #include "ice_trace.h" 6 7 7 8 #define ICE_ETH_DA_OFFSET 0 8 9 #define ICE_ETH_ETHTYPE_OFFSET 12 ··· 1472 1471 recps[i].root_rid = i; 1473 1472 INIT_LIST_HEAD(&recps[i].filt_rules); 1474 1473 INIT_LIST_HEAD(&recps[i].filt_replay_rules); 1475 - INIT_LIST_HEAD(&recps[i].rg_list); 1476 1474 mutex_init(&recps[i].filt_rule_lock); 1477 1475 } 1478 1476 ··· 1962 1962 hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 1963 1963 status = -ENOENT; 1964 1964 1965 + if (!status) { 1966 + if (opc == ice_aqc_opc_add_sw_rules) 1967 + hw->switch_info->rule_cnt += num_rules; 1968 + else if (opc == ice_aqc_opc_remove_sw_rules) 1969 + hw->switch_info->rule_cnt -= num_rules; 1970 + } 1971 + 1972 + trace_ice_aq_sw_rules(hw->switch_info); 1973 + 1965 1974 return status; 1966 1975 } 1967 1976 ··· 2191 2182 sw_buf->res_type = cpu_to_le16(res_type); 2192 2183 status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, 2193 2184 ice_aqc_opc_alloc_res); 2194 - if (!status) 2185 + if (!status) { 2195 2186 *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp); 2187 + hw->switch_info->recp_cnt++; 2188 + } 2196 2189 2197 2190 return status; 2198 2191 } ··· 2208 2197 */ 2209 2198 static int ice_free_recipe_res(struct ice_hw *hw, u16 rid) 2210 2199 { 2211 - return ice_free_hw_res(hw, ICE_AQC_RES_TYPE_RECIPE, 1, &rid); 2200 + int status; 2201 + 2202 + status = ice_free_hw_res(hw, ICE_AQC_RES_TYPE_RECIPE, 1, &rid); 2203 + if (!status) 2204 + hw->switch_info->recp_cnt--; 2205 + 2206 + return status; 2212 2207 } 2213 2208 2214 2209 /** ··· 2299 2282 } 2300 2283 2301 2284 /** 2302 - * ice_collect_result_idx - copy result index values 2303 - * @buf: buffer that contains the result index 2304 - * @recp: the recipe struct to copy data into 2305 - */ 2306 - static void 2307 - ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf, 2308 - struct ice_sw_recipe *recp) 2309 - { 2310 - if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2311 - set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN, 2312 - recp->res_idxs); 2313 - } 2314 - 2315 - /** 2316 2285 * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries 2317 2286 * @hw: pointer to hardware structure 2318 2287 * @recps: struct that we need to populate ··· 2356 2353 2357 2354 for (sub_recps = 0; sub_recps < num_recps; sub_recps++) { 2358 2355 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps]; 2359 - struct ice_recp_grp_entry *rg_entry; 2360 2356 u8 i, prof, idx, prot = 0; 2361 2357 bool is_root; 2362 2358 u16 off = 0; 2363 - 2364 - rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry), 2365 - GFP_KERNEL); 2366 - if (!rg_entry) { 2367 - status = -ENOMEM; 2368 - goto err_unroll; 2369 - } 2370 2359 2371 2360 idx = root_bufs.recipe_indx; 2372 2361 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT; ··· 2372 2377 prof = find_first_bit(recipe_to_profile[idx], 2373 2378 ICE_MAX_NUM_PROFILES); 2374 2379 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) { 2375 - u8 lkup_indx = root_bufs.content.lkup_indx[i + 1]; 2376 - 2377 - rg_entry->fv_idx[i] = lkup_indx; 2378 - rg_entry->fv_mask[i] = 2379 - le16_to_cpu(root_bufs.content.mask[i + 1]); 2380 + u8 lkup_indx = root_bufs.content.lkup_indx[i]; 2381 + u16 lkup_mask = le16_to_cpu(root_bufs.content.mask[i]); 2380 2382 2381 2383 /* If the recipe is a chained recipe then all its 2382 2384 * child recipe's result will have a result index. ··· 2384 2392 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a 2385 2393 * valid offset value. 2386 2394 */ 2387 - if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) || 2388 - rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE || 2389 - rg_entry->fv_idx[i] == 0) 2395 + if (!lkup_indx || 2396 + (lkup_indx & ICE_AQ_RECIPE_LKUP_IGNORE) || 2397 + test_bit(lkup_indx, 2398 + hw->switch_info->prof_res_bm[prof])) 2390 2399 continue; 2391 2400 2392 - ice_find_prot_off(hw, ICE_BLK_SW, prof, 2393 - rg_entry->fv_idx[i], &prot, &off); 2401 + ice_find_prot_off(hw, ICE_BLK_SW, prof, lkup_indx, 2402 + &prot, &off); 2394 2403 lkup_exts->fv_words[fv_word_idx].prot_id = prot; 2395 2404 lkup_exts->fv_words[fv_word_idx].off = off; 2396 - lkup_exts->field_mask[fv_word_idx] = 2397 - rg_entry->fv_mask[i]; 2405 + lkup_exts->field_mask[fv_word_idx] = lkup_mask; 2398 2406 fv_word_idx++; 2399 2407 } 2400 - /* populate rg_list with the data from the child entry of this 2401 - * recipe 2402 - */ 2403 - list_add(&rg_entry->l_entry, &recps[rid].rg_list); 2404 2408 2405 2409 /* Propagate some data to the recipe database */ 2406 - recps[idx].is_root = !!is_root; 2407 2410 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2408 2411 recps[idx].need_pass_l2 = root_bufs.content.act_ctrl & 2409 2412 ICE_AQ_RECIPE_ACT_NEED_PASS_L2; ··· 2406 2419 ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 2407 2420 bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS); 2408 2421 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) { 2409 - recps[idx].chain_idx = root_bufs.content.result_indx & 2410 - ~ICE_AQ_RECIPE_RESULT_EN; 2411 - set_bit(recps[idx].chain_idx, recps[idx].res_idxs); 2412 - } else { 2413 - recps[idx].chain_idx = ICE_INVAL_CHAIN_IND; 2422 + set_bit(root_bufs.content.result_indx & 2423 + ~ICE_AQ_RECIPE_RESULT_EN, recps[idx].res_idxs); 2414 2424 } 2415 2425 2416 2426 if (!is_root) { ··· 2427 2443 2428 2444 /* Complete initialization of the root recipe entry */ 2429 2445 lkup_exts->n_val_words = fv_word_idx; 2430 - recps[rid].big_recp = (num_recps > 1); 2431 - recps[rid].n_grp_count = (u8)num_recps; 2432 - recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp, 2433 - recps[rid].n_grp_count * sizeof(*recps[rid].root_buf), 2434 - GFP_KERNEL); 2435 - if (!recps[rid].root_buf) { 2436 - status = -ENOMEM; 2437 - goto err_unroll; 2438 - } 2439 2446 2440 2447 /* Copy result indexes */ 2441 2448 bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS); ··· 4743 4768 continue; 4744 4769 } 4745 4770 4746 - /* Skip inverse action recipes */ 4747 - if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 4748 - ICE_AQ_RECIPE_ACT_INV_ACT) 4749 - continue; 4750 - 4751 4771 /* if number of words we are looking for match */ 4752 4772 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 4753 4773 struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; ··· 4867 4897 } 4868 4898 4869 4899 /** 4870 - * ice_create_first_fit_recp_def - Create a recipe grouping 4871 - * @hw: pointer to the hardware structure 4872 - * @lkup_exts: an array of protocol header extractions 4873 - * @rg_list: pointer to a list that stores new recipe groups 4874 - * @recp_cnt: pointer to a variable that stores returned number of recipe groups 4875 - * 4876 - * Using first fit algorithm, take all the words that are still not done 4877 - * and start grouping them in 4-word groups. Each group makes up one 4878 - * recipe. 4879 - */ 4880 - static int 4881 - ice_create_first_fit_recp_def(struct ice_hw *hw, 4882 - struct ice_prot_lkup_ext *lkup_exts, 4883 - struct list_head *rg_list, 4884 - u8 *recp_cnt) 4885 - { 4886 - struct ice_pref_recipe_group *grp = NULL; 4887 - u8 j; 4888 - 4889 - *recp_cnt = 0; 4890 - 4891 - /* Walk through every word in the rule to check if it is not done. If so 4892 - * then this word needs to be part of a new recipe. 4893 - */ 4894 - for (j = 0; j < lkup_exts->n_val_words; j++) 4895 - if (!test_bit(j, lkup_exts->done)) { 4896 - if (!grp || 4897 - grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 4898 - struct ice_recp_grp_entry *entry; 4899 - 4900 - entry = devm_kzalloc(ice_hw_to_dev(hw), 4901 - sizeof(*entry), 4902 - GFP_KERNEL); 4903 - if (!entry) 4904 - return -ENOMEM; 4905 - list_add(&entry->l_entry, rg_list); 4906 - grp = &entry->r_group; 4907 - (*recp_cnt)++; 4908 - } 4909 - 4910 - grp->pairs[grp->n_val_pairs].prot_id = 4911 - lkup_exts->fv_words[j].prot_id; 4912 - grp->pairs[grp->n_val_pairs].off = 4913 - lkup_exts->fv_words[j].off; 4914 - grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 4915 - grp->n_val_pairs++; 4916 - } 4917 - 4918 - return 0; 4919 - } 4920 - 4921 - /** 4922 4900 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 4923 4901 * @hw: pointer to the hardware structure 4924 - * @fv_list: field vector with the extraction sequence information 4925 - * @rg_list: recipe groupings with protocol-offset pairs 4902 + * @rm: recipe management list entry 4926 4903 * 4927 4904 * Helper function to fill in the field vector indices for protocol-offset 4928 4905 * pairs. These indexes are then ultimately programmed into a recipe. 4929 4906 */ 4930 4907 static int 4931 - ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list, 4932 - struct list_head *rg_list) 4908 + ice_fill_fv_word_index(struct ice_hw *hw, struct ice_sw_recipe *rm) 4933 4909 { 4934 4910 struct ice_sw_fv_list_entry *fv; 4935 - struct ice_recp_grp_entry *rg; 4936 4911 struct ice_fv_word *fv_ext; 4912 + u8 i; 4937 4913 4938 - if (list_empty(fv_list)) 4939 - return 0; 4914 + if (list_empty(&rm->fv_list)) 4915 + return -EINVAL; 4940 4916 4941 - fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry, 4917 + fv = list_first_entry(&rm->fv_list, struct ice_sw_fv_list_entry, 4942 4918 list_entry); 4943 4919 fv_ext = fv->fv_ptr->ew; 4944 4920 4945 - list_for_each_entry(rg, rg_list, l_entry) { 4946 - u8 i; 4921 + /* Add switch id as the first word. */ 4922 + rm->fv_idx[0] = ICE_AQ_SW_ID_LKUP_IDX; 4923 + rm->fv_mask[0] = ICE_AQ_SW_ID_LKUP_MASK; 4924 + rm->n_ext_words++; 4947 4925 4948 - for (i = 0; i < rg->r_group.n_val_pairs; i++) { 4949 - struct ice_fv_word *pr; 4950 - bool found = false; 4951 - u16 mask; 4952 - u8 j; 4926 + for (i = 1; i < rm->n_ext_words; i++) { 4927 + struct ice_fv_word *fv_word = &rm->ext_words[i - 1]; 4928 + u16 fv_mask = rm->word_masks[i - 1]; 4929 + bool found = false; 4930 + u8 j; 4953 4931 4954 - pr = &rg->r_group.pairs[i]; 4955 - mask = rg->r_group.mask[i]; 4932 + for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) { 4933 + if (fv_ext[j].prot_id == fv_word->prot_id && 4934 + fv_ext[j].off == fv_word->off) { 4935 + found = true; 4956 4936 4957 - for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 4958 - if (fv_ext[j].prot_id == pr->prot_id && 4959 - fv_ext[j].off == pr->off) { 4960 - found = true; 4961 - 4962 - /* Store index of field vector */ 4963 - rg->fv_idx[i] = j; 4964 - rg->fv_mask[i] = mask; 4965 - break; 4966 - } 4967 - 4968 - /* Protocol/offset could not be found, caller gave an 4969 - * invalid pair 4970 - */ 4971 - if (!found) 4972 - return -EINVAL; 4937 + /* Store index of field vector */ 4938 + rm->fv_idx[i] = j; 4939 + rm->fv_mask[i] = fv_mask; 4940 + break; 4941 + } 4973 4942 } 4943 + 4944 + /* Protocol/offset could not be found, caller gave an invalid 4945 + * pair. 4946 + */ 4947 + if (!found) 4948 + return -EINVAL; 4974 4949 } 4975 4950 4976 4951 return 0; ··· 4989 5074 } 4990 5075 4991 5076 /** 5077 + * ice_calc_recp_cnt - calculate number of recipes based on word count 5078 + * @word_cnt: number of lookup words 5079 + * 5080 + * Word count should include switch ID word and regular lookup words. 5081 + * Returns: number of recipes required to fit @word_cnt, including extra recipes 5082 + * needed for recipe chaining (if needed). 5083 + */ 5084 + static int ice_calc_recp_cnt(u8 word_cnt) 5085 + { 5086 + /* All words fit in a single recipe, no need for chaining. */ 5087 + if (word_cnt <= ICE_NUM_WORDS_RECIPE) 5088 + return 1; 5089 + 5090 + /* Recipe chaining required. Result indexes are fitted right after 5091 + * regular lookup words. In some cases a new recipe must be added in 5092 + * order to fit result indexes. 5093 + * 5094 + * While the word count increases, every 5 words an extra recipe needs 5095 + * to be added. However, by adding a recipe, one word for its result 5096 + * index must also be added, therefore every 4 words recipe count 5097 + * increases by 1. This calculation does not apply to word count == 1, 5098 + * which is handled above. 5099 + */ 5100 + return (word_cnt + 2) / (ICE_NUM_WORDS_RECIPE - 1); 5101 + } 5102 + 5103 + static void fill_recipe_template(struct ice_aqc_recipe_data_elem *recp, u16 rid, 5104 + const struct ice_sw_recipe *rm) 5105 + { 5106 + int i; 5107 + 5108 + recp->recipe_indx = rid; 5109 + recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_PRUNE_INDX_M; 5110 + 5111 + for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) { 5112 + recp->content.lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE; 5113 + recp->content.mask[i] = cpu_to_le16(0); 5114 + } 5115 + 5116 + set_bit(rid, (unsigned long *)recp->recipe_bitmap); 5117 + recp->content.act_ctrl_fwd_priority = rm->priority; 5118 + 5119 + if (rm->need_pass_l2) 5120 + recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2; 5121 + 5122 + if (rm->allow_pass_l2) 5123 + recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 5124 + } 5125 + 5126 + static void bookkeep_recipe(struct ice_sw_recipe *recipe, 5127 + struct ice_aqc_recipe_data_elem *r, 5128 + const struct ice_sw_recipe *rm) 5129 + { 5130 + memcpy(recipe->r_bitmap, r->recipe_bitmap, sizeof(recipe->r_bitmap)); 5131 + 5132 + recipe->priority = r->content.act_ctrl_fwd_priority; 5133 + recipe->tun_type = rm->tun_type; 5134 + recipe->need_pass_l2 = rm->need_pass_l2; 5135 + recipe->allow_pass_l2 = rm->allow_pass_l2; 5136 + recipe->recp_created = true; 5137 + } 5138 + 5139 + /* For memcpy in ice_add_sw_recipe. */ 5140 + static_assert(sizeof_field(struct ice_aqc_recipe_data_elem, recipe_bitmap) == 5141 + sizeof_field(struct ice_sw_recipe, r_bitmap)); 5142 + 5143 + /** 4992 5144 * ice_add_sw_recipe - function to call AQ calls to create switch recipe 4993 5145 * @hw: pointer to hardware structure 4994 5146 * @rm: recipe management list entry ··· 5065 5083 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 5066 5084 unsigned long *profiles) 5067 5085 { 5086 + struct ice_aqc_recipe_data_elem *buf __free(kfree) = NULL; 5068 5087 DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); 5069 - struct ice_aqc_recipe_content *content; 5070 - struct ice_aqc_recipe_data_elem *tmp; 5071 - struct ice_aqc_recipe_data_elem *buf; 5072 - struct ice_recp_grp_entry *entry; 5073 - u16 free_res_idx; 5074 - u16 recipe_count; 5075 - u8 chain_idx; 5076 - u8 recps = 0; 5088 + struct ice_aqc_recipe_data_elem *root; 5089 + struct ice_sw_recipe *recipe; 5090 + u16 free_res_idx, rid; 5091 + int lookup = 0; 5092 + int recp_cnt; 5077 5093 int status; 5094 + int word; 5095 + int i; 5078 5096 5079 - /* When more than one recipe are required, another recipe is needed to 5080 - * chain them together. Matching a tunnel metadata ID takes up one of 5081 - * the match fields in the chaining recipe reducing the number of 5082 - * chained recipes by one. 5083 - */ 5084 - /* check number of free result indices */ 5097 + recp_cnt = ice_calc_recp_cnt(rm->n_ext_words); 5098 + 5085 5099 bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS); 5100 + bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 5101 + 5102 + /* Check number of free result indices */ 5086 5103 free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 5087 5104 5088 5105 ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 5089 - free_res_idx, rm->n_grp_count); 5106 + free_res_idx, recp_cnt); 5090 5107 5091 - if (rm->n_grp_count > 1) { 5092 - if (rm->n_grp_count > free_res_idx) 5093 - return -ENOSPC; 5094 - 5095 - rm->n_grp_count++; 5096 - } 5097 - 5098 - if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 5108 + /* Last recipe doesn't need result index */ 5109 + if (recp_cnt - 1 > free_res_idx) 5099 5110 return -ENOSPC; 5100 5111 5101 - tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 5102 - if (!tmp) 5112 + if (recp_cnt > ICE_MAX_CHAIN_RECIPE_RES) 5113 + return -E2BIG; 5114 + 5115 + buf = kcalloc(recp_cnt, sizeof(*buf), GFP_KERNEL); 5116 + if (!buf) 5103 5117 return -ENOMEM; 5104 5118 5105 - buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf), 5106 - GFP_KERNEL); 5107 - if (!buf) { 5108 - status = -ENOMEM; 5109 - goto err_mem; 5110 - } 5111 - 5112 - bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 5113 - recipe_count = ICE_MAX_NUM_RECIPES; 5114 - status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 5115 - NULL); 5116 - if (status || recipe_count == 0) 5117 - goto err_unroll; 5118 - 5119 - /* Allocate the recipe resources, and configure them according to the 5120 - * match fields from protocol headers and extracted field vectors. 5119 + /* Setup the non-root subrecipes. These do not contain lookups for other 5120 + * subrecipes results. Set associated recipe only to own recipe index. 5121 + * Each non-root subrecipe needs a free result index from FV. 5122 + * 5123 + * Note: only done if there is more than one recipe. 5121 5124 */ 5122 - chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 5123 - list_for_each_entry(entry, &rm->rg_list, l_entry) { 5124 - u8 i; 5125 + for (i = 0; i < recp_cnt - 1; i++) { 5126 + struct ice_aqc_recipe_content *content; 5127 + u8 result_idx; 5125 5128 5126 - status = ice_alloc_recipe(hw, &entry->rid); 5127 - if (status) 5128 - goto err_unroll; 5129 - 5130 - content = &buf[recps].content; 5131 - 5132 - /* Clear the result index of the located recipe, as this will be 5133 - * updated, if needed, later in the recipe creation process. 5134 - */ 5135 - tmp[0].content.result_indx = 0; 5136 - 5137 - buf[recps] = tmp[0]; 5138 - buf[recps].recipe_indx = (u8)entry->rid; 5139 - /* if the recipe is a non-root recipe RID should be programmed 5140 - * as 0 for the rules to be applied correctly. 5141 - */ 5142 - content->rid = 0; 5143 - memset(&content->lkup_indx, 0, 5144 - sizeof(content->lkup_indx)); 5145 - 5146 - /* All recipes use look-up index 0 to match switch ID. */ 5147 - content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5148 - content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5149 - /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 5150 - * to be 0 5151 - */ 5152 - for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5153 - content->lkup_indx[i] = 0x80; 5154 - content->mask[i] = 0; 5155 - } 5156 - 5157 - for (i = 0; i < entry->r_group.n_val_pairs; i++) { 5158 - content->lkup_indx[i + 1] = entry->fv_idx[i]; 5159 - content->mask[i + 1] = cpu_to_le16(entry->fv_mask[i]); 5160 - } 5161 - 5162 - if (rm->n_grp_count > 1) { 5163 - /* Checks to see if there really is a valid result index 5164 - * that can be used. 5165 - */ 5166 - if (chain_idx >= ICE_MAX_FV_WORDS) { 5167 - ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 5168 - status = -ENOSPC; 5169 - goto err_unroll; 5170 - } 5171 - 5172 - entry->chain_idx = chain_idx; 5173 - content->result_indx = 5174 - ICE_AQ_RECIPE_RESULT_EN | 5175 - FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M, 5176 - chain_idx); 5177 - clear_bit(chain_idx, result_idx_bm); 5178 - chain_idx = find_first_bit(result_idx_bm, 5179 - ICE_MAX_FV_WORDS); 5180 - } 5181 - 5182 - /* fill recipe dependencies */ 5183 - bitmap_zero((unsigned long *)buf[recps].recipe_bitmap, 5184 - ICE_MAX_NUM_RECIPES); 5185 - set_bit(buf[recps].recipe_indx, 5186 - (unsigned long *)buf[recps].recipe_bitmap); 5187 - content->act_ctrl_fwd_priority = rm->priority; 5188 - 5189 - if (rm->need_pass_l2) 5190 - content->act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2; 5191 - 5192 - if (rm->allow_pass_l2) 5193 - content->act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 5194 - recps++; 5195 - } 5196 - 5197 - if (rm->n_grp_count == 1) { 5198 - rm->root_rid = buf[0].recipe_indx; 5199 - set_bit(buf[0].recipe_indx, rm->r_bitmap); 5200 - buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 5201 - if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 5202 - memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 5203 - sizeof(buf[0].recipe_bitmap)); 5204 - } else { 5205 - status = -EINVAL; 5206 - goto err_unroll; 5207 - } 5208 - /* Applicable only for ROOT_RECIPE, set the fwd_priority for 5209 - * the recipe which is getting created if specified 5210 - * by user. Usually any advanced switch filter, which results 5211 - * into new extraction sequence, ended up creating a new recipe 5212 - * of type ROOT and usually recipes are associated with profiles 5213 - * Switch rule referreing newly created recipe, needs to have 5214 - * either/or 'fwd' or 'join' priority, otherwise switch rule 5215 - * evaluation will not happen correctly. In other words, if 5216 - * switch rule to be evaluated on priority basis, then recipe 5217 - * needs to have priority, otherwise it will be evaluated last. 5218 - */ 5219 - buf[0].content.act_ctrl_fwd_priority = rm->priority; 5220 - } else { 5221 - struct ice_recp_grp_entry *last_chain_entry; 5222 - u16 rid, i; 5223 - 5224 - /* Allocate the last recipe that will chain the outcomes of the 5225 - * other recipes together 5226 - */ 5227 5129 status = ice_alloc_recipe(hw, &rid); 5228 5130 if (status) 5229 - goto err_unroll; 5131 + return status; 5230 5132 5231 - content = &buf[recps].content; 5133 + fill_recipe_template(&buf[i], rid, rm); 5232 5134 5233 - buf[recps].recipe_indx = (u8)rid; 5234 - content->rid = (u8)rid; 5235 - content->rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 5236 - /* the new entry created should also be part of rg_list to 5237 - * make sure we have complete recipe 5135 + result_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 5136 + /* Check if there really is a valid result index that can be 5137 + * used. 5238 5138 */ 5239 - last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw), 5240 - sizeof(*last_chain_entry), 5241 - GFP_KERNEL); 5242 - if (!last_chain_entry) { 5243 - status = -ENOMEM; 5244 - goto err_unroll; 5139 + if (result_idx >= ICE_MAX_FV_WORDS) { 5140 + ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 5141 + return -ENOSPC; 5245 5142 } 5246 - last_chain_entry->rid = rid; 5247 - memset(&content->lkup_indx, 0, sizeof(content->lkup_indx)); 5248 - /* All recipes use look-up index 0 to match switch ID. */ 5249 - content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5250 - content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5251 - for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5252 - content->lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE; 5253 - content->mask[i] = 0; 5254 - } 5143 + clear_bit(result_idx, result_idx_bm); 5255 5144 5256 - i = 1; 5257 - /* update r_bitmap with the recp that is used for chaining */ 5145 + content = &buf[i].content; 5146 + content->result_indx = ICE_AQ_RECIPE_RESULT_EN | 5147 + FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M, 5148 + result_idx); 5149 + 5150 + /* Set recipe association to be used for root recipe */ 5258 5151 set_bit(rid, rm->r_bitmap); 5259 - /* this is the recipe that chains all the other recipes so it 5260 - * should not have a chaining ID to indicate the same 5261 - */ 5262 - last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 5263 - list_for_each_entry(entry, &rm->rg_list, l_entry) { 5264 - last_chain_entry->fv_idx[i] = entry->chain_idx; 5265 - content->lkup_indx[i] = entry->chain_idx; 5266 - content->mask[i++] = cpu_to_le16(0xFFFF); 5267 - set_bit(entry->rid, rm->r_bitmap); 5268 - } 5269 - list_add(&last_chain_entry->l_entry, &rm->rg_list); 5270 - if (sizeof(buf[recps].recipe_bitmap) >= 5271 - sizeof(rm->r_bitmap)) { 5272 - memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 5273 - sizeof(buf[recps].recipe_bitmap)); 5274 - } else { 5275 - status = -EINVAL; 5276 - goto err_unroll; 5277 - } 5278 - content->act_ctrl_fwd_priority = rm->priority; 5279 5152 5280 - recps++; 5281 - rm->root_rid = (u8)rid; 5153 + word = 0; 5154 + while (lookup < rm->n_ext_words && 5155 + word < ICE_NUM_WORDS_RECIPE) { 5156 + content->lkup_indx[word] = rm->fv_idx[lookup]; 5157 + content->mask[word] = cpu_to_le16(rm->fv_mask[lookup]); 5158 + 5159 + lookup++; 5160 + word++; 5161 + } 5162 + 5163 + recipe = &hw->switch_info->recp_list[rid]; 5164 + set_bit(result_idx, recipe->res_idxs); 5165 + bookkeep_recipe(recipe, &buf[i], rm); 5282 5166 } 5167 + 5168 + /* Setup the root recipe */ 5169 + status = ice_alloc_recipe(hw, &rid); 5170 + if (status) 5171 + return status; 5172 + 5173 + recipe = &hw->switch_info->recp_list[rid]; 5174 + root = &buf[recp_cnt - 1]; 5175 + fill_recipe_template(root, rid, rm); 5176 + 5177 + /* Set recipe association, use previously set bitmap and own rid */ 5178 + set_bit(rid, rm->r_bitmap); 5179 + memcpy(root->recipe_bitmap, rm->r_bitmap, sizeof(root->recipe_bitmap)); 5180 + 5181 + /* For non-root recipes rid should be 0, for root it should be correct 5182 + * rid value ored with 0x80 (is root bit). 5183 + */ 5184 + root->content.rid = rid | ICE_AQ_RECIPE_ID_IS_ROOT; 5185 + 5186 + /* Fill remaining lookups in root recipe */ 5187 + word = 0; 5188 + while (lookup < rm->n_ext_words && 5189 + word < ICE_NUM_WORDS_RECIPE /* should always be true */) { 5190 + root->content.lkup_indx[word] = rm->fv_idx[lookup]; 5191 + root->content.mask[word] = cpu_to_le16(rm->fv_mask[lookup]); 5192 + 5193 + lookup++; 5194 + word++; 5195 + } 5196 + 5197 + /* Fill result indexes as lookups */ 5198 + i = 0; 5199 + while (i < recp_cnt - 1 && 5200 + word < ICE_NUM_WORDS_RECIPE /* should always be true */) { 5201 + root->content.lkup_indx[word] = buf[i].content.result_indx & 5202 + ~ICE_AQ_RECIPE_RESULT_EN; 5203 + root->content.mask[word] = cpu_to_le16(0xffff); 5204 + /* For bookkeeping, it is needed to mark FV index as used for 5205 + * intermediate result. 5206 + */ 5207 + set_bit(root->content.lkup_indx[word], recipe->res_idxs); 5208 + 5209 + i++; 5210 + word++; 5211 + } 5212 + 5213 + rm->root_rid = rid; 5214 + bookkeep_recipe(&hw->switch_info->recp_list[rid], root, rm); 5215 + 5216 + /* Program the recipe */ 5283 5217 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5284 5218 if (status) 5285 - goto err_unroll; 5219 + return status; 5286 5220 5287 - status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 5221 + status = ice_aq_add_recipe(hw, buf, recp_cnt, NULL); 5288 5222 ice_release_change_lock(hw); 5289 5223 if (status) 5290 - goto err_unroll; 5224 + return status; 5291 5225 5292 - /* Every recipe that just got created add it to the recipe 5293 - * book keeping list 5294 - */ 5295 - list_for_each_entry(entry, &rm->rg_list, l_entry) { 5296 - struct ice_switch_info *sw = hw->switch_info; 5297 - bool is_root, idx_found = false; 5298 - struct ice_sw_recipe *recp; 5299 - u16 idx, buf_idx = 0; 5300 - 5301 - /* find buffer index for copying some data */ 5302 - for (idx = 0; idx < rm->n_grp_count; idx++) 5303 - if (buf[idx].recipe_indx == entry->rid) { 5304 - buf_idx = idx; 5305 - idx_found = true; 5306 - } 5307 - 5308 - if (!idx_found) { 5309 - status = -EIO; 5310 - goto err_unroll; 5311 - } 5312 - 5313 - recp = &sw->recp_list[entry->rid]; 5314 - is_root = (rm->root_rid == entry->rid); 5315 - recp->is_root = is_root; 5316 - 5317 - recp->root_rid = entry->rid; 5318 - recp->big_recp = (is_root && rm->n_grp_count > 1); 5319 - 5320 - memcpy(&recp->ext_words, entry->r_group.pairs, 5321 - entry->r_group.n_val_pairs * sizeof(struct ice_fv_word)); 5322 - 5323 - memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 5324 - sizeof(recp->r_bitmap)); 5325 - 5326 - /* Copy non-result fv index values and masks to recipe. This 5327 - * call will also update the result recipe bitmask. 5328 - */ 5329 - ice_collect_result_idx(&buf[buf_idx], recp); 5330 - 5331 - /* for non-root recipes, also copy to the root, this allows 5332 - * easier matching of a complete chained recipe 5333 - */ 5334 - if (!is_root) 5335 - ice_collect_result_idx(&buf[buf_idx], 5336 - &sw->recp_list[rm->root_rid]); 5337 - 5338 - recp->n_ext_words = entry->r_group.n_val_pairs; 5339 - recp->chain_idx = entry->chain_idx; 5340 - recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 5341 - recp->n_grp_count = rm->n_grp_count; 5342 - recp->tun_type = rm->tun_type; 5343 - recp->need_pass_l2 = rm->need_pass_l2; 5344 - recp->allow_pass_l2 = rm->allow_pass_l2; 5345 - recp->recp_created = true; 5346 - } 5347 - rm->root_buf = buf; 5348 - kfree(tmp); 5349 - return status; 5350 - 5351 - err_unroll: 5352 - err_mem: 5353 - kfree(tmp); 5354 - devm_kfree(ice_hw_to_dev(hw), buf); 5355 - return status; 5356 - } 5357 - 5358 - /** 5359 - * ice_create_recipe_group - creates recipe group 5360 - * @hw: pointer to hardware structure 5361 - * @rm: recipe management list entry 5362 - * @lkup_exts: lookup elements 5363 - */ 5364 - static int 5365 - ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 5366 - struct ice_prot_lkup_ext *lkup_exts) 5367 - { 5368 - u8 recp_count = 0; 5369 - int status; 5370 - 5371 - rm->n_grp_count = 0; 5372 - 5373 - /* Create recipes for words that are marked not done by packing them 5374 - * as best fit. 5375 - */ 5376 - status = ice_create_first_fit_recp_def(hw, lkup_exts, 5377 - &rm->rg_list, &recp_count); 5378 - if (!status) { 5379 - rm->n_grp_count += recp_count; 5380 - rm->n_ext_words = lkup_exts->n_val_words; 5381 - memcpy(&rm->ext_words, lkup_exts->fv_words, 5382 - sizeof(rm->ext_words)); 5383 - memcpy(rm->word_masks, lkup_exts->field_mask, 5384 - sizeof(rm->word_masks)); 5385 - } 5386 - 5387 - return status; 5226 + return 0; 5388 5227 } 5389 5228 5390 5229 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule ··· 5312 5509 DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES); 5313 5510 DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES); 5314 5511 struct ice_prot_lkup_ext *lkup_exts; 5315 - struct ice_recp_grp_entry *r_entry; 5316 5512 struct ice_sw_fv_list_entry *fvit; 5317 - struct ice_recp_grp_entry *r_tmp; 5318 5513 struct ice_sw_fv_list_entry *tmp; 5319 5514 struct ice_sw_recipe *rm; 5320 5515 int status = 0; ··· 5354 5553 * headers being programmed. 5355 5554 */ 5356 5555 INIT_LIST_HEAD(&rm->fv_list); 5357 - INIT_LIST_HEAD(&rm->rg_list); 5358 5556 5359 5557 /* Get bitmap of field vectors (profiles) that are compatible with the 5360 5558 * rule request; only these will be searched in the subsequent call to ··· 5365 5565 if (status) 5366 5566 goto err_unroll; 5367 5567 5368 - /* Group match words into recipes using preferred recipe grouping 5369 - * criteria. 5370 - */ 5371 - status = ice_create_recipe_group(hw, rm, lkup_exts); 5372 - if (status) 5373 - goto err_unroll; 5568 + /* Copy FV words and masks from lkup_exts to recipe struct. */ 5569 + rm->n_ext_words = lkup_exts->n_val_words; 5570 + memcpy(rm->ext_words, lkup_exts->fv_words, sizeof(rm->ext_words)); 5571 + memcpy(rm->word_masks, lkup_exts->field_mask, sizeof(rm->word_masks)); 5374 5572 5375 5573 /* set the recipe priority if specified */ 5376 5574 rm->priority = (u8)rinfo->priority; ··· 5379 5581 /* Find offsets from the field vector. Pick the first one for all the 5380 5582 * recipes. 5381 5583 */ 5382 - status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 5584 + status = ice_fill_fv_word_index(hw, rm); 5383 5585 if (status) 5384 5586 goto err_unroll; 5385 5587 ··· 5457 5659 } 5458 5660 5459 5661 err_unroll: 5460 - list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) { 5461 - list_del(&r_entry->l_entry); 5462 - devm_kfree(ice_hw_to_dev(hw), r_entry); 5463 - } 5464 - 5465 5662 list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) { 5466 5663 list_del(&fvit->list_entry); 5467 5664 devm_kfree(ice_hw_to_dev(hw), fvit); 5468 5665 } 5469 5666 5470 - devm_kfree(ice_hw_to_dev(hw), rm->root_buf); 5471 5667 kfree(rm); 5472 5668 5473 5669 err_free_lkup_exts:
+2 -18
drivers/net/ethernet/intel/ice/ice_switch.h
··· 216 216 /* For a chained recipe the root recipe is what should be used for 217 217 * programming rules 218 218 */ 219 - u8 is_root; 220 219 u8 root_rid; 221 220 u8 recp_created; 222 221 ··· 226 227 */ 227 228 struct ice_fv_word ext_words[ICE_MAX_CHAIN_WORDS]; 228 229 u16 word_masks[ICE_MAX_CHAIN_WORDS]; 229 - 230 - /* if this recipe is a collection of other recipe */ 231 - u8 big_recp; 232 - 233 - /* if this recipe is part of another bigger recipe then chain index 234 - * corresponding to this recipe 235 - */ 236 - u8 chain_idx; 237 - 238 - /* if this recipe is a collection of other recipe then count of other 239 - * recipes and recipe IDs of those recipes 240 - */ 241 - u8 n_grp_count; 230 + u8 fv_idx[ICE_MAX_CHAIN_WORDS]; 231 + u16 fv_mask[ICE_MAX_CHAIN_WORDS]; 242 232 243 233 /* Bit map specifying the IDs associated with this group of recipe */ 244 234 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); ··· 260 272 u8 need_pass_l2:1; 261 273 u8 allow_pass_l2:1; 262 274 263 - struct list_head rg_list; 264 - 265 - /* AQ buffer associated with this recipe */ 266 - struct ice_aqc_recipe_data_elem *root_buf; 267 275 /* This struct saves the fv_words for a given lookup */ 268 276 struct ice_prot_lkup_ext lkup_exts; 269 277 };
+18
drivers/net/ethernet/intel/ice/ice_trace.h
··· 330 330 TP_ARGS(port) 331 331 ); 332 332 333 + DECLARE_EVENT_CLASS(ice_switch_stats_template, 334 + TP_PROTO(struct ice_switch_info *sw_info), 335 + TP_ARGS(sw_info), 336 + TP_STRUCT__entry(__field(u16, rule_cnt) 337 + __field(u8, recp_cnt)), 338 + TP_fast_assign(__entry->rule_cnt = sw_info->rule_cnt; 339 + __entry->recp_cnt = sw_info->recp_cnt;), 340 + TP_printk("rules=%u recipes=%u", 341 + __entry->rule_cnt, 342 + __entry->recp_cnt) 343 + ); 344 + 345 + DEFINE_EVENT(ice_switch_stats_template, 346 + ice_aq_sw_rules, 347 + TP_PROTO(struct ice_switch_info *sw_info), 348 + TP_ARGS(sw_info) 349 + ); 350 + 333 351 /* End tracepoints */ 334 352 335 353 #endif /* _ICE_TRACE_H_ */
+2
drivers/net/ethernet/intel/ice/ice_type.h
··· 762 762 struct ice_sw_recipe *recp_list; 763 763 u16 prof_res_bm_init; 764 764 u16 max_used_prof_index; 765 + u16 rule_cnt; 766 + u8 recp_cnt; 765 767 766 768 DECLARE_BITMAP(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS); 767 769 };