1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Copyright (c) 2018, Intel Corporation. */ |
3 | |
4 | #ifndef _ICE_SWITCH_H_ |
5 | #define _ICE_SWITCH_H_ |
6 | |
7 | #include "ice_common.h" |
8 | |
9 | #define ICE_SW_CFG_MAX_BUF_LEN 2048 |
10 | #define ICE_DFLT_VSI_INVAL 0xff |
11 | #define ICE_FLTR_RX BIT(0) |
12 | #define ICE_FLTR_TX BIT(1) |
13 | #define ICE_VSI_INVAL_ID 0xffff |
14 | #define ICE_INVAL_Q_HANDLE 0xFFFF |
15 | |
16 | /* Switch Profile IDs for Profile related switch rules */ |
17 | #define ICE_PROFID_IPV4_GTPC_TEID 41 |
18 | #define ICE_PROFID_IPV4_GTPC_NO_TEID 42 |
19 | #define ICE_PROFID_IPV4_GTPU_TEID 43 |
20 | #define ICE_PROFID_IPV6_GTPC_TEID 44 |
21 | #define ICE_PROFID_IPV6_GTPC_NO_TEID 45 |
22 | #define ICE_PROFID_IPV6_GTPU_TEID 46 |
23 | #define ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER 70 |
24 | |
25 | #define ICE_SW_RULE_VSI_LIST_SIZE(s, n) struct_size((s), vsi, (n)) |
26 | #define ICE_SW_RULE_RX_TX_HDR_SIZE(s, l) struct_size((s), hdr_data, (l)) |
27 | #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s) \ |
28 | ICE_SW_RULE_RX_TX_HDR_SIZE((s), DUMMY_ETH_HDR_LEN) |
29 | #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s) \ |
30 | ICE_SW_RULE_RX_TX_HDR_SIZE((s), 0) |
31 | #define ICE_SW_RULE_LG_ACT_SIZE(s, n) struct_size((s), act, (n)) |
32 | |
33 | #define DUMMY_ETH_HDR_LEN 16 |
34 | |
35 | /* VSI context structure for add/get/update/free operations */ |
36 | struct ice_vsi_ctx { |
37 | u16 vsi_num; |
38 | u16 vsis_allocd; |
39 | u16 vsis_unallocated; |
40 | u16 flags; |
41 | struct ice_aqc_vsi_props info; |
42 | struct ice_sched_vsi_info sched; |
43 | u8 alloc_from_pool; |
44 | u8 vf_num; |
45 | u16 num_lan_q_entries[ICE_MAX_TRAFFIC_CLASS]; |
46 | struct ice_q_ctx *lan_q_ctx[ICE_MAX_TRAFFIC_CLASS]; |
47 | u16 num_rdma_q_entries[ICE_MAX_TRAFFIC_CLASS]; |
48 | struct ice_q_ctx *rdma_q_ctx[ICE_MAX_TRAFFIC_CLASS]; |
49 | }; |
50 | |
51 | /* Switch recipe ID enum values are specific to hardware */ |
52 | enum ice_sw_lkup_type { |
53 | ICE_SW_LKUP_ETHERTYPE = 0, |
54 | ICE_SW_LKUP_MAC = 1, |
55 | ICE_SW_LKUP_MAC_VLAN = 2, |
56 | ICE_SW_LKUP_PROMISC = 3, |
57 | ICE_SW_LKUP_VLAN = 4, |
58 | ICE_SW_LKUP_DFLT = 5, |
59 | ICE_SW_LKUP_ETHERTYPE_MAC = 8, |
60 | ICE_SW_LKUP_PROMISC_VLAN = 9, |
61 | ICE_SW_LKUP_LAST |
62 | }; |
63 | |
64 | /* type of filter src ID */ |
65 | enum ice_src_id { |
66 | ICE_SRC_ID_UNKNOWN = 0, |
67 | ICE_SRC_ID_VSI, |
68 | ICE_SRC_ID_QUEUE, |
69 | ICE_SRC_ID_LPORT, |
70 | }; |
71 | |
72 | struct ice_fltr_info { |
73 | /* Look up information: how to look up packet */ |
74 | enum ice_sw_lkup_type lkup_type; |
75 | /* Forward action: filter action to do after lookup */ |
76 | enum ice_sw_fwd_act_type fltr_act; |
77 | /* rule ID returned by firmware once filter rule is created */ |
78 | u16 fltr_rule_id; |
79 | u16 flag; |
80 | |
81 | /* Source VSI for LOOKUP_TX or source port for LOOKUP_RX */ |
82 | u16 src; |
83 | enum ice_src_id src_id; |
84 | |
85 | union { |
86 | struct { |
87 | u8 mac_addr[ETH_ALEN]; |
88 | } mac; |
89 | struct { |
90 | u8 mac_addr[ETH_ALEN]; |
91 | u16 vlan_id; |
92 | } mac_vlan; |
93 | struct { |
94 | u16 vlan_id; |
95 | u16 tpid; |
96 | u8 tpid_valid; |
97 | } vlan; |
98 | /* Set lkup_type as ICE_SW_LKUP_ETHERTYPE |
99 | * if just using ethertype as filter. Set lkup_type as |
100 | * ICE_SW_LKUP_ETHERTYPE_MAC if MAC also needs to be |
101 | * passed in as filter. |
102 | */ |
103 | struct { |
104 | u16 ethertype; |
105 | u8 mac_addr[ETH_ALEN]; /* optional */ |
106 | } ethertype_mac; |
107 | } l_data; /* Make sure to zero out the memory of l_data before using |
108 | * it or only set the data associated with lookup match |
109 | * rest everything should be zero |
110 | */ |
111 | |
112 | /* Depending on filter action */ |
113 | union { |
114 | /* queue ID in case of ICE_FWD_TO_Q and starting |
115 | * queue ID in case of ICE_FWD_TO_QGRP. |
116 | */ |
117 | u16 q_id:11; |
118 | u16 hw_vsi_id:10; |
119 | u16 vsi_list_id:10; |
120 | } fwd_id; |
121 | |
122 | /* Sw VSI handle */ |
123 | u16 vsi_handle; |
124 | |
125 | /* Set to num_queues if action is ICE_FWD_TO_QGRP. This field |
126 | * determines the range of queues the packet needs to be forwarded to. |
127 | * Note that qgrp_size must be set to a power of 2. |
128 | */ |
129 | u8 qgrp_size; |
130 | |
131 | /* Rule creations populate these indicators basing on the switch type */ |
132 | u8 lb_en; /* Indicate if packet can be looped back */ |
133 | u8 lan_en; /* Indicate if packet can be forwarded to the uplink */ |
134 | }; |
135 | |
136 | struct ice_update_recipe_lkup_idx_params { |
137 | u16 rid; |
138 | u16 fv_idx; |
139 | bool ignore_valid; |
140 | u16 mask; |
141 | bool mask_valid; |
142 | u8 lkup_idx; |
143 | }; |
144 | |
145 | struct ice_adv_lkup_elem { |
146 | enum ice_protocol_type type; |
147 | union { |
148 | union ice_prot_hdr h_u; /* Header values */ |
149 | /* Used to iterate over the headers */ |
150 | u16 h_raw[sizeof(union ice_prot_hdr) / sizeof(u16)]; |
151 | }; |
152 | union { |
153 | union ice_prot_hdr m_u; /* Mask of header values to match */ |
154 | /* Used to iterate over header mask */ |
155 | u16 m_raw[sizeof(union ice_prot_hdr) / sizeof(u16)]; |
156 | }; |
157 | }; |
158 | |
159 | struct ice_sw_act_ctrl { |
160 | /* Source VSI for LOOKUP_TX or source port for LOOKUP_RX */ |
161 | u16 src; |
162 | u16 flag; |
163 | enum ice_sw_fwd_act_type fltr_act; |
164 | /* Depending on filter action */ |
165 | union { |
166 | /* This is a queue ID in case of ICE_FWD_TO_Q and starting |
167 | * queue ID in case of ICE_FWD_TO_QGRP. |
168 | */ |
169 | u16 q_id:11; |
170 | u16 vsi_id:10; |
171 | u16 hw_vsi_id:10; |
172 | u16 vsi_list_id:10; |
173 | } fwd_id; |
174 | /* software VSI handle */ |
175 | u16 vsi_handle; |
176 | u8 qgrp_size; |
177 | }; |
178 | |
179 | struct ice_rule_query_data { |
180 | /* Recipe ID for which the requested rule was added */ |
181 | u16 rid; |
182 | /* Rule ID that was added or is supposed to be removed */ |
183 | u16 rule_id; |
184 | /* vsi_handle for which Rule was added or is supposed to be removed */ |
185 | u16 vsi_handle; |
186 | }; |
187 | |
188 | /* This structure allows to pass info about lb_en and lan_en |
189 | * flags to ice_add_adv_rule. Values in act would be used |
190 | * only if act_valid was set to true, otherwise default |
191 | * values would be used. |
192 | */ |
193 | struct ice_adv_rule_flags_info { |
194 | u32 act; |
195 | u8 act_valid; /* indicate if flags in act are valid */ |
196 | }; |
197 | |
198 | struct ice_adv_rule_info { |
199 | /* Store metadata values in rule info */ |
200 | enum ice_sw_tunnel_type tun_type; |
201 | u16 vlan_type; |
202 | u16 fltr_rule_id; |
203 | u32 priority; |
204 | u16 need_pass_l2:1; |
205 | u16 allow_pass_l2:1; |
206 | u16 src_vsi; |
207 | struct ice_sw_act_ctrl sw_act; |
208 | struct ice_adv_rule_flags_info flags_info; |
209 | }; |
210 | |
211 | /* A collection of one or more four word recipe */ |
212 | struct ice_sw_recipe { |
213 | /* For a chained recipe the root recipe is what should be used for |
214 | * programming rules |
215 | */ |
216 | u8 is_root; |
217 | u8 root_rid; |
218 | u8 recp_created; |
219 | |
220 | /* Number of extraction words */ |
221 | u8 n_ext_words; |
222 | /* Protocol ID and Offset pair (extraction word) to describe the |
223 | * recipe |
224 | */ |
225 | struct ice_fv_word ext_words[ICE_MAX_CHAIN_WORDS]; |
226 | u16 word_masks[ICE_MAX_CHAIN_WORDS]; |
227 | |
228 | /* if this recipe is a collection of other recipe */ |
229 | u8 big_recp; |
230 | |
231 | /* if this recipe is part of another bigger recipe then chain index |
232 | * corresponding to this recipe |
233 | */ |
234 | u8 chain_idx; |
235 | |
236 | /* if this recipe is a collection of other recipe then count of other |
237 | * recipes and recipe IDs of those recipes |
238 | */ |
239 | u8 n_grp_count; |
240 | |
241 | /* Bit map specifying the IDs associated with this group of recipe */ |
242 | DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); |
243 | |
244 | enum ice_sw_tunnel_type tun_type; |
245 | |
246 | /* List of type ice_fltr_mgmt_list_entry or adv_rule */ |
247 | u8 adv_rule; |
248 | struct list_head filt_rules; |
249 | struct list_head filt_replay_rules; |
250 | |
251 | struct mutex filt_rule_lock; /* protect filter rule structure */ |
252 | |
253 | /* Profiles this recipe should be associated with */ |
254 | struct list_head fv_list; |
255 | |
256 | /* Profiles this recipe is associated with */ |
257 | u8 num_profs, *prof_ids; |
258 | |
259 | /* Bit map for possible result indexes */ |
260 | DECLARE_BITMAP(res_idxs, ICE_MAX_FV_WORDS); |
261 | |
262 | /* This allows user to specify the recipe priority. |
263 | * For now, this becomes 'fwd_priority' when recipe |
264 | * is created, usually recipes can have 'fwd' and 'join' |
265 | * priority. |
266 | */ |
267 | u8 priority; |
268 | |
269 | u8 need_pass_l2:1; |
270 | u8 allow_pass_l2:1; |
271 | |
272 | struct list_head rg_list; |
273 | |
274 | /* AQ buffer associated with this recipe */ |
275 | struct ice_aqc_recipe_data_elem *root_buf; |
276 | /* This struct saves the fv_words for a given lookup */ |
277 | struct ice_prot_lkup_ext lkup_exts; |
278 | }; |
279 | |
280 | /* Bookkeeping structure to hold bitmap of VSIs corresponding to VSI list ID */ |
281 | struct ice_vsi_list_map_info { |
282 | struct list_head list_entry; |
283 | DECLARE_BITMAP(vsi_map, ICE_MAX_VSI); |
284 | u16 vsi_list_id; |
285 | /* counter to track how many rules are reusing this VSI list */ |
286 | u16 ref_cnt; |
287 | }; |
288 | |
289 | struct ice_fltr_list_entry { |
290 | struct list_head list_entry; |
291 | int status; |
292 | struct ice_fltr_info fltr_info; |
293 | }; |
294 | |
295 | /* This defines an entry in the list that maintains MAC or VLAN membership |
296 | * to HW list mapping, since multiple VSIs can subscribe to the same MAC or |
297 | * VLAN. As an optimization the VSI list should be created only when a |
298 | * second VSI becomes a subscriber to the same MAC address. VSI lists are always |
299 | * used for VLAN membership. |
300 | */ |
301 | struct ice_fltr_mgmt_list_entry { |
302 | /* back pointer to VSI list ID to VSI list mapping */ |
303 | struct ice_vsi_list_map_info *vsi_list_info; |
304 | u16 vsi_count; |
305 | #define ICE_INVAL_LG_ACT_INDEX 0xffff |
306 | u16 lg_act_idx; |
307 | #define ICE_INVAL_SW_MARKER_ID 0xffff |
308 | u16 sw_marker_id; |
309 | struct list_head list_entry; |
310 | struct ice_fltr_info fltr_info; |
311 | #define ICE_INVAL_COUNTER_ID 0xff |
312 | u8 counter_index; |
313 | }; |
314 | |
315 | struct ice_adv_fltr_mgmt_list_entry { |
316 | struct list_head list_entry; |
317 | |
318 | struct ice_adv_lkup_elem *lkups; |
319 | struct ice_adv_rule_info rule_info; |
320 | u16 lkups_cnt; |
321 | struct ice_vsi_list_map_info *vsi_list_info; |
322 | u16 vsi_count; |
323 | }; |
324 | |
325 | enum ice_promisc_flags { |
326 | ICE_PROMISC_UCAST_RX = 0x1, |
327 | ICE_PROMISC_UCAST_TX = 0x2, |
328 | ICE_PROMISC_MCAST_RX = 0x4, |
329 | ICE_PROMISC_MCAST_TX = 0x8, |
330 | ICE_PROMISC_BCAST_RX = 0x10, |
331 | ICE_PROMISC_BCAST_TX = 0x20, |
332 | ICE_PROMISC_VLAN_RX = 0x40, |
333 | ICE_PROMISC_VLAN_TX = 0x80, |
334 | }; |
335 | |
336 | /* VSI related commands */ |
337 | int |
338 | ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, |
339 | struct ice_sq_cd *cd); |
340 | int |
341 | ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, |
342 | bool keep_vsi_alloc, struct ice_sq_cd *cd); |
343 | int |
344 | ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, |
345 | struct ice_sq_cd *cd); |
346 | bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle); |
347 | struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle); |
348 | void ice_clear_all_vsi_ctx(struct ice_hw *hw); |
349 | /* Switch config */ |
350 | int ice_get_initial_sw_cfg(struct ice_hw *hw); |
351 | |
352 | int |
353 | ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, |
354 | u16 *counter_id); |
355 | int |
356 | ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, |
357 | u16 counter_id); |
358 | int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id); |
359 | |
360 | /* Switch/bridge related commands */ |
361 | void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup); |
362 | void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup); |
363 | void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup); |
364 | void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup); |
365 | int |
366 | ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, |
367 | u16 lkups_cnt, struct ice_adv_rule_info *rinfo, |
368 | struct ice_rule_query_data *added_entry); |
369 | int ice_update_sw_rule_bridge_mode(struct ice_hw *hw); |
370 | int ice_add_vlan(struct ice_hw *hw, struct list_head *m_list); |
371 | int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list); |
372 | int ice_add_mac(struct ice_hw *hw, struct list_head *m_lst); |
373 | int ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst); |
374 | bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle); |
375 | int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list); |
376 | int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list); |
377 | int ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable); |
378 | void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle); |
379 | |
380 | /* Promisc/defport setup for VSIs */ |
381 | int |
382 | ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, |
383 | u8 direction); |
384 | bool |
385 | ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, |
386 | bool *rule_exists); |
387 | |
388 | int |
389 | ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, |
390 | u16 vid); |
391 | int |
392 | ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, |
393 | u16 vid); |
394 | int |
395 | ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, |
396 | bool rm_vlan_promisc); |
397 | |
398 | int |
399 | ice_rem_adv_rule_by_id(struct ice_hw *hw, |
400 | struct ice_rule_query_data *remove_entry); |
401 | |
402 | int ice_init_def_sw_recp(struct ice_hw *hw); |
403 | u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle); |
404 | |
405 | int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle); |
406 | void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw); |
407 | void ice_fill_eth_hdr(u8 *eth_hdr); |
408 | |
409 | int |
410 | ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, |
411 | u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd); |
412 | int |
413 | ice_update_recipe_lkup_idx(struct ice_hw *hw, |
414 | struct ice_update_recipe_lkup_idx_params *params); |
415 | void ice_change_proto_id_to_dvm(void); |
416 | struct ice_vsi_list_map_info * |
417 | ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle, |
418 | u16 *vsi_list_id); |
419 | int ice_alloc_recipe(struct ice_hw *hw, u16 *rid); |
420 | int ice_aq_get_recipe(struct ice_hw *hw, |
421 | struct ice_aqc_recipe_data_elem *s_recipe_list, |
422 | u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd); |
423 | int ice_aq_add_recipe(struct ice_hw *hw, |
424 | struct ice_aqc_recipe_data_elem *s_recipe_list, |
425 | u16 num_recipes, struct ice_sq_cd *cd); |
426 | int |
427 | ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, |
428 | struct ice_sq_cd *cd); |
429 | int |
430 | ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, |
431 | struct ice_sq_cd *cd); |
432 | |
433 | #endif /* _ICE_SWITCH_H_ */ |
434 | |