xref: /openbmc/linux/drivers/net/ethernet/intel/ice/ice_switch.c (revision dd2934a95701576203b2f61e8ded4e4a2f9183ea)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Intel Corporation. */
3 
4 #include "ice_switch.h"
5 
6 #define ICE_ETH_DA_OFFSET		0
7 #define ICE_ETH_ETHTYPE_OFFSET		12
8 #define ICE_ETH_VLAN_TCI_OFFSET		14
9 #define ICE_MAX_VLAN_ID			0xFFF
10 
11 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
12  * struct to configure any switch filter rules.
13  * {DA (6 bytes), SA(6 bytes),
14  * Ether type (2 bytes for header without VLAN tag) OR
15  * VLAN tag (4 bytes for header with VLAN tag) }
16  *
17  * Word on Hardcoded values
18  * byte 0 = 0x2: to identify it as locally administered DA MAC
19  * byte 6 = 0x2: to identify it as locally administered SA MAC
20  * byte 12 = 0x81 & byte 13 = 0x00:
21  *	In case of VLAN filter first two bytes defines ether type (0x8100)
22  *	and remaining two bytes are placeholder for programming a given VLAN id
23  *	In case of Ether type filter it is treated as header without VLAN tag
24  *	and byte 12 and 13 is used to program a given Ether type instead
25  */
26 #define DUMMY_ETH_HDR_LEN		16
27 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
28 							0x2, 0, 0, 0, 0, 0,
29 							0x81, 0, 0, 0};
30 
31 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \
32 	(sizeof(struct ice_aqc_sw_rules_elem) - \
33 	 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
34 	 sizeof(struct ice_sw_rule_lkup_rx_tx) + DUMMY_ETH_HDR_LEN - 1)
35 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \
36 	(sizeof(struct ice_aqc_sw_rules_elem) - \
37 	 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
38 	 sizeof(struct ice_sw_rule_lkup_rx_tx) - 1)
39 #define ICE_SW_RULE_LG_ACT_SIZE(n) \
40 	(sizeof(struct ice_aqc_sw_rules_elem) - \
41 	 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
42 	 sizeof(struct ice_sw_rule_lg_act) - \
43 	 sizeof(((struct ice_sw_rule_lg_act *)0)->act) + \
44 	 ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act)))
45 #define ICE_SW_RULE_VSI_LIST_SIZE(n) \
46 	(sizeof(struct ice_aqc_sw_rules_elem) - \
47 	 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
48 	 sizeof(struct ice_sw_rule_vsi_list) - \
49 	 sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi) + \
50 	 ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi)))
51 
52 /**
53  * ice_aq_alloc_free_res - command to allocate/free resources
54  * @hw: pointer to the hw struct
55  * @num_entries: number of resource entries in buffer
56  * @buf: Indirect buffer to hold data parameters and response
57  * @buf_size: size of buffer for indirect commands
58  * @opc: pass in the command opcode
59  * @cd: pointer to command details structure or NULL
60  *
61  * Helper function to allocate/free resources using the admin queue commands
62  */
63 static enum ice_status
64 ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
65 		      struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size,
66 		      enum ice_adminq_opc opc, struct ice_sq_cd *cd)
67 {
68 	struct ice_aqc_alloc_free_res_cmd *cmd;
69 	struct ice_aq_desc desc;
70 
71 	cmd = &desc.params.sw_res_ctrl;
72 
73 	if (!buf)
74 		return ICE_ERR_PARAM;
75 
76 	if (buf_size < (num_entries * sizeof(buf->elem[0])))
77 		return ICE_ERR_PARAM;
78 
79 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
80 
81 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
82 
83 	cmd->num_entries = cpu_to_le16(num_entries);
84 
85 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
86 }
87 
88 /**
89  * ice_init_def_sw_recp - initialize the recipe book keeping tables
90  * @hw: pointer to the hw struct
91  *
92  * Allocate memory for the entire recipe table and initialize the structures/
93  * entries corresponding to basic recipes.
94  */
95 enum ice_status
96 ice_init_def_sw_recp(struct ice_hw *hw)
97 {
98 	struct ice_sw_recipe *recps;
99 	u8 i;
100 
101 	recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
102 			     sizeof(struct ice_sw_recipe), GFP_KERNEL);
103 	if (!recps)
104 		return ICE_ERR_NO_MEMORY;
105 
106 	for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
107 		recps[i].root_rid = i;
108 		INIT_LIST_HEAD(&recps[i].filt_rules);
109 		mutex_init(&recps[i].filt_rule_lock);
110 	}
111 
112 	hw->switch_info->recp_list = recps;
113 
114 	return 0;
115 }
116 
117 /**
118  * ice_aq_get_sw_cfg - get switch configuration
119  * @hw: pointer to the hardware structure
120  * @buf: pointer to the result buffer
121  * @buf_size: length of the buffer available for response
122  * @req_desc: pointer to requested descriptor
123  * @num_elems: pointer to number of elements
124  * @cd: pointer to command details structure or NULL
125  *
126  * Get switch configuration (0x0200) to be placed in 'buff'.
127  * This admin command returns information such as initial VSI/port number
128  * and switch ID it belongs to.
129  *
130  * NOTE: *req_desc is both an input/output parameter.
131  * The caller of this function first calls this function with *request_desc set
132  * to 0.  If the response from f/w has *req_desc set to 0, all the switch
133  * configuration information has been returned; if non-zero (meaning not all
134  * the information was returned), the caller should call this function again
135  * with *req_desc set to the previous value returned by f/w to get the
136  * next block of switch configuration information.
137  *
138  * *num_elems is output only parameter. This reflects the number of elements
139  * in response buffer. The caller of this function to use *num_elems while
140  * parsing the response buffer.
141  */
142 static enum ice_status
143 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp *buf,
144 		  u16 buf_size, u16 *req_desc, u16 *num_elems,
145 		  struct ice_sq_cd *cd)
146 {
147 	struct ice_aqc_get_sw_cfg *cmd;
148 	enum ice_status status;
149 	struct ice_aq_desc desc;
150 
151 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
152 	cmd = &desc.params.get_sw_conf;
153 	cmd->element = cpu_to_le16(*req_desc);
154 
155 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
156 	if (!status) {
157 		*req_desc = le16_to_cpu(cmd->element);
158 		*num_elems = le16_to_cpu(cmd->num_elems);
159 	}
160 
161 	return status;
162 }
163 
164 /**
165  * ice_aq_add_vsi
166  * @hw: pointer to the hw struct
167  * @vsi_ctx: pointer to a VSI context struct
168  * @cd: pointer to command details structure or NULL
169  *
170  * Add a VSI context to the hardware (0x0210)
171  */
172 static enum ice_status
173 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
174 	       struct ice_sq_cd *cd)
175 {
176 	struct ice_aqc_add_update_free_vsi_resp *res;
177 	struct ice_aqc_add_get_update_free_vsi *cmd;
178 	struct ice_aq_desc desc;
179 	enum ice_status status;
180 
181 	cmd = &desc.params.vsi_cmd;
182 	res = &desc.params.add_update_free_vsi_res;
183 
184 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
185 
186 	if (!vsi_ctx->alloc_from_pool)
187 		cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
188 					   ICE_AQ_VSI_IS_VALID);
189 
190 	cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
191 
192 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
193 
194 	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
195 				 sizeof(vsi_ctx->info), cd);
196 
197 	if (!status) {
198 		vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
199 		vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
200 		vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
201 	}
202 
203 	return status;
204 }
205 
206 /**
207  * ice_aq_free_vsi
208  * @hw: pointer to the hw struct
209  * @vsi_ctx: pointer to a VSI context struct
210  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
211  * @cd: pointer to command details structure or NULL
212  *
213  * Free VSI context info from hardware (0x0213)
214  */
215 static enum ice_status
216 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
217 		bool keep_vsi_alloc, struct ice_sq_cd *cd)
218 {
219 	struct ice_aqc_add_update_free_vsi_resp *resp;
220 	struct ice_aqc_add_get_update_free_vsi *cmd;
221 	struct ice_aq_desc desc;
222 	enum ice_status status;
223 
224 	cmd = &desc.params.vsi_cmd;
225 	resp = &desc.params.add_update_free_vsi_res;
226 
227 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
228 
229 	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
230 	if (keep_vsi_alloc)
231 		cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
232 
233 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
234 	if (!status) {
235 		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
236 		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
237 	}
238 
239 	return status;
240 }
241 
242 /**
243  * ice_aq_update_vsi
244  * @hw: pointer to the hw struct
245  * @vsi_ctx: pointer to a VSI context struct
246  * @cd: pointer to command details structure or NULL
247  *
248  * Update VSI context in the hardware (0x0211)
249  */
250 enum ice_status
251 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
252 		  struct ice_sq_cd *cd)
253 {
254 	struct ice_aqc_add_update_free_vsi_resp *resp;
255 	struct ice_aqc_add_get_update_free_vsi *cmd;
256 	struct ice_aq_desc desc;
257 	enum ice_status status;
258 
259 	cmd = &desc.params.vsi_cmd;
260 	resp = &desc.params.add_update_free_vsi_res;
261 
262 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
263 
264 	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
265 
266 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
267 
268 	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
269 				 sizeof(vsi_ctx->info), cd);
270 
271 	if (!status) {
272 		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
273 		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
274 	}
275 
276 	return status;
277 }
278 
279 /**
280  * ice_update_fltr_vsi_map - update given filter VSI map
281  * @list_head: list for which filters needs to be updated
282  * @list_lock: filter lock which needs to be updated
283  * @old_vsi_num: old VSI HW id
284  * @new_vsi_num: new VSI HW id
285  *
286  * update the VSI map for a given filter list
287  */
288 static void
289 ice_update_fltr_vsi_map(struct list_head *list_head,
290 			struct mutex *list_lock, u16 old_vsi_num,
291 			u16 new_vsi_num)
292 {
293 	struct ice_fltr_mgmt_list_entry *itr;
294 
295 	mutex_lock(list_lock);
296 	if (list_empty(list_head))
297 		goto exit_update_map;
298 
299 	list_for_each_entry(itr, list_head, list_entry) {
300 		if (itr->vsi_list_info &&
301 		    test_bit(old_vsi_num, itr->vsi_list_info->vsi_map)) {
302 			clear_bit(old_vsi_num, itr->vsi_list_info->vsi_map);
303 			set_bit(new_vsi_num, itr->vsi_list_info->vsi_map);
304 		} else if (itr->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
305 			   itr->fltr_info.fwd_id.vsi_id == old_vsi_num) {
306 			itr->fltr_info.fwd_id.vsi_id = new_vsi_num;
307 			itr->fltr_info.src = new_vsi_num;
308 		}
309 	}
310 exit_update_map:
311 	mutex_unlock(list_lock);
312 }
313 
314 /**
315  * ice_update_all_fltr_vsi_map - update all filters VSI map
316  * @hw: pointer to the hardware structure
317  * @old_vsi_num: old VSI HW id
318  * @new_vsi_num: new VSI HW id
319  *
320  * update all filters VSI map
321  */
322 static void
323 ice_update_all_fltr_vsi_map(struct ice_hw *hw, u16 old_vsi_num, u16 new_vsi_num)
324 {
325 	struct ice_switch_info *sw = hw->switch_info;
326 	u8 i;
327 
328 	for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
329 		struct list_head *head = &sw->recp_list[i].filt_rules;
330 		struct mutex *lock; /* Lock to protect filter rule list */
331 
332 		lock = &sw->recp_list[i].filt_rule_lock;
333 		ice_update_fltr_vsi_map(head, lock, old_vsi_num,
334 					new_vsi_num);
335 	}
336 }
337 
338 /**
339  * ice_is_vsi_valid - check whether the VSI is valid or not
340  * @hw: pointer to the hw struct
341  * @vsi_handle: VSI handle
342  *
343  * check whether the VSI is valid or not
344  */
345 static bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
346 {
347 	return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
348 }
349 
350 /**
351  * ice_get_hw_vsi_num - return the hw VSI number
352  * @hw: pointer to the hw struct
353  * @vsi_handle: VSI handle
354  *
355  * return the hw VSI number
356  * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
357  */
358 static u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
359 {
360 	return hw->vsi_ctx[vsi_handle]->vsi_num;
361 }
362 
363 /**
364  * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
365  * @hw: pointer to the hw struct
366  * @vsi_handle: VSI handle
367  *
368  * return the VSI context entry for a given VSI handle
369  */
370 static struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
371 {
372 	return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
373 }
374 
375 /**
376  * ice_save_vsi_ctx - save the VSI context for a given VSI handle
377  * @hw: pointer to the hw struct
378  * @vsi_handle: VSI handle
379  * @vsi: VSI context pointer
380  *
381  * save the VSI context entry for a given VSI handle
382  */
383 static void ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle,
384 			     struct ice_vsi_ctx *vsi)
385 {
386 	hw->vsi_ctx[vsi_handle] = vsi;
387 }
388 
389 /**
390  * ice_clear_vsi_ctx - clear the VSI context entry
391  * @hw: pointer to the hw struct
392  * @vsi_handle: VSI handle
393  *
394  * clear the VSI context entry
395  */
396 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
397 {
398 	struct ice_vsi_ctx *vsi;
399 
400 	vsi = ice_get_vsi_ctx(hw, vsi_handle);
401 	if (vsi) {
402 		devm_kfree(ice_hw_to_dev(hw), vsi);
403 		hw->vsi_ctx[vsi_handle] = NULL;
404 	}
405 }
406 
407 /**
408  * ice_add_vsi - add VSI context to the hardware and VSI handle list
409  * @hw: pointer to the hw struct
410  * @vsi_handle: unique VSI handle provided by drivers
411  * @vsi_ctx: pointer to a VSI context struct
412  * @cd: pointer to command details structure or NULL
413  *
414  * Add a VSI context to the hardware also add it into the VSI handle list.
415  * If this function gets called after reset for existing VSIs then update
416  * with the new HW VSI number in the corresponding VSI handle list entry.
417  */
418 enum ice_status
419 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
420 	    struct ice_sq_cd *cd)
421 {
422 	struct ice_vsi_ctx *tmp_vsi_ctx;
423 	enum ice_status status;
424 
425 	if (vsi_handle >= ICE_MAX_VSI)
426 		return ICE_ERR_PARAM;
427 	status = ice_aq_add_vsi(hw, vsi_ctx, cd);
428 	if (status)
429 		return status;
430 	tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
431 	if (!tmp_vsi_ctx) {
432 		/* Create a new vsi context */
433 		tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
434 					   sizeof(*tmp_vsi_ctx), GFP_KERNEL);
435 		if (!tmp_vsi_ctx) {
436 			ice_aq_free_vsi(hw, vsi_ctx, false, cd);
437 			return ICE_ERR_NO_MEMORY;
438 		}
439 		*tmp_vsi_ctx = *vsi_ctx;
440 		ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
441 	} else {
442 		/* update with new HW VSI num */
443 		if (tmp_vsi_ctx->vsi_num != vsi_ctx->vsi_num) {
444 			/* update all filter lists with new HW VSI num */
445 			ice_update_all_fltr_vsi_map(hw, tmp_vsi_ctx->vsi_num,
446 						    vsi_ctx->vsi_num);
447 			tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
448 		}
449 	}
450 
451 	return status;
452 }
453 
454 /**
455  * ice_free_vsi- free VSI context from hardware and VSI handle list
456  * @hw: pointer to the hw struct
457  * @vsi_handle: unique VSI handle
458  * @vsi_ctx: pointer to a VSI context struct
459  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
460  * @cd: pointer to command details structure or NULL
461  *
462  * Free VSI context info from hardware as well as from VSI handle list
463  */
464 enum ice_status
465 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
466 	     bool keep_vsi_alloc, struct ice_sq_cd *cd)
467 {
468 	enum ice_status status;
469 
470 	if (!ice_is_vsi_valid(hw, vsi_handle))
471 		return ICE_ERR_PARAM;
472 	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
473 	status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
474 	if (!status)
475 		ice_clear_vsi_ctx(hw, vsi_handle);
476 	return status;
477 }
478 
479 /**
480  * ice_aq_alloc_free_vsi_list
481  * @hw: pointer to the hw struct
482  * @vsi_list_id: VSI list id returned or used for lookup
483  * @lkup_type: switch rule filter lookup type
484  * @opc: switch rules population command type - pass in the command opcode
485  *
486  * allocates or free a VSI list resource
487  */
488 static enum ice_status
489 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
490 			   enum ice_sw_lkup_type lkup_type,
491 			   enum ice_adminq_opc opc)
492 {
493 	struct ice_aqc_alloc_free_res_elem *sw_buf;
494 	struct ice_aqc_res_elem *vsi_ele;
495 	enum ice_status status;
496 	u16 buf_len;
497 
498 	buf_len = sizeof(*sw_buf);
499 	sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
500 	if (!sw_buf)
501 		return ICE_ERR_NO_MEMORY;
502 	sw_buf->num_elems = cpu_to_le16(1);
503 
504 	if (lkup_type == ICE_SW_LKUP_MAC ||
505 	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
506 	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
507 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
508 	    lkup_type == ICE_SW_LKUP_PROMISC ||
509 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN) {
510 		sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
511 	} else if (lkup_type == ICE_SW_LKUP_VLAN) {
512 		sw_buf->res_type =
513 			cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
514 	} else {
515 		status = ICE_ERR_PARAM;
516 		goto ice_aq_alloc_free_vsi_list_exit;
517 	}
518 
519 	if (opc == ice_aqc_opc_free_res)
520 		sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
521 
522 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
523 	if (status)
524 		goto ice_aq_alloc_free_vsi_list_exit;
525 
526 	if (opc == ice_aqc_opc_alloc_res) {
527 		vsi_ele = &sw_buf->elem[0];
528 		*vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
529 	}
530 
531 ice_aq_alloc_free_vsi_list_exit:
532 	devm_kfree(ice_hw_to_dev(hw), sw_buf);
533 	return status;
534 }
535 
536 /**
537  * ice_aq_sw_rules - add/update/remove switch rules
538  * @hw: pointer to the hw struct
539  * @rule_list: pointer to switch rule population list
540  * @rule_list_sz: total size of the rule list in bytes
541  * @num_rules: number of switch rules in the rule_list
542  * @opc: switch rules population command type - pass in the command opcode
543  * @cd: pointer to command details structure or NULL
544  *
545  * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
546  */
547 static enum ice_status
548 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
549 		u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
550 {
551 	struct ice_aq_desc desc;
552 
553 	if (opc != ice_aqc_opc_add_sw_rules &&
554 	    opc != ice_aqc_opc_update_sw_rules &&
555 	    opc != ice_aqc_opc_remove_sw_rules)
556 		return ICE_ERR_PARAM;
557 
558 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
559 
560 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
561 	desc.params.sw_rules.num_rules_fltr_entry_index =
562 		cpu_to_le16(num_rules);
563 	return ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
564 }
565 
566 /* ice_init_port_info - Initialize port_info with switch configuration data
567  * @pi: pointer to port_info
568  * @vsi_port_num: VSI number or port number
569  * @type: Type of switch element (port or VSI)
570  * @swid: switch ID of the switch the element is attached to
571  * @pf_vf_num: PF or VF number
572  * @is_vf: true if the element is a VF, false otherwise
573  */
574 static void
575 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
576 		   u16 swid, u16 pf_vf_num, bool is_vf)
577 {
578 	switch (type) {
579 	case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
580 		pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
581 		pi->sw_id = swid;
582 		pi->pf_vf_num = pf_vf_num;
583 		pi->is_vf = is_vf;
584 		pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
585 		pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
586 		break;
587 	default:
588 		ice_debug(pi->hw, ICE_DBG_SW,
589 			  "incorrect VSI/port type received\n");
590 		break;
591 	}
592 }
593 
594 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
595  * @hw: pointer to the hardware structure
596  */
597 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
598 {
599 	struct ice_aqc_get_sw_cfg_resp *rbuf;
600 	enum ice_status status;
601 	u16 req_desc = 0;
602 	u16 num_elems;
603 	u16 i;
604 
605 	rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN,
606 			    GFP_KERNEL);
607 
608 	if (!rbuf)
609 		return ICE_ERR_NO_MEMORY;
610 
611 	/* Multiple calls to ice_aq_get_sw_cfg may be required
612 	 * to get all the switch configuration information. The need
613 	 * for additional calls is indicated by ice_aq_get_sw_cfg
614 	 * writing a non-zero value in req_desc
615 	 */
616 	do {
617 		status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
618 					   &req_desc, &num_elems, NULL);
619 
620 		if (status)
621 			break;
622 
623 		for (i = 0; i < num_elems; i++) {
624 			struct ice_aqc_get_sw_cfg_resp_elem *ele;
625 			u16 pf_vf_num, swid, vsi_port_num;
626 			bool is_vf = false;
627 			u8 type;
628 
629 			ele = rbuf[i].elements;
630 			vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
631 				ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
632 
633 			pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
634 				ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
635 
636 			swid = le16_to_cpu(ele->swid);
637 
638 			if (le16_to_cpu(ele->pf_vf_num) &
639 			    ICE_AQC_GET_SW_CONF_RESP_IS_VF)
640 				is_vf = true;
641 
642 			type = le16_to_cpu(ele->vsi_port_num) >>
643 				ICE_AQC_GET_SW_CONF_RESP_TYPE_S;
644 
645 			if (type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
646 				/* FW VSI is not needed. Just continue. */
647 				continue;
648 			}
649 
650 			ice_init_port_info(hw->port_info, vsi_port_num,
651 					   type, swid, pf_vf_num, is_vf);
652 		}
653 	} while (req_desc && !status);
654 
655 	devm_kfree(ice_hw_to_dev(hw), (void *)rbuf);
656 	return status;
657 }
658 
659 /**
660  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
661  * @hw: pointer to the hardware structure
662  * @f_info: filter info structure to fill/update
663  *
664  * This helper function populates the lb_en and lan_en elements of the provided
665  * ice_fltr_info struct using the switch's type and characteristics of the
666  * switch rule being configured.
667  */
668 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *f_info)
669 {
670 	f_info->lb_en = false;
671 	f_info->lan_en = false;
672 	if ((f_info->flag & ICE_FLTR_TX) &&
673 	    (f_info->fltr_act == ICE_FWD_TO_VSI ||
674 	     f_info->fltr_act == ICE_FWD_TO_VSI_LIST ||
675 	     f_info->fltr_act == ICE_FWD_TO_Q ||
676 	     f_info->fltr_act == ICE_FWD_TO_QGRP)) {
677 		f_info->lb_en = true;
678 		if (!(hw->evb_veb && f_info->lkup_type == ICE_SW_LKUP_MAC &&
679 		      is_unicast_ether_addr(f_info->l_data.mac.mac_addr)))
680 			f_info->lan_en = true;
681 	}
682 }
683 
684 /**
685  * ice_fill_sw_rule - Helper function to fill switch rule structure
686  * @hw: pointer to the hardware structure
687  * @f_info: entry containing packet forwarding information
688  * @s_rule: switch rule structure to be filled in based on mac_entry
689  * @opc: switch rules population command type - pass in the command opcode
690  */
691 static void
692 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
693 		 struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
694 {
695 	u16 vlan_id = ICE_MAX_VLAN_ID + 1;
696 	void *daddr = NULL;
697 	u16 eth_hdr_sz;
698 	u8 *eth_hdr;
699 	u32 act = 0;
700 	__be16 *off;
701 
702 	if (opc == ice_aqc_opc_remove_sw_rules) {
703 		s_rule->pdata.lkup_tx_rx.act = 0;
704 		s_rule->pdata.lkup_tx_rx.index =
705 			cpu_to_le16(f_info->fltr_rule_id);
706 		s_rule->pdata.lkup_tx_rx.hdr_len = 0;
707 		return;
708 	}
709 
710 	eth_hdr_sz = sizeof(dummy_eth_header);
711 	eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
712 
713 	/* initialize the ether header with a dummy header */
714 	memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
715 	ice_fill_sw_info(hw, f_info);
716 
717 	switch (f_info->fltr_act) {
718 	case ICE_FWD_TO_VSI:
719 		act |= (f_info->fwd_id.vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
720 			ICE_SINGLE_ACT_VSI_ID_M;
721 		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
722 			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
723 				ICE_SINGLE_ACT_VALID_BIT;
724 		break;
725 	case ICE_FWD_TO_VSI_LIST:
726 		act |= ICE_SINGLE_ACT_VSI_LIST;
727 		act |= (f_info->fwd_id.vsi_list_id <<
728 			ICE_SINGLE_ACT_VSI_LIST_ID_S) &
729 			ICE_SINGLE_ACT_VSI_LIST_ID_M;
730 		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
731 			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
732 				ICE_SINGLE_ACT_VALID_BIT;
733 		break;
734 	case ICE_FWD_TO_Q:
735 		act |= ICE_SINGLE_ACT_TO_Q;
736 		act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
737 			ICE_SINGLE_ACT_Q_INDEX_M;
738 		break;
739 	case ICE_FWD_TO_QGRP:
740 		act |= ICE_SINGLE_ACT_TO_Q;
741 		act |= (f_info->qgrp_size << ICE_SINGLE_ACT_Q_REGION_S) &
742 			ICE_SINGLE_ACT_Q_REGION_M;
743 		break;
744 	case ICE_DROP_PACKET:
745 		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP;
746 		break;
747 	default:
748 		return;
749 	}
750 
751 	if (f_info->lb_en)
752 		act |= ICE_SINGLE_ACT_LB_ENABLE;
753 	if (f_info->lan_en)
754 		act |= ICE_SINGLE_ACT_LAN_ENABLE;
755 
756 	switch (f_info->lkup_type) {
757 	case ICE_SW_LKUP_MAC:
758 		daddr = f_info->l_data.mac.mac_addr;
759 		break;
760 	case ICE_SW_LKUP_VLAN:
761 		vlan_id = f_info->l_data.vlan.vlan_id;
762 		if (f_info->fltr_act == ICE_FWD_TO_VSI ||
763 		    f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
764 			act |= ICE_SINGLE_ACT_PRUNE;
765 			act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
766 		}
767 		break;
768 	case ICE_SW_LKUP_ETHERTYPE_MAC:
769 		daddr = f_info->l_data.ethertype_mac.mac_addr;
770 		/* fall-through */
771 	case ICE_SW_LKUP_ETHERTYPE:
772 		off = (__be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
773 		*off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
774 		break;
775 	case ICE_SW_LKUP_MAC_VLAN:
776 		daddr = f_info->l_data.mac_vlan.mac_addr;
777 		vlan_id = f_info->l_data.mac_vlan.vlan_id;
778 		break;
779 	case ICE_SW_LKUP_PROMISC_VLAN:
780 		vlan_id = f_info->l_data.mac_vlan.vlan_id;
781 		/* fall-through */
782 	case ICE_SW_LKUP_PROMISC:
783 		daddr = f_info->l_data.mac_vlan.mac_addr;
784 		break;
785 	default:
786 		break;
787 	}
788 
789 	s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
790 		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
791 		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
792 
793 	/* Recipe set depending on lookup type */
794 	s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(f_info->lkup_type);
795 	s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(f_info->src);
796 	s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act);
797 
798 	if (daddr)
799 		ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
800 
801 	if (!(vlan_id > ICE_MAX_VLAN_ID)) {
802 		off = (__be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
803 		*off = cpu_to_be16(vlan_id);
804 	}
805 
806 	/* Create the switch rule with the final dummy Ethernet header */
807 	if (opc != ice_aqc_opc_update_sw_rules)
808 		s_rule->pdata.lkup_tx_rx.hdr_len = cpu_to_le16(eth_hdr_sz);
809 }
810 
811 /**
812  * ice_add_marker_act
813  * @hw: pointer to the hardware structure
814  * @m_ent: the management entry for which sw marker needs to be added
815  * @sw_marker: sw marker to tag the Rx descriptor with
816  * @l_id: large action resource id
817  *
818  * Create a large action to hold software marker and update the switch rule
819  * entry pointed by m_ent with newly created large action
820  */
821 static enum ice_status
822 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
823 		   u16 sw_marker, u16 l_id)
824 {
825 	struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
826 	/* For software marker we need 3 large actions
827 	 * 1. FWD action: FWD TO VSI or VSI LIST
828 	 * 2. GENERIC VALUE action to hold the profile id
829 	 * 3. GENERIC VALUE action to hold the software marker id
830 	 */
831 	const u16 num_lg_acts = 3;
832 	enum ice_status status;
833 	u16 lg_act_size;
834 	u16 rules_size;
835 	u16 vsi_info;
836 	u32 act;
837 
838 	if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
839 		return ICE_ERR_PARAM;
840 
841 	/* Create two back-to-back switch rules and submit them to the HW using
842 	 * one memory buffer:
843 	 *    1. Large Action
844 	 *    2. Look up tx rx
845 	 */
846 	lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
847 	rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
848 	lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
849 	if (!lg_act)
850 		return ICE_ERR_NO_MEMORY;
851 
852 	rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
853 
854 	/* Fill in the first switch rule i.e. large action */
855 	lg_act->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
856 	lg_act->pdata.lg_act.index = cpu_to_le16(l_id);
857 	lg_act->pdata.lg_act.size = cpu_to_le16(num_lg_acts);
858 
859 	/* First action VSI forwarding or VSI list forwarding depending on how
860 	 * many VSIs
861 	 */
862 	vsi_info = (m_ent->vsi_count > 1) ?
863 		m_ent->fltr_info.fwd_id.vsi_list_id :
864 		m_ent->fltr_info.fwd_id.vsi_id;
865 
866 	act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
867 	act |= (vsi_info << ICE_LG_ACT_VSI_LIST_ID_S) &
868 		ICE_LG_ACT_VSI_LIST_ID_M;
869 	if (m_ent->vsi_count > 1)
870 		act |= ICE_LG_ACT_VSI_LIST;
871 	lg_act->pdata.lg_act.act[0] = cpu_to_le32(act);
872 
873 	/* Second action descriptor type */
874 	act = ICE_LG_ACT_GENERIC;
875 
876 	act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
877 	lg_act->pdata.lg_act.act[1] = cpu_to_le32(act);
878 
879 	act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
880 	       ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
881 
882 	/* Third action Marker value */
883 	act |= ICE_LG_ACT_GENERIC;
884 	act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
885 		ICE_LG_ACT_GENERIC_VALUE_M;
886 
887 	lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);
888 
889 	/* call the fill switch rule to fill the lookup tx rx structure */
890 	ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
891 			 ice_aqc_opc_update_sw_rules);
892 
893 	/* Update the action to point to the large action id */
894 	rx_tx->pdata.lkup_tx_rx.act =
895 		cpu_to_le32(ICE_SINGLE_ACT_PTR |
896 			    ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
897 			     ICE_SINGLE_ACT_PTR_VAL_M));
898 
899 	/* Use the filter rule id of the previously created rule with single
900 	 * act. Once the update happens, hardware will treat this as large
901 	 * action
902 	 */
903 	rx_tx->pdata.lkup_tx_rx.index =
904 		cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
905 
906 	status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
907 				 ice_aqc_opc_update_sw_rules, NULL);
908 	if (!status) {
909 		m_ent->lg_act_idx = l_id;
910 		m_ent->sw_marker_id = sw_marker;
911 	}
912 
913 	devm_kfree(ice_hw_to_dev(hw), lg_act);
914 	return status;
915 }
916 
917 /**
918  * ice_create_vsi_list_map
919  * @hw: pointer to the hardware structure
920  * @vsi_array: array of VSIs to form a VSI list
921  * @num_vsi: num VSI in the array
922  * @vsi_list_id: VSI list id generated as part of allocate resource
923  *
924  * Helper function to create a new entry of VSI list id to VSI mapping
925  * using the given VSI list id
926  */
927 static struct ice_vsi_list_map_info *
928 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
929 			u16 vsi_list_id)
930 {
931 	struct ice_switch_info *sw = hw->switch_info;
932 	struct ice_vsi_list_map_info *v_map;
933 	int i;
934 
935 	v_map = devm_kcalloc(ice_hw_to_dev(hw), 1, sizeof(*v_map), GFP_KERNEL);
936 	if (!v_map)
937 		return NULL;
938 
939 	v_map->vsi_list_id = vsi_list_id;
940 
941 	for (i = 0; i < num_vsi; i++)
942 		set_bit(vsi_array[i], v_map->vsi_map);
943 
944 	list_add(&v_map->list_entry, &sw->vsi_list_map_head);
945 	return v_map;
946 }
947 
948 /**
949  * ice_update_vsi_list_rule
950  * @hw: pointer to the hardware structure
951  * @vsi_array: array of VSIs to form a VSI list
952  * @num_vsi: num VSI in the array
953  * @vsi_list_id: VSI list id generated as part of allocate resource
954  * @remove: Boolean value to indicate if this is a remove action
955  * @opc: switch rules population command type - pass in the command opcode
956  * @lkup_type: lookup type of the filter
957  *
958  * Call AQ command to add a new switch rule or update existing switch rule
959  * using the given VSI list id
960  */
961 static enum ice_status
962 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
963 			 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
964 			 enum ice_sw_lkup_type lkup_type)
965 {
966 	struct ice_aqc_sw_rules_elem *s_rule;
967 	enum ice_status status;
968 	u16 s_rule_size;
969 	u16 type;
970 	int i;
971 
972 	if (!num_vsi)
973 		return ICE_ERR_PARAM;
974 
975 	if (lkup_type == ICE_SW_LKUP_MAC ||
976 	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
977 	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
978 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
979 	    lkup_type == ICE_SW_LKUP_PROMISC ||
980 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN)
981 		type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
982 				ICE_AQC_SW_RULES_T_VSI_LIST_SET;
983 	else if (lkup_type == ICE_SW_LKUP_VLAN)
984 		type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
985 				ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
986 	else
987 		return ICE_ERR_PARAM;
988 
989 	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
990 	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
991 	if (!s_rule)
992 		return ICE_ERR_NO_MEMORY;
993 
994 	for (i = 0; i < num_vsi; i++)
995 		s_rule->pdata.vsi_list.vsi[i] = cpu_to_le16(vsi_array[i]);
996 
997 	s_rule->type = cpu_to_le16(type);
998 	s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi);
999 	s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);
1000 
1001 	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
1002 
1003 	devm_kfree(ice_hw_to_dev(hw), s_rule);
1004 	return status;
1005 }
1006 
1007 /**
1008  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
1009  * @hw: pointer to the hw struct
1010  * @vsi_array: array of VSIs to form a VSI list
1011  * @num_vsi: number of VSIs in the array
1012  * @vsi_list_id: stores the ID of the VSI list to be created
1013  * @lkup_type: switch rule filter's lookup type
1014  */
1015 static enum ice_status
1016 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
1017 			 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
1018 {
1019 	enum ice_status status;
1020 	int i;
1021 
1022 	for (i = 0; i < num_vsi; i++)
1023 		if (vsi_array[i] >= ICE_MAX_VSI)
1024 			return ICE_ERR_OUT_OF_RANGE;
1025 
1026 	status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
1027 					    ice_aqc_opc_alloc_res);
1028 	if (status)
1029 		return status;
1030 
1031 	/* Update the newly created VSI list to include the specified VSIs */
1032 	return ice_update_vsi_list_rule(hw, vsi_array, num_vsi, *vsi_list_id,
1033 					false, ice_aqc_opc_add_sw_rules,
1034 					lkup_type);
1035 }
1036 
1037 /**
1038  * ice_create_pkt_fwd_rule
1039  * @hw: pointer to the hardware structure
1040  * @f_entry: entry containing packet forwarding information
1041  *
1042  * Create switch rule with given filter information and add an entry
1043  * to the corresponding filter management list to track this switch rule
1044  * and VSI mapping
1045  */
1046 static enum ice_status
1047 ice_create_pkt_fwd_rule(struct ice_hw *hw,
1048 			struct ice_fltr_list_entry *f_entry)
1049 {
1050 	struct ice_fltr_mgmt_list_entry *fm_entry;
1051 	struct ice_aqc_sw_rules_elem *s_rule;
1052 	enum ice_sw_lkup_type l_type;
1053 	struct ice_sw_recipe *recp;
1054 	enum ice_status status;
1055 
1056 	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1057 			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1058 	if (!s_rule)
1059 		return ICE_ERR_NO_MEMORY;
1060 	fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
1061 				GFP_KERNEL);
1062 	if (!fm_entry) {
1063 		status = ICE_ERR_NO_MEMORY;
1064 		goto ice_create_pkt_fwd_rule_exit;
1065 	}
1066 
1067 	fm_entry->fltr_info = f_entry->fltr_info;
1068 
1069 	/* Initialize all the fields for the management entry */
1070 	fm_entry->vsi_count = 1;
1071 	fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
1072 	fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
1073 	fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
1074 
1075 	ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
1076 			 ice_aqc_opc_add_sw_rules);
1077 
1078 	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
1079 				 ice_aqc_opc_add_sw_rules, NULL);
1080 	if (status) {
1081 		devm_kfree(ice_hw_to_dev(hw), fm_entry);
1082 		goto ice_create_pkt_fwd_rule_exit;
1083 	}
1084 
1085 	f_entry->fltr_info.fltr_rule_id =
1086 		le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1087 	fm_entry->fltr_info.fltr_rule_id =
1088 		le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1089 
1090 	/* The book keeping entries will get removed when base driver
1091 	 * calls remove filter AQ command
1092 	 */
1093 	l_type = fm_entry->fltr_info.lkup_type;
1094 	recp = &hw->switch_info->recp_list[l_type];
1095 	list_add(&fm_entry->list_entry, &recp->filt_rules);
1096 
1097 ice_create_pkt_fwd_rule_exit:
1098 	devm_kfree(ice_hw_to_dev(hw), s_rule);
1099 	return status;
1100 }
1101 
1102 /**
1103  * ice_update_pkt_fwd_rule
1104  * @hw: pointer to the hardware structure
1105  * @f_info: filter information for switch rule
1106  *
1107  * Call AQ command to update a previously created switch rule with a
1108  * VSI list id
1109  */
1110 static enum ice_status
1111 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
1112 {
1113 	struct ice_aqc_sw_rules_elem *s_rule;
1114 	enum ice_status status;
1115 
1116 	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1117 			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1118 	if (!s_rule)
1119 		return ICE_ERR_NO_MEMORY;
1120 
1121 	ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
1122 
1123 	s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(f_info->fltr_rule_id);
1124 
1125 	/* Update switch rule with new rule set to forward VSI list */
1126 	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
1127 				 ice_aqc_opc_update_sw_rules, NULL);
1128 
1129 	devm_kfree(ice_hw_to_dev(hw), s_rule);
1130 	return status;
1131 }
1132 
1133 /**
1134  * ice_update_sw_rule_bridge_mode
1135  * @hw: pointer to the hw struct
1136  *
1137  * Updates unicast switch filter rules based on VEB/VEPA mode
1138  */
1139 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
1140 {
1141 	struct ice_switch_info *sw = hw->switch_info;
1142 	struct ice_fltr_mgmt_list_entry *fm_entry;
1143 	enum ice_status status = 0;
1144 	struct list_head *rule_head;
1145 	struct mutex *rule_lock; /* Lock to protect filter rule list */
1146 
1147 	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
1148 	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
1149 
1150 	mutex_lock(rule_lock);
1151 	list_for_each_entry(fm_entry, rule_head, list_entry) {
1152 		struct ice_fltr_info *fi = &fm_entry->fltr_info;
1153 		u8 *addr = fi->l_data.mac.mac_addr;
1154 
1155 		/* Update unicast Tx rules to reflect the selected
1156 		 * VEB/VEPA mode
1157 		 */
1158 		if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
1159 		    (fi->fltr_act == ICE_FWD_TO_VSI ||
1160 		     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
1161 		     fi->fltr_act == ICE_FWD_TO_Q ||
1162 		     fi->fltr_act == ICE_FWD_TO_QGRP)) {
1163 			status = ice_update_pkt_fwd_rule(hw, fi);
1164 			if (status)
1165 				break;
1166 		}
1167 	}
1168 
1169 	mutex_unlock(rule_lock);
1170 
1171 	return status;
1172 }
1173 
1174 /**
1175  * ice_add_update_vsi_list
1176  * @hw: pointer to the hardware structure
1177  * @m_entry: pointer to current filter management list entry
1178  * @cur_fltr: filter information from the book keeping entry
1179  * @new_fltr: filter information with the new VSI to be added
1180  *
1181  * Call AQ command to add or update previously created VSI list with new VSI.
1182  *
1183  * Helper function to do book keeping associated with adding filter information
1184  * The algorithm to do the booking keeping is described below :
1185  * When a VSI needs to subscribe to a given filter( MAC/VLAN/Ethtype etc.)
1186  *	if only one VSI has been added till now
1187  *		Allocate a new VSI list and add two VSIs
1188  *		to this list using switch rule command
1189  *		Update the previously created switch rule with the
1190  *		newly created VSI list id
1191  *	if a VSI list was previously created
1192  *		Add the new VSI to the previously created VSI list set
1193  *		using the update switch rule command
1194  */
1195 static enum ice_status
1196 ice_add_update_vsi_list(struct ice_hw *hw,
1197 			struct ice_fltr_mgmt_list_entry *m_entry,
1198 			struct ice_fltr_info *cur_fltr,
1199 			struct ice_fltr_info *new_fltr)
1200 {
1201 	enum ice_status status = 0;
1202 	u16 vsi_list_id = 0;
1203 
1204 	if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
1205 	     cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
1206 		return ICE_ERR_NOT_IMPL;
1207 
1208 	if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
1209 	     new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
1210 	    (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
1211 	     cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
1212 		return ICE_ERR_NOT_IMPL;
1213 
1214 	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
1215 		/* Only one entry existed in the mapping and it was not already
1216 		 * a part of a VSI list. So, create a VSI list with the old and
1217 		 * new VSIs.
1218 		 */
1219 		struct ice_fltr_info tmp_fltr;
1220 		u16 vsi_id_arr[2];
1221 
1222 		/* A rule already exists with the new VSI being added */
1223 		if (cur_fltr->fwd_id.vsi_id == new_fltr->fwd_id.vsi_id)
1224 			return ICE_ERR_ALREADY_EXISTS;
1225 
1226 		vsi_id_arr[0] = cur_fltr->fwd_id.vsi_id;
1227 		vsi_id_arr[1] = new_fltr->fwd_id.vsi_id;
1228 		status = ice_create_vsi_list_rule(hw, &vsi_id_arr[0], 2,
1229 						  &vsi_list_id,
1230 						  new_fltr->lkup_type);
1231 		if (status)
1232 			return status;
1233 
1234 		tmp_fltr = *new_fltr;
1235 		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
1236 		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
1237 		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
1238 		/* Update the previous switch rule of "MAC forward to VSI" to
1239 		 * "MAC fwd to VSI list"
1240 		 */
1241 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
1242 		if (status)
1243 			return status;
1244 
1245 		cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
1246 		cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1247 		m_entry->vsi_list_info =
1248 			ice_create_vsi_list_map(hw, &vsi_id_arr[0], 2,
1249 						vsi_list_id);
1250 
1251 		/* If this entry was large action then the large action needs
1252 		 * to be updated to point to FWD to VSI list
1253 		 */
1254 		if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
1255 			status =
1256 			    ice_add_marker_act(hw, m_entry,
1257 					       m_entry->sw_marker_id,
1258 					       m_entry->lg_act_idx);
1259 	} else {
1260 		u16 vsi_id = new_fltr->fwd_id.vsi_id;
1261 		enum ice_adminq_opc opcode;
1262 
1263 		/* A rule already exists with the new VSI being added */
1264 		if (test_bit(vsi_id, m_entry->vsi_list_info->vsi_map))
1265 			return 0;
1266 
1267 		/* Update the previously created VSI list set with
1268 		 * the new VSI id passed in
1269 		 */
1270 		vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
1271 		opcode = ice_aqc_opc_update_sw_rules;
1272 
1273 		status = ice_update_vsi_list_rule(hw, &vsi_id, 1, vsi_list_id,
1274 						  false, opcode,
1275 						  new_fltr->lkup_type);
1276 		/* update VSI list mapping info with new VSI id */
1277 		if (!status)
1278 			set_bit(vsi_id, m_entry->vsi_list_info->vsi_map);
1279 	}
1280 	if (!status)
1281 		m_entry->vsi_count++;
1282 	return status;
1283 }
1284 
1285 /**
1286  * ice_find_rule_entry - Search a rule entry
1287  * @hw: pointer to the hardware structure
1288  * @recp_id: lookup type for which the specified rule needs to be searched
1289  * @f_info: rule information
1290  *
1291  * Helper function to search for a given rule entry
1292  * Returns pointer to entry storing the rule if found
1293  */
1294 static struct ice_fltr_mgmt_list_entry *
1295 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
1296 {
1297 	struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
1298 	struct ice_switch_info *sw = hw->switch_info;
1299 	struct list_head *list_head;
1300 
1301 	list_head = &sw->recp_list[recp_id].filt_rules;
1302 	list_for_each_entry(list_itr, list_head, list_entry) {
1303 		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
1304 			    sizeof(f_info->l_data)) &&
1305 		    f_info->flag == list_itr->fltr_info.flag) {
1306 			ret = list_itr;
1307 			break;
1308 		}
1309 	}
1310 	return ret;
1311 }
1312 
1313 /**
1314  * ice_add_rule_internal - add rule for a given lookup type
1315  * @hw: pointer to the hardware structure
1316  * @recp_id: lookup type (recipe id) for which rule has to be added
1317  * @f_entry: structure containing MAC forwarding information
1318  *
1319  * Adds or updates the rule lists for a given recipe
1320  */
1321 static enum ice_status
1322 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
1323 		      struct ice_fltr_list_entry *f_entry)
1324 {
1325 	struct ice_switch_info *sw = hw->switch_info;
1326 	struct ice_fltr_info *new_fltr, *cur_fltr;
1327 	struct ice_fltr_mgmt_list_entry *m_entry;
1328 	struct mutex *rule_lock; /* Lock to protect filter rule list */
1329 	enum ice_status status = 0;
1330 
1331 	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1332 
1333 	mutex_lock(rule_lock);
1334 	new_fltr = &f_entry->fltr_info;
1335 	if (new_fltr->flag & ICE_FLTR_RX)
1336 		new_fltr->src = hw->port_info->lport;
1337 	else if (new_fltr->flag & ICE_FLTR_TX)
1338 		new_fltr->src = f_entry->fltr_info.fwd_id.vsi_id;
1339 
1340 	m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
1341 	if (!m_entry) {
1342 		mutex_unlock(rule_lock);
1343 		return ice_create_pkt_fwd_rule(hw, f_entry);
1344 	}
1345 
1346 	cur_fltr = &m_entry->fltr_info;
1347 	status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
1348 	mutex_unlock(rule_lock);
1349 
1350 	return status;
1351 }
1352 
1353 /**
1354  * ice_remove_vsi_list_rule
1355  * @hw: pointer to the hardware structure
1356  * @vsi_list_id: VSI list id generated as part of allocate resource
1357  * @lkup_type: switch rule filter lookup type
1358  *
1359  * The VSI list should be emptied before this function is called to remove the
1360  * VSI list.
1361  */
1362 static enum ice_status
1363 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
1364 			 enum ice_sw_lkup_type lkup_type)
1365 {
1366 	struct ice_aqc_sw_rules_elem *s_rule;
1367 	enum ice_status status;
1368 	u16 s_rule_size;
1369 
1370 	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(0);
1371 	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
1372 	if (!s_rule)
1373 		return ICE_ERR_NO_MEMORY;
1374 
1375 	s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
1376 	s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);
1377 
1378 	/* Free the vsi_list resource that we allocated. It is assumed that the
1379 	 * list is empty at this point.
1380 	 */
1381 	status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
1382 					    ice_aqc_opc_free_res);
1383 
1384 	devm_kfree(ice_hw_to_dev(hw), s_rule);
1385 	return status;
1386 }
1387 
1388 /**
1389  * ice_rem_update_vsi_list
1390  * @hw: pointer to the hardware structure
1391  * @vsi_id: ID of the VSI to remove
1392  * @fm_list: filter management entry for which the VSI list management needs to
1393  *           be done
1394  */
1395 static enum ice_status
1396 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_id,
1397 			struct ice_fltr_mgmt_list_entry *fm_list)
1398 {
1399 	enum ice_sw_lkup_type lkup_type;
1400 	enum ice_status status = 0;
1401 	u16 vsi_list_id;
1402 
1403 	if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
1404 	    fm_list->vsi_count == 0)
1405 		return ICE_ERR_PARAM;
1406 
1407 	/* A rule with the VSI being removed does not exist */
1408 	if (!test_bit(vsi_id, fm_list->vsi_list_info->vsi_map))
1409 		return ICE_ERR_DOES_NOT_EXIST;
1410 
1411 	lkup_type = fm_list->fltr_info.lkup_type;
1412 	vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
1413 
1414 	status = ice_update_vsi_list_rule(hw, &vsi_id, 1, vsi_list_id, true,
1415 					  ice_aqc_opc_update_sw_rules,
1416 					  lkup_type);
1417 	if (status)
1418 		return status;
1419 
1420 	fm_list->vsi_count--;
1421 	clear_bit(vsi_id, fm_list->vsi_list_info->vsi_map);
1422 
1423 	if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
1424 	    (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
1425 		struct ice_vsi_list_map_info *vsi_list_info =
1426 			fm_list->vsi_list_info;
1427 		u16 rem_vsi_id;
1428 
1429 		rem_vsi_id = find_first_bit(vsi_list_info->vsi_map,
1430 					    ICE_MAX_VSI);
1431 		if (rem_vsi_id == ICE_MAX_VSI)
1432 			return ICE_ERR_OUT_OF_RANGE;
1433 
1434 		status = ice_update_vsi_list_rule(hw, &rem_vsi_id, 1,
1435 						  vsi_list_id, true,
1436 						  ice_aqc_opc_update_sw_rules,
1437 						  lkup_type);
1438 		if (status)
1439 			return status;
1440 
1441 		/* Remove the VSI list since it is no longer used */
1442 		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
1443 		if (status)
1444 			return status;
1445 
1446 		/* Change the list entry action from VSI_LIST to VSI */
1447 		fm_list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1448 		fm_list->fltr_info.fwd_id.vsi_id = rem_vsi_id;
1449 
1450 		list_del(&vsi_list_info->list_entry);
1451 		devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
1452 		fm_list->vsi_list_info = NULL;
1453 	}
1454 
1455 	return status;
1456 }
1457 
1458 /**
1459  * ice_remove_rule_internal - Remove a filter rule of a given type
1460  * @hw: pointer to the hardware structure
1461  * @recp_id: recipe id for which the rule needs to removed
1462  * @f_entry: rule entry containing filter information
1463  */
1464 static enum ice_status
1465 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
1466 			 struct ice_fltr_list_entry *f_entry)
1467 {
1468 	struct ice_switch_info *sw = hw->switch_info;
1469 	struct ice_fltr_mgmt_list_entry *list_elem;
1470 	struct mutex *rule_lock; /* Lock to protect filter rule list */
1471 	enum ice_status status = 0;
1472 	bool remove_rule = false;
1473 	u16 vsi_id;
1474 
1475 	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1476 	mutex_lock(rule_lock);
1477 	list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
1478 	if (!list_elem) {
1479 		status = ICE_ERR_DOES_NOT_EXIST;
1480 		goto exit;
1481 	}
1482 
1483 	if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
1484 		remove_rule = true;
1485 	} else {
1486 		vsi_id = f_entry->fltr_info.fwd_id.vsi_id;
1487 		status = ice_rem_update_vsi_list(hw, vsi_id, list_elem);
1488 		if (status)
1489 			goto exit;
1490 		/* if vsi count goes to zero after updating the vsi list */
1491 		if (list_elem->vsi_count == 0)
1492 			remove_rule = true;
1493 	}
1494 
1495 	if (remove_rule) {
1496 		/* Remove the lookup rule */
1497 		struct ice_aqc_sw_rules_elem *s_rule;
1498 
1499 		s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1500 				      ICE_SW_RULE_RX_TX_NO_HDR_SIZE,
1501 				      GFP_KERNEL);
1502 		if (!s_rule) {
1503 			status = ICE_ERR_NO_MEMORY;
1504 			goto exit;
1505 		}
1506 
1507 		ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
1508 				 ice_aqc_opc_remove_sw_rules);
1509 
1510 		status = ice_aq_sw_rules(hw, s_rule,
1511 					 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
1512 					 ice_aqc_opc_remove_sw_rules, NULL);
1513 		if (status)
1514 			goto exit;
1515 
1516 		/* Remove a book keeping from the list */
1517 		devm_kfree(ice_hw_to_dev(hw), s_rule);
1518 
1519 		list_del(&list_elem->list_entry);
1520 		devm_kfree(ice_hw_to_dev(hw), list_elem);
1521 	}
1522 exit:
1523 	mutex_unlock(rule_lock);
1524 	return status;
1525 }
1526 
1527 /**
1528  * ice_add_mac - Add a MAC address based filter rule
1529  * @hw: pointer to the hardware structure
1530  * @m_list: list of MAC addresses and forwarding information
1531  *
1532  * IMPORTANT: When the ucast_shared flag is set to false and m_list has
1533  * multiple unicast addresses, the function assumes that all the
1534  * addresses are unique in a given add_mac call. It doesn't
1535  * check for duplicates in this case, removing duplicates from a given
1536  * list should be taken care of in the caller of this function.
1537  */
1538 enum ice_status
1539 ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
1540 {
1541 	struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
1542 	struct ice_fltr_list_entry *m_list_itr;
1543 	struct list_head *rule_head;
1544 	u16 elem_sent, total_elem_left;
1545 	struct ice_switch_info *sw;
1546 	struct mutex *rule_lock; /* Lock to protect filter rule list */
1547 	enum ice_status status = 0;
1548 	u16 num_unicast = 0;
1549 	u16 s_rule_size;
1550 
1551 	if (!m_list || !hw)
1552 		return ICE_ERR_PARAM;
1553 
1554 	s_rule = NULL;
1555 	sw = hw->switch_info;
1556 	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
1557 	list_for_each_entry(m_list_itr, m_list, list_entry) {
1558 		u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
1559 
1560 		m_list_itr->fltr_info.flag = ICE_FLTR_TX;
1561 		if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
1562 		    is_zero_ether_addr(add))
1563 			return ICE_ERR_PARAM;
1564 		if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
1565 			/* Don't overwrite the unicast address */
1566 			mutex_lock(rule_lock);
1567 			if (ice_find_rule_entry(hw, ICE_SW_LKUP_MAC,
1568 						&m_list_itr->fltr_info)) {
1569 				mutex_unlock(rule_lock);
1570 				return ICE_ERR_ALREADY_EXISTS;
1571 			}
1572 			mutex_unlock(rule_lock);
1573 			num_unicast++;
1574 		} else if (is_multicast_ether_addr(add) ||
1575 			   (is_unicast_ether_addr(add) && hw->ucast_shared)) {
1576 			m_list_itr->status =
1577 				ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
1578 						      m_list_itr);
1579 			if (m_list_itr->status)
1580 				return m_list_itr->status;
1581 		}
1582 	}
1583 
1584 	mutex_lock(rule_lock);
1585 	/* Exit if no suitable entries were found for adding bulk switch rule */
1586 	if (!num_unicast) {
1587 		status = 0;
1588 		goto ice_add_mac_exit;
1589 	}
1590 
1591 	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
1592 
1593 	/* Allocate switch rule buffer for the bulk update for unicast */
1594 	s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
1595 	s_rule = devm_kcalloc(ice_hw_to_dev(hw), num_unicast, s_rule_size,
1596 			      GFP_KERNEL);
1597 	if (!s_rule) {
1598 		status = ICE_ERR_NO_MEMORY;
1599 		goto ice_add_mac_exit;
1600 	}
1601 
1602 	r_iter = s_rule;
1603 	list_for_each_entry(m_list_itr, m_list, list_entry) {
1604 		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
1605 		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
1606 
1607 		if (is_unicast_ether_addr(mac_addr)) {
1608 			ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
1609 					 ice_aqc_opc_add_sw_rules);
1610 			r_iter = (struct ice_aqc_sw_rules_elem *)
1611 				((u8 *)r_iter + s_rule_size);
1612 		}
1613 	}
1614 
1615 	/* Call AQ bulk switch rule update for all unicast addresses */
1616 	r_iter = s_rule;
1617 	/* Call AQ switch rule in AQ_MAX chunk */
1618 	for (total_elem_left = num_unicast; total_elem_left > 0;
1619 	     total_elem_left -= elem_sent) {
1620 		struct ice_aqc_sw_rules_elem *entry = r_iter;
1621 
1622 		elem_sent = min(total_elem_left,
1623 				(u16)(ICE_AQ_MAX_BUF_LEN / s_rule_size));
1624 		status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
1625 					 elem_sent, ice_aqc_opc_add_sw_rules,
1626 					 NULL);
1627 		if (status)
1628 			goto ice_add_mac_exit;
1629 		r_iter = (struct ice_aqc_sw_rules_elem *)
1630 			((u8 *)r_iter + (elem_sent * s_rule_size));
1631 	}
1632 
1633 	/* Fill up rule id based on the value returned from FW */
1634 	r_iter = s_rule;
1635 	list_for_each_entry(m_list_itr, m_list, list_entry) {
1636 		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
1637 		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
1638 		struct ice_fltr_mgmt_list_entry *fm_entry;
1639 
1640 		if (is_unicast_ether_addr(mac_addr)) {
1641 			f_info->fltr_rule_id =
1642 				le16_to_cpu(r_iter->pdata.lkup_tx_rx.index);
1643 			f_info->fltr_act = ICE_FWD_TO_VSI;
1644 			/* Create an entry to track this MAC address */
1645 			fm_entry = devm_kzalloc(ice_hw_to_dev(hw),
1646 						sizeof(*fm_entry), GFP_KERNEL);
1647 			if (!fm_entry) {
1648 				status = ICE_ERR_NO_MEMORY;
1649 				goto ice_add_mac_exit;
1650 			}
1651 			fm_entry->fltr_info = *f_info;
1652 			fm_entry->vsi_count = 1;
1653 			/* The book keeping entries will get removed when
1654 			 * base driver calls remove filter AQ command
1655 			 */
1656 
1657 			list_add(&fm_entry->list_entry, rule_head);
1658 			r_iter = (struct ice_aqc_sw_rules_elem *)
1659 				((u8 *)r_iter + s_rule_size);
1660 		}
1661 	}
1662 
1663 ice_add_mac_exit:
1664 	mutex_unlock(rule_lock);
1665 	if (s_rule)
1666 		devm_kfree(ice_hw_to_dev(hw), s_rule);
1667 	return status;
1668 }
1669 
1670 /**
1671  * ice_add_vlan_internal - Add one VLAN based filter rule
1672  * @hw: pointer to the hardware structure
1673  * @f_entry: filter entry containing one VLAN information
1674  */
1675 static enum ice_status
1676 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
1677 {
1678 	struct ice_switch_info *sw = hw->switch_info;
1679 	struct ice_fltr_info *new_fltr, *cur_fltr;
1680 	struct ice_fltr_mgmt_list_entry *v_list_itr;
1681 	struct mutex *rule_lock; /* Lock to protect filter rule list */
1682 	enum ice_status status = 0;
1683 
1684 	new_fltr = &f_entry->fltr_info;
1685 	/* VLAN id should only be 12 bits */
1686 	if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
1687 		return ICE_ERR_PARAM;
1688 
1689 	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
1690 	mutex_lock(rule_lock);
1691 	v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
1692 	if (!v_list_itr) {
1693 		u16 vsi_id = ICE_VSI_INVAL_ID;
1694 		u16 vsi_list_id = 0;
1695 
1696 		if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
1697 			enum ice_sw_lkup_type lkup_type = new_fltr->lkup_type;
1698 
1699 			/* All VLAN pruning rules use a VSI list.
1700 			 * Convert the action to forwarding to a VSI list.
1701 			 */
1702 			vsi_id = new_fltr->fwd_id.vsi_id;
1703 			status = ice_create_vsi_list_rule(hw, &vsi_id, 1,
1704 							  &vsi_list_id,
1705 							  lkup_type);
1706 			if (status)
1707 				goto exit;
1708 			new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1709 			new_fltr->fwd_id.vsi_list_id = vsi_list_id;
1710 		}
1711 
1712 		status = ice_create_pkt_fwd_rule(hw, f_entry);
1713 		if (!status && vsi_id != ICE_VSI_INVAL_ID) {
1714 			v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
1715 							 new_fltr);
1716 			if (!v_list_itr) {
1717 				status = ICE_ERR_DOES_NOT_EXIST;
1718 				goto exit;
1719 			}
1720 			v_list_itr->vsi_list_info =
1721 				ice_create_vsi_list_map(hw, &vsi_id, 1,
1722 							vsi_list_id);
1723 		}
1724 
1725 		goto exit;
1726 	}
1727 
1728 	cur_fltr = &v_list_itr->fltr_info;
1729 	status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, new_fltr);
1730 
1731 exit:
1732 	mutex_unlock(rule_lock);
1733 	return status;
1734 }
1735 
1736 /**
1737  * ice_add_vlan - Add VLAN based filter rule
1738  * @hw: pointer to the hardware structure
1739  * @v_list: list of VLAN entries and forwarding information
1740  */
1741 enum ice_status
1742 ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
1743 {
1744 	struct ice_fltr_list_entry *v_list_itr;
1745 
1746 	if (!v_list || !hw)
1747 		return ICE_ERR_PARAM;
1748 
1749 	list_for_each_entry(v_list_itr, v_list, list_entry) {
1750 		if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
1751 			return ICE_ERR_PARAM;
1752 		v_list_itr->fltr_info.flag = ICE_FLTR_TX;
1753 		v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
1754 		if (v_list_itr->status)
1755 			return v_list_itr->status;
1756 	}
1757 	return 0;
1758 }
1759 
1760 /**
1761  * ice_rem_sw_rule_info
1762  * @hw: pointer to the hardware structure
1763  * @rule_head: pointer to the switch list structure that we want to delete
1764  */
1765 static void
1766 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
1767 {
1768 	if (!list_empty(rule_head)) {
1769 		struct ice_fltr_mgmt_list_entry *entry;
1770 		struct ice_fltr_mgmt_list_entry *tmp;
1771 
1772 		list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
1773 			list_del(&entry->list_entry);
1774 			devm_kfree(ice_hw_to_dev(hw), entry);
1775 		}
1776 	}
1777 }
1778 
1779 /**
1780  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
1781  * @hw: pointer to the hardware structure
1782  * @vsi_id: number of VSI to set as default
1783  * @set: true to add the above mentioned switch rule, false to remove it
1784  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
1785  *
1786  * add filter rule to set/unset given VSI as default VSI for the switch
1787  * (represented by swid)
1788  */
1789 enum ice_status
1790 ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction)
1791 {
1792 	struct ice_aqc_sw_rules_elem *s_rule;
1793 	struct ice_fltr_info f_info;
1794 	enum ice_adminq_opc opcode;
1795 	enum ice_status status;
1796 	u16 s_rule_size;
1797 
1798 	s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
1799 			    ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
1800 	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
1801 	if (!s_rule)
1802 		return ICE_ERR_NO_MEMORY;
1803 
1804 	memset(&f_info, 0, sizeof(f_info));
1805 
1806 	f_info.lkup_type = ICE_SW_LKUP_DFLT;
1807 	f_info.flag = direction;
1808 	f_info.fltr_act = ICE_FWD_TO_VSI;
1809 	f_info.fwd_id.vsi_id = vsi_id;
1810 
1811 	if (f_info.flag & ICE_FLTR_RX) {
1812 		f_info.src = hw->port_info->lport;
1813 		if (!set)
1814 			f_info.fltr_rule_id =
1815 				hw->port_info->dflt_rx_vsi_rule_id;
1816 	} else if (f_info.flag & ICE_FLTR_TX) {
1817 		f_info.src = vsi_id;
1818 		if (!set)
1819 			f_info.fltr_rule_id =
1820 				hw->port_info->dflt_tx_vsi_rule_id;
1821 	}
1822 
1823 	if (set)
1824 		opcode = ice_aqc_opc_add_sw_rules;
1825 	else
1826 		opcode = ice_aqc_opc_remove_sw_rules;
1827 
1828 	ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
1829 
1830 	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
1831 	if (status || !(f_info.flag & ICE_FLTR_TX_RX))
1832 		goto out;
1833 	if (set) {
1834 		u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1835 
1836 		if (f_info.flag & ICE_FLTR_TX) {
1837 			hw->port_info->dflt_tx_vsi_num = vsi_id;
1838 			hw->port_info->dflt_tx_vsi_rule_id = index;
1839 		} else if (f_info.flag & ICE_FLTR_RX) {
1840 			hw->port_info->dflt_rx_vsi_num = vsi_id;
1841 			hw->port_info->dflt_rx_vsi_rule_id = index;
1842 		}
1843 	} else {
1844 		if (f_info.flag & ICE_FLTR_TX) {
1845 			hw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
1846 			hw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
1847 		} else if (f_info.flag & ICE_FLTR_RX) {
1848 			hw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
1849 			hw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
1850 		}
1851 	}
1852 
1853 out:
1854 	devm_kfree(ice_hw_to_dev(hw), s_rule);
1855 	return status;
1856 }
1857 
1858 /**
1859  * ice_remove_mac - remove a MAC address based filter rule
1860  * @hw: pointer to the hardware structure
1861  * @m_list: list of MAC addresses and forwarding information
1862  *
1863  * This function removes either a MAC filter rule or a specific VSI from a
1864  * VSI list for a multicast MAC address.
1865  *
1866  * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
1867  * ice_add_mac. Caller should be aware that this call will only work if all
1868  * the entries passed into m_list were added previously. It will not attempt to
1869  * do a partial remove of entries that were found.
1870  */
1871 enum ice_status
1872 ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
1873 {
1874 	struct ice_fltr_list_entry *list_itr;
1875 
1876 	if (!m_list)
1877 		return ICE_ERR_PARAM;
1878 
1879 	list_for_each_entry(list_itr, m_list, list_entry) {
1880 		enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
1881 
1882 		if (l_type != ICE_SW_LKUP_MAC)
1883 			return ICE_ERR_PARAM;
1884 		list_itr->status = ice_remove_rule_internal(hw,
1885 							    ICE_SW_LKUP_MAC,
1886 							    list_itr);
1887 		if (list_itr->status)
1888 			return list_itr->status;
1889 	}
1890 	return 0;
1891 }
1892 
1893 /**
1894  * ice_remove_vlan - Remove VLAN based filter rule
1895  * @hw: pointer to the hardware structure
1896  * @v_list: list of VLAN entries and forwarding information
1897  */
1898 enum ice_status
1899 ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
1900 {
1901 	struct ice_fltr_list_entry *v_list_itr;
1902 
1903 	if (!v_list || !hw)
1904 		return ICE_ERR_PARAM;
1905 
1906 	list_for_each_entry(v_list_itr, v_list, list_entry) {
1907 		enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
1908 
1909 		if (l_type != ICE_SW_LKUP_VLAN)
1910 			return ICE_ERR_PARAM;
1911 		v_list_itr->status = ice_remove_rule_internal(hw,
1912 							      ICE_SW_LKUP_VLAN,
1913 							      v_list_itr);
1914 		if (v_list_itr->status)
1915 			return v_list_itr->status;
1916 	}
1917 	return 0;
1918 }
1919 
1920 /**
1921  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
1922  * @fm_entry: filter entry to inspect
1923  * @vsi_id: ID of VSI to compare with filter info
1924  */
1925 static bool
1926 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_id)
1927 {
1928 	return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
1929 		 fm_entry->fltr_info.fwd_id.vsi_id == vsi_id) ||
1930 		(fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
1931 		 (test_bit(vsi_id, fm_entry->vsi_list_info->vsi_map))));
1932 }
1933 
1934 /**
1935  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
1936  * @hw: pointer to the hardware structure
1937  * @vsi_id: ID of VSI to remove filters from
1938  * @vsi_list_head: pointer to the list to add entry to
1939  * @fi: pointer to fltr_info of filter entry to copy & add
1940  *
1941  * Helper function, used when creating a list of filters to remove from
1942  * a specific VSI. The entry added to vsi_list_head is a COPY of the
1943  * original filter entry, with the exception of fltr_info.fltr_act and
1944  * fltr_info.fwd_id fields. These are set such that later logic can
1945  * extract which VSI to remove the fltr from, and pass on that information.
1946  */
1947 static enum ice_status
1948 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1949 			       struct list_head *vsi_list_head,
1950 			       struct ice_fltr_info *fi)
1951 {
1952 	struct ice_fltr_list_entry *tmp;
1953 
1954 	/* this memory is freed up in the caller function
1955 	 * once filters for this VSI are removed
1956 	 */
1957 	tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
1958 	if (!tmp)
1959 		return ICE_ERR_NO_MEMORY;
1960 
1961 	tmp->fltr_info = *fi;
1962 
1963 	/* Overwrite these fields to indicate which VSI to remove filter from,
1964 	 * so find and remove logic can extract the information from the
1965 	 * list entries. Note that original entries will still have proper
1966 	 * values.
1967 	 */
1968 	tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1969 	tmp->fltr_info.fwd_id.vsi_id = vsi_id;
1970 
1971 	list_add(&tmp->list_entry, vsi_list_head);
1972 
1973 	return 0;
1974 }
1975 
1976 /**
1977  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
1978  * @hw: pointer to the hardware structure
1979  * @vsi_id: ID of VSI to remove filters from
1980  * @lkup_list_head: pointer to the list that has certain lookup type filters
1981  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_id
1982  *
1983  * Locates all filters in lkup_list_head that are used by the given VSI,
1984  * and adds COPIES of those entries to vsi_list_head (intended to be used
1985  * to remove the listed filters).
1986  * Note that this means all entries in vsi_list_head must be explicitly
1987  * deallocated by the caller when done with list.
1988  */
1989 static enum ice_status
1990 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1991 			 struct list_head *lkup_list_head,
1992 			 struct list_head *vsi_list_head)
1993 {
1994 	struct ice_fltr_mgmt_list_entry *fm_entry;
1995 	enum ice_status status = 0;
1996 
1997 	/* check to make sure VSI id is valid and within boundary */
1998 	if (vsi_id >= ICE_MAX_VSI)
1999 		return ICE_ERR_PARAM;
2000 
2001 	list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
2002 		struct ice_fltr_info *fi;
2003 
2004 		fi = &fm_entry->fltr_info;
2005 		if (!ice_vsi_uses_fltr(fm_entry, vsi_id))
2006 			continue;
2007 
2008 		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_id,
2009 							vsi_list_head, fi);
2010 		if (status)
2011 			return status;
2012 	}
2013 	return status;
2014 }
2015 
2016 /**
2017  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
2018  * @hw: pointer to the hardware structure
2019  * @vsi_id: ID of VSI to remove filters from
2020  * @lkup: switch rule filter lookup type
2021  */
2022 static void
2023 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_id,
2024 			 enum ice_sw_lkup_type lkup)
2025 {
2026 	struct ice_switch_info *sw = hw->switch_info;
2027 	struct ice_fltr_list_entry *fm_entry;
2028 	struct list_head remove_list_head;
2029 	struct list_head *rule_head;
2030 	struct ice_fltr_list_entry *tmp;
2031 	struct mutex *rule_lock;	/* Lock to protect filter rule list */
2032 	enum ice_status status;
2033 
2034 	INIT_LIST_HEAD(&remove_list_head);
2035 	rule_lock = &sw->recp_list[lkup].filt_rule_lock;
2036 	rule_head = &sw->recp_list[lkup].filt_rules;
2037 	mutex_lock(rule_lock);
2038 	status = ice_add_to_vsi_fltr_list(hw, vsi_id, rule_head,
2039 					  &remove_list_head);
2040 	mutex_unlock(rule_lock);
2041 	if (status)
2042 		return;
2043 
2044 	switch (lkup) {
2045 	case ICE_SW_LKUP_MAC:
2046 		ice_remove_mac(hw, &remove_list_head);
2047 		break;
2048 	case ICE_SW_LKUP_VLAN:
2049 		ice_remove_vlan(hw, &remove_list_head);
2050 		break;
2051 	case ICE_SW_LKUP_MAC_VLAN:
2052 	case ICE_SW_LKUP_ETHERTYPE:
2053 	case ICE_SW_LKUP_ETHERTYPE_MAC:
2054 	case ICE_SW_LKUP_PROMISC:
2055 	case ICE_SW_LKUP_DFLT:
2056 	case ICE_SW_LKUP_PROMISC_VLAN:
2057 	case ICE_SW_LKUP_LAST:
2058 	default:
2059 		ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
2060 		break;
2061 	}
2062 
2063 	list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
2064 		list_del(&fm_entry->list_entry);
2065 		devm_kfree(ice_hw_to_dev(hw), fm_entry);
2066 	}
2067 }
2068 
2069 /**
2070  * ice_remove_vsi_fltr - Remove all filters for a VSI
2071  * @hw: pointer to the hardware structure
2072  * @vsi_id: ID of VSI to remove filters from
2073  */
2074 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id)
2075 {
2076 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_MAC);
2077 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_MAC_VLAN);
2078 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_PROMISC);
2079 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_VLAN);
2080 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_DFLT);
2081 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_ETHERTYPE);
2082 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_ETHERTYPE_MAC);
2083 	ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_PROMISC_VLAN);
2084 }
2085 
2086 /**
2087  * ice_replay_fltr - Replay all the filters stored by a specific list head
2088  * @hw: pointer to the hardware structure
2089  * @list_head: list for which filters needs to be replayed
2090  * @recp_id: Recipe id for which rules need to be replayed
2091  */
2092 static enum ice_status
2093 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct list_head *list_head)
2094 {
2095 	struct ice_fltr_mgmt_list_entry *itr;
2096 	struct list_head l_head;
2097 	enum ice_status status = 0;
2098 
2099 	if (list_empty(list_head))
2100 		return status;
2101 
2102 	/* Move entries from the given list_head to a temporary l_head so that
2103 	 * they can be replayed. Otherwise when trying to re-add the same
2104 	 * filter, the function will return already exists
2105 	 */
2106 	list_replace_init(list_head, &l_head);
2107 
2108 	/* Mark the given list_head empty by reinitializing it so filters
2109 	 * could be added again by *handler
2110 	 */
2111 	list_for_each_entry(itr, &l_head, list_entry) {
2112 		struct ice_fltr_list_entry f_entry;
2113 
2114 		f_entry.fltr_info = itr->fltr_info;
2115 		if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
2116 			status = ice_add_rule_internal(hw, recp_id, &f_entry);
2117 			if (status)
2118 				goto end;
2119 			continue;
2120 		}
2121 
2122 		/* Add a filter per vsi separately */
2123 		while (1) {
2124 			u16 vsi;
2125 
2126 			vsi = find_first_bit(itr->vsi_list_info->vsi_map,
2127 					     ICE_MAX_VSI);
2128 			if (vsi == ICE_MAX_VSI)
2129 				break;
2130 
2131 			clear_bit(vsi, itr->vsi_list_info->vsi_map);
2132 			f_entry.fltr_info.fwd_id.vsi_id = vsi;
2133 			f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
2134 			if (recp_id == ICE_SW_LKUP_VLAN)
2135 				status = ice_add_vlan_internal(hw, &f_entry);
2136 			else
2137 				status = ice_add_rule_internal(hw, recp_id,
2138 							       &f_entry);
2139 			if (status)
2140 				goto end;
2141 		}
2142 	}
2143 end:
2144 	/* Clear the filter management list */
2145 	ice_rem_sw_rule_info(hw, &l_head);
2146 	return status;
2147 }
2148 
2149 /**
2150  * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
2151  * @hw: pointer to the hardware structure
2152  *
2153  * NOTE: This function does not clean up partially added filters on error.
2154  * It is up to caller of the function to issue a reset or fail early.
2155  */
2156 enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
2157 {
2158 	struct ice_switch_info *sw = hw->switch_info;
2159 	enum ice_status status = 0;
2160 	u8 i;
2161 
2162 	for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
2163 		struct list_head *head = &sw->recp_list[i].filt_rules;
2164 
2165 		status = ice_replay_fltr(hw, i, head);
2166 		if (status)
2167 			return status;
2168 	}
2169 	return status;
2170 }
2171