Merge tag 'powerpc-5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / drivers / net / ethernet / intel / ice / ice_switch.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Intel Corporation. */
3
4 #include "ice_lib.h"
5 #include "ice_switch.h"
6
7 #define ICE_ETH_DA_OFFSET               0
8 #define ICE_ETH_ETHTYPE_OFFSET          12
9 #define ICE_ETH_VLAN_TCI_OFFSET         14
10 #define ICE_MAX_VLAN_ID                 0xFFF
11
12 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
13  * struct to configure any switch filter rules.
14  * {DA (6 bytes), SA(6 bytes),
15  * Ether type (2 bytes for header without VLAN tag) OR
16  * VLAN tag (4 bytes for header with VLAN tag) }
17  *
18  * Word on Hardcoded values
19  * byte 0 = 0x2: to identify it as locally administered DA MAC
20  * byte 6 = 0x2: to identify it as locally administered SA MAC
21  * byte 12 = 0x81 & byte 13 = 0x00:
22  *      In case of VLAN filter first two bytes defines ether type (0x8100)
23  *      and remaining two bytes are placeholder for programming a given VLAN ID
24  *      In case of Ether type filter it is treated as header without VLAN tag
25  *      and byte 12 and 13 is used to program a given Ether type instead
26  */
27 #define DUMMY_ETH_HDR_LEN               16
28 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
29                                                         0x2, 0, 0, 0, 0, 0,
30                                                         0x81, 0, 0, 0};
31
32 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \
33         (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr) + \
34          (DUMMY_ETH_HDR_LEN * \
35           sizeof(((struct ice_sw_rule_lkup_rx_tx *)0)->hdr[0])))
36 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \
37         (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr))
38 #define ICE_SW_RULE_LG_ACT_SIZE(n) \
39         (offsetof(struct ice_aqc_sw_rules_elem, pdata.lg_act.act) + \
40          ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act[0])))
41 #define ICE_SW_RULE_VSI_LIST_SIZE(n) \
42         (offsetof(struct ice_aqc_sw_rules_elem, pdata.vsi_list.vsi) + \
43          ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi[0])))
44
45 /**
46  * ice_init_def_sw_recp - initialize the recipe book keeping tables
47  * @hw: pointer to the HW struct
48  *
49  * Allocate memory for the entire recipe table and initialize the structures/
50  * entries corresponding to basic recipes.
51  */
52 enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
53 {
54         struct ice_sw_recipe *recps;
55         u8 i;
56
57         recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
58                              sizeof(*recps), GFP_KERNEL);
59         if (!recps)
60                 return ICE_ERR_NO_MEMORY;
61
62         for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
63                 recps[i].root_rid = i;
64                 INIT_LIST_HEAD(&recps[i].filt_rules);
65                 INIT_LIST_HEAD(&recps[i].filt_replay_rules);
66                 mutex_init(&recps[i].filt_rule_lock);
67         }
68
69         hw->switch_info->recp_list = recps;
70
71         return 0;
72 }
73
74 /**
75  * ice_aq_get_sw_cfg - get switch configuration
76  * @hw: pointer to the hardware structure
77  * @buf: pointer to the result buffer
78  * @buf_size: length of the buffer available for response
79  * @req_desc: pointer to requested descriptor
80  * @num_elems: pointer to number of elements
81  * @cd: pointer to command details structure or NULL
82  *
83  * Get switch configuration (0x0200) to be placed in buf.
84  * This admin command returns information such as initial VSI/port number
85  * and switch ID it belongs to.
86  *
87  * NOTE: *req_desc is both an input/output parameter.
88  * The caller of this function first calls this function with *request_desc set
89  * to 0. If the response from f/w has *req_desc set to 0, all the switch
90  * configuration information has been returned; if non-zero (meaning not all
91  * the information was returned), the caller should call this function again
92  * with *req_desc set to the previous value returned by f/w to get the
93  * next block of switch configuration information.
94  *
95  * *num_elems is output only parameter. This reflects the number of elements
96  * in response buffer. The caller of this function to use *num_elems while
97  * parsing the response buffer.
98  */
99 static enum ice_status
100 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
101                   u16 buf_size, u16 *req_desc, u16 *num_elems,
102                   struct ice_sq_cd *cd)
103 {
104         struct ice_aqc_get_sw_cfg *cmd;
105         struct ice_aq_desc desc;
106         enum ice_status status;
107
108         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
109         cmd = &desc.params.get_sw_conf;
110         cmd->element = cpu_to_le16(*req_desc);
111
112         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
113         if (!status) {
114                 *req_desc = le16_to_cpu(cmd->element);
115                 *num_elems = le16_to_cpu(cmd->num_elems);
116         }
117
118         return status;
119 }
120
121 /**
122  * ice_aq_add_vsi
123  * @hw: pointer to the HW struct
124  * @vsi_ctx: pointer to a VSI context struct
125  * @cd: pointer to command details structure or NULL
126  *
127  * Add a VSI context to the hardware (0x0210)
128  */
129 static enum ice_status
130 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
131                struct ice_sq_cd *cd)
132 {
133         struct ice_aqc_add_update_free_vsi_resp *res;
134         struct ice_aqc_add_get_update_free_vsi *cmd;
135         struct ice_aq_desc desc;
136         enum ice_status status;
137
138         cmd = &desc.params.vsi_cmd;
139         res = &desc.params.add_update_free_vsi_res;
140
141         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
142
143         if (!vsi_ctx->alloc_from_pool)
144                 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
145                                            ICE_AQ_VSI_IS_VALID);
146         cmd->vf_id = vsi_ctx->vf_num;
147
148         cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
149
150         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
151
152         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
153                                  sizeof(vsi_ctx->info), cd);
154
155         if (!status) {
156                 vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
157                 vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
158                 vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
159         }
160
161         return status;
162 }
163
164 /**
165  * ice_aq_free_vsi
166  * @hw: pointer to the HW struct
167  * @vsi_ctx: pointer to a VSI context struct
168  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
169  * @cd: pointer to command details structure or NULL
170  *
171  * Free VSI context info from hardware (0x0213)
172  */
173 static enum ice_status
174 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
175                 bool keep_vsi_alloc, struct ice_sq_cd *cd)
176 {
177         struct ice_aqc_add_update_free_vsi_resp *resp;
178         struct ice_aqc_add_get_update_free_vsi *cmd;
179         struct ice_aq_desc desc;
180         enum ice_status status;
181
182         cmd = &desc.params.vsi_cmd;
183         resp = &desc.params.add_update_free_vsi_res;
184
185         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
186
187         cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
188         if (keep_vsi_alloc)
189                 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
190
191         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
192         if (!status) {
193                 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
194                 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
195         }
196
197         return status;
198 }
199
200 /**
201  * ice_aq_update_vsi
202  * @hw: pointer to the HW struct
203  * @vsi_ctx: pointer to a VSI context struct
204  * @cd: pointer to command details structure or NULL
205  *
206  * Update VSI context in the hardware (0x0211)
207  */
208 static enum ice_status
209 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
210                   struct ice_sq_cd *cd)
211 {
212         struct ice_aqc_add_update_free_vsi_resp *resp;
213         struct ice_aqc_add_get_update_free_vsi *cmd;
214         struct ice_aq_desc desc;
215         enum ice_status status;
216
217         cmd = &desc.params.vsi_cmd;
218         resp = &desc.params.add_update_free_vsi_res;
219
220         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
221
222         cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
223
224         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
225
226         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
227                                  sizeof(vsi_ctx->info), cd);
228
229         if (!status) {
230                 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
231                 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
232         }
233
234         return status;
235 }
236
237 /**
238  * ice_is_vsi_valid - check whether the VSI is valid or not
239  * @hw: pointer to the HW struct
240  * @vsi_handle: VSI handle
241  *
242  * check whether the VSI is valid or not
243  */
244 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
245 {
246         return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
247 }
248
249 /**
250  * ice_get_hw_vsi_num - return the HW VSI number
251  * @hw: pointer to the HW struct
252  * @vsi_handle: VSI handle
253  *
254  * return the HW VSI number
255  * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
256  */
257 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
258 {
259         return hw->vsi_ctx[vsi_handle]->vsi_num;
260 }
261
262 /**
263  * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
264  * @hw: pointer to the HW struct
265  * @vsi_handle: VSI handle
266  *
267  * return the VSI context entry for a given VSI handle
268  */
269 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
270 {
271         return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
272 }
273
274 /**
275  * ice_save_vsi_ctx - save the VSI context for a given VSI handle
276  * @hw: pointer to the HW struct
277  * @vsi_handle: VSI handle
278  * @vsi: VSI context pointer
279  *
280  * save the VSI context entry for a given VSI handle
281  */
282 static void
283 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
284 {
285         hw->vsi_ctx[vsi_handle] = vsi;
286 }
287
288 /**
289  * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
290  * @hw: pointer to the HW struct
291  * @vsi_handle: VSI handle
292  */
293 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
294 {
295         struct ice_vsi_ctx *vsi;
296         u8 i;
297
298         vsi = ice_get_vsi_ctx(hw, vsi_handle);
299         if (!vsi)
300                 return;
301         ice_for_each_traffic_class(i) {
302                 if (vsi->lan_q_ctx[i]) {
303                         devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
304                         vsi->lan_q_ctx[i] = NULL;
305                 }
306                 if (vsi->rdma_q_ctx[i]) {
307                         devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
308                         vsi->rdma_q_ctx[i] = NULL;
309                 }
310         }
311 }
312
313 /**
314  * ice_clear_vsi_ctx - clear the VSI context entry
315  * @hw: pointer to the HW struct
316  * @vsi_handle: VSI handle
317  *
318  * clear the VSI context entry
319  */
320 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
321 {
322         struct ice_vsi_ctx *vsi;
323
324         vsi = ice_get_vsi_ctx(hw, vsi_handle);
325         if (vsi) {
326                 ice_clear_vsi_q_ctx(hw, vsi_handle);
327                 devm_kfree(ice_hw_to_dev(hw), vsi);
328                 hw->vsi_ctx[vsi_handle] = NULL;
329         }
330 }
331
332 /**
333  * ice_clear_all_vsi_ctx - clear all the VSI context entries
334  * @hw: pointer to the HW struct
335  */
336 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
337 {
338         u16 i;
339
340         for (i = 0; i < ICE_MAX_VSI; i++)
341                 ice_clear_vsi_ctx(hw, i);
342 }
343
344 /**
345  * ice_add_vsi - add VSI context to the hardware and VSI handle list
346  * @hw: pointer to the HW struct
347  * @vsi_handle: unique VSI handle provided by drivers
348  * @vsi_ctx: pointer to a VSI context struct
349  * @cd: pointer to command details structure or NULL
350  *
351  * Add a VSI context to the hardware also add it into the VSI handle list.
352  * If this function gets called after reset for existing VSIs then update
353  * with the new HW VSI number in the corresponding VSI handle list entry.
354  */
355 enum ice_status
356 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
357             struct ice_sq_cd *cd)
358 {
359         struct ice_vsi_ctx *tmp_vsi_ctx;
360         enum ice_status status;
361
362         if (vsi_handle >= ICE_MAX_VSI)
363                 return ICE_ERR_PARAM;
364         status = ice_aq_add_vsi(hw, vsi_ctx, cd);
365         if (status)
366                 return status;
367         tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
368         if (!tmp_vsi_ctx) {
369                 /* Create a new VSI context */
370                 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
371                                            sizeof(*tmp_vsi_ctx), GFP_KERNEL);
372                 if (!tmp_vsi_ctx) {
373                         ice_aq_free_vsi(hw, vsi_ctx, false, cd);
374                         return ICE_ERR_NO_MEMORY;
375                 }
376                 *tmp_vsi_ctx = *vsi_ctx;
377                 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
378         } else {
379                 /* update with new HW VSI num */
380                 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
381         }
382
383         return 0;
384 }
385
386 /**
387  * ice_free_vsi- free VSI context from hardware and VSI handle list
388  * @hw: pointer to the HW struct
389  * @vsi_handle: unique VSI handle
390  * @vsi_ctx: pointer to a VSI context struct
391  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
392  * @cd: pointer to command details structure or NULL
393  *
394  * Free VSI context info from hardware as well as from VSI handle list
395  */
396 enum ice_status
397 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
398              bool keep_vsi_alloc, struct ice_sq_cd *cd)
399 {
400         enum ice_status status;
401
402         if (!ice_is_vsi_valid(hw, vsi_handle))
403                 return ICE_ERR_PARAM;
404         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
405         status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
406         if (!status)
407                 ice_clear_vsi_ctx(hw, vsi_handle);
408         return status;
409 }
410
411 /**
412  * ice_update_vsi
413  * @hw: pointer to the HW struct
414  * @vsi_handle: unique VSI handle
415  * @vsi_ctx: pointer to a VSI context struct
416  * @cd: pointer to command details structure or NULL
417  *
418  * Update VSI context in the hardware
419  */
420 enum ice_status
421 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
422                struct ice_sq_cd *cd)
423 {
424         if (!ice_is_vsi_valid(hw, vsi_handle))
425                 return ICE_ERR_PARAM;
426         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
427         return ice_aq_update_vsi(hw, vsi_ctx, cd);
428 }
429
430 /**
431  * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI
432  * @hw: pointer to HW struct
433  * @vsi_handle: VSI SW index
434  * @enable: boolean for enable/disable
435  */
436 int
437 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
438 {
439         struct ice_vsi_ctx *ctx;
440
441         ctx = ice_get_vsi_ctx(hw, vsi_handle);
442         if (!ctx)
443                 return -EIO;
444
445         if (enable)
446                 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
447         else
448                 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
449
450         return ice_status_to_errno(ice_update_vsi(hw, vsi_handle, ctx, NULL));
451 }
452
453 /**
454  * ice_aq_alloc_free_vsi_list
455  * @hw: pointer to the HW struct
456  * @vsi_list_id: VSI list ID returned or used for lookup
457  * @lkup_type: switch rule filter lookup type
458  * @opc: switch rules population command type - pass in the command opcode
459  *
460  * allocates or free a VSI list resource
461  */
462 static enum ice_status
463 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
464                            enum ice_sw_lkup_type lkup_type,
465                            enum ice_adminq_opc opc)
466 {
467         struct ice_aqc_alloc_free_res_elem *sw_buf;
468         struct ice_aqc_res_elem *vsi_ele;
469         enum ice_status status;
470         u16 buf_len;
471
472         buf_len = struct_size(sw_buf, elem, 1);
473         sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
474         if (!sw_buf)
475                 return ICE_ERR_NO_MEMORY;
476         sw_buf->num_elems = cpu_to_le16(1);
477
478         if (lkup_type == ICE_SW_LKUP_MAC ||
479             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
480             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
481             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
482             lkup_type == ICE_SW_LKUP_PROMISC ||
483             lkup_type == ICE_SW_LKUP_PROMISC_VLAN) {
484                 sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
485         } else if (lkup_type == ICE_SW_LKUP_VLAN) {
486                 sw_buf->res_type =
487                         cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
488         } else {
489                 status = ICE_ERR_PARAM;
490                 goto ice_aq_alloc_free_vsi_list_exit;
491         }
492
493         if (opc == ice_aqc_opc_free_res)
494                 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
495
496         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
497         if (status)
498                 goto ice_aq_alloc_free_vsi_list_exit;
499
500         if (opc == ice_aqc_opc_alloc_res) {
501                 vsi_ele = &sw_buf->elem[0];
502                 *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
503         }
504
505 ice_aq_alloc_free_vsi_list_exit:
506         devm_kfree(ice_hw_to_dev(hw), sw_buf);
507         return status;
508 }
509
510 /**
511  * ice_aq_sw_rules - add/update/remove switch rules
512  * @hw: pointer to the HW struct
513  * @rule_list: pointer to switch rule population list
514  * @rule_list_sz: total size of the rule list in bytes
515  * @num_rules: number of switch rules in the rule_list
516  * @opc: switch rules population command type - pass in the command opcode
517  * @cd: pointer to command details structure or NULL
518  *
519  * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
520  */
521 static enum ice_status
522 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
523                 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
524 {
525         struct ice_aq_desc desc;
526         enum ice_status status;
527
528         if (opc != ice_aqc_opc_add_sw_rules &&
529             opc != ice_aqc_opc_update_sw_rules &&
530             opc != ice_aqc_opc_remove_sw_rules)
531                 return ICE_ERR_PARAM;
532
533         ice_fill_dflt_direct_cmd_desc(&desc, opc);
534
535         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
536         desc.params.sw_rules.num_rules_fltr_entry_index =
537                 cpu_to_le16(num_rules);
538         status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
539         if (opc != ice_aqc_opc_add_sw_rules &&
540             hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
541                 status = ICE_ERR_DOES_NOT_EXIST;
542
543         return status;
544 }
545
546 /* ice_init_port_info - Initialize port_info with switch configuration data
547  * @pi: pointer to port_info
548  * @vsi_port_num: VSI number or port number
549  * @type: Type of switch element (port or VSI)
550  * @swid: switch ID of the switch the element is attached to
551  * @pf_vf_num: PF or VF number
552  * @is_vf: true if the element is a VF, false otherwise
553  */
554 static void
555 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
556                    u16 swid, u16 pf_vf_num, bool is_vf)
557 {
558         switch (type) {
559         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
560                 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
561                 pi->sw_id = swid;
562                 pi->pf_vf_num = pf_vf_num;
563                 pi->is_vf = is_vf;
564                 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
565                 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
566                 break;
567         default:
568                 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
569                 break;
570         }
571 }
572
573 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
574  * @hw: pointer to the hardware structure
575  */
576 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
577 {
578         struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
579         enum ice_status status;
580         u16 req_desc = 0;
581         u16 num_elems;
582         u16 i;
583
584         rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN,
585                             GFP_KERNEL);
586
587         if (!rbuf)
588                 return ICE_ERR_NO_MEMORY;
589
590         /* Multiple calls to ice_aq_get_sw_cfg may be required
591          * to get all the switch configuration information. The need
592          * for additional calls is indicated by ice_aq_get_sw_cfg
593          * writing a non-zero value in req_desc
594          */
595         do {
596                 struct ice_aqc_get_sw_cfg_resp_elem *ele;
597
598                 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
599                                            &req_desc, &num_elems, NULL);
600
601                 if (status)
602                         break;
603
604                 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
605                         u16 pf_vf_num, swid, vsi_port_num;
606                         bool is_vf = false;
607                         u8 res_type;
608
609                         vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
610                                 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
611
612                         pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
613                                 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
614
615                         swid = le16_to_cpu(ele->swid);
616
617                         if (le16_to_cpu(ele->pf_vf_num) &
618                             ICE_AQC_GET_SW_CONF_RESP_IS_VF)
619                                 is_vf = true;
620
621                         res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
622                                         ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
623
624                         if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
625                                 /* FW VSI is not needed. Just continue. */
626                                 continue;
627                         }
628
629                         ice_init_port_info(hw->port_info, vsi_port_num,
630                                            res_type, swid, pf_vf_num, is_vf);
631                 }
632         } while (req_desc && !status);
633
634         devm_kfree(ice_hw_to_dev(hw), rbuf);
635         return status;
636 }
637
638 /**
639  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
640  * @hw: pointer to the hardware structure
641  * @fi: filter info structure to fill/update
642  *
643  * This helper function populates the lb_en and lan_en elements of the provided
644  * ice_fltr_info struct using the switch's type and characteristics of the
645  * switch rule being configured.
646  */
647 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
648 {
649         fi->lb_en = false;
650         fi->lan_en = false;
651         if ((fi->flag & ICE_FLTR_TX) &&
652             (fi->fltr_act == ICE_FWD_TO_VSI ||
653              fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
654              fi->fltr_act == ICE_FWD_TO_Q ||
655              fi->fltr_act == ICE_FWD_TO_QGRP)) {
656                 /* Setting LB for prune actions will result in replicated
657                  * packets to the internal switch that will be dropped.
658                  */
659                 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
660                         fi->lb_en = true;
661
662                 /* Set lan_en to TRUE if
663                  * 1. The switch is a VEB AND
664                  * 2
665                  * 2.1 The lookup is a directional lookup like ethertype,
666                  * promiscuous, ethertype-MAC, promiscuous-VLAN
667                  * and default-port OR
668                  * 2.2 The lookup is VLAN, OR
669                  * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
670                  * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
671                  *
672                  * OR
673                  *
674                  * The switch is a VEPA.
675                  *
676                  * In all other cases, the LAN enable has to be set to false.
677                  */
678                 if (hw->evb_veb) {
679                         if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
680                             fi->lkup_type == ICE_SW_LKUP_PROMISC ||
681                             fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
682                             fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
683                             fi->lkup_type == ICE_SW_LKUP_DFLT ||
684                             fi->lkup_type == ICE_SW_LKUP_VLAN ||
685                             (fi->lkup_type == ICE_SW_LKUP_MAC &&
686                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
687                             (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
688                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
689                                 fi->lan_en = true;
690                 } else {
691                         fi->lan_en = true;
692                 }
693         }
694 }
695
696 /**
697  * ice_fill_sw_rule - Helper function to fill switch rule structure
698  * @hw: pointer to the hardware structure
699  * @f_info: entry containing packet forwarding information
700  * @s_rule: switch rule structure to be filled in based on mac_entry
701  * @opc: switch rules population command type - pass in the command opcode
702  */
703 static void
704 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
705                  struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
706 {
707         u16 vlan_id = ICE_MAX_VLAN_ID + 1;
708         void *daddr = NULL;
709         u16 eth_hdr_sz;
710         u8 *eth_hdr;
711         u32 act = 0;
712         __be16 *off;
713         u8 q_rgn;
714
715         if (opc == ice_aqc_opc_remove_sw_rules) {
716                 s_rule->pdata.lkup_tx_rx.act = 0;
717                 s_rule->pdata.lkup_tx_rx.index =
718                         cpu_to_le16(f_info->fltr_rule_id);
719                 s_rule->pdata.lkup_tx_rx.hdr_len = 0;
720                 return;
721         }
722
723         eth_hdr_sz = sizeof(dummy_eth_header);
724         eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
725
726         /* initialize the ether header with a dummy header */
727         memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
728         ice_fill_sw_info(hw, f_info);
729
730         switch (f_info->fltr_act) {
731         case ICE_FWD_TO_VSI:
732                 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
733                         ICE_SINGLE_ACT_VSI_ID_M;
734                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
735                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
736                                 ICE_SINGLE_ACT_VALID_BIT;
737                 break;
738         case ICE_FWD_TO_VSI_LIST:
739                 act |= ICE_SINGLE_ACT_VSI_LIST;
740                 act |= (f_info->fwd_id.vsi_list_id <<
741                         ICE_SINGLE_ACT_VSI_LIST_ID_S) &
742                         ICE_SINGLE_ACT_VSI_LIST_ID_M;
743                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
744                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
745                                 ICE_SINGLE_ACT_VALID_BIT;
746                 break;
747         case ICE_FWD_TO_Q:
748                 act |= ICE_SINGLE_ACT_TO_Q;
749                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
750                         ICE_SINGLE_ACT_Q_INDEX_M;
751                 break;
752         case ICE_DROP_PACKET:
753                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
754                         ICE_SINGLE_ACT_VALID_BIT;
755                 break;
756         case ICE_FWD_TO_QGRP:
757                 q_rgn = f_info->qgrp_size > 0 ?
758                         (u8)ilog2(f_info->qgrp_size) : 0;
759                 act |= ICE_SINGLE_ACT_TO_Q;
760                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
761                         ICE_SINGLE_ACT_Q_INDEX_M;
762                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
763                         ICE_SINGLE_ACT_Q_REGION_M;
764                 break;
765         default:
766                 return;
767         }
768
769         if (f_info->lb_en)
770                 act |= ICE_SINGLE_ACT_LB_ENABLE;
771         if (f_info->lan_en)
772                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
773
774         switch (f_info->lkup_type) {
775         case ICE_SW_LKUP_MAC:
776                 daddr = f_info->l_data.mac.mac_addr;
777                 break;
778         case ICE_SW_LKUP_VLAN:
779                 vlan_id = f_info->l_data.vlan.vlan_id;
780                 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
781                     f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
782                         act |= ICE_SINGLE_ACT_PRUNE;
783                         act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
784                 }
785                 break;
786         case ICE_SW_LKUP_ETHERTYPE_MAC:
787                 daddr = f_info->l_data.ethertype_mac.mac_addr;
788                 fallthrough;
789         case ICE_SW_LKUP_ETHERTYPE:
790                 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
791                 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
792                 break;
793         case ICE_SW_LKUP_MAC_VLAN:
794                 daddr = f_info->l_data.mac_vlan.mac_addr;
795                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
796                 break;
797         case ICE_SW_LKUP_PROMISC_VLAN:
798                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
799                 fallthrough;
800         case ICE_SW_LKUP_PROMISC:
801                 daddr = f_info->l_data.mac_vlan.mac_addr;
802                 break;
803         default:
804                 break;
805         }
806
807         s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
808                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
809                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
810
811         /* Recipe set depending on lookup type */
812         s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(f_info->lkup_type);
813         s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(f_info->src);
814         s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act);
815
816         if (daddr)
817                 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
818
819         if (!(vlan_id > ICE_MAX_VLAN_ID)) {
820                 off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
821                 *off = cpu_to_be16(vlan_id);
822         }
823
824         /* Create the switch rule with the final dummy Ethernet header */
825         if (opc != ice_aqc_opc_update_sw_rules)
826                 s_rule->pdata.lkup_tx_rx.hdr_len = cpu_to_le16(eth_hdr_sz);
827 }
828
829 /**
830  * ice_add_marker_act
831  * @hw: pointer to the hardware structure
832  * @m_ent: the management entry for which sw marker needs to be added
833  * @sw_marker: sw marker to tag the Rx descriptor with
834  * @l_id: large action resource ID
835  *
836  * Create a large action to hold software marker and update the switch rule
837  * entry pointed by m_ent with newly created large action
838  */
839 static enum ice_status
840 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
841                    u16 sw_marker, u16 l_id)
842 {
843         struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
844         /* For software marker we need 3 large actions
845          * 1. FWD action: FWD TO VSI or VSI LIST
846          * 2. GENERIC VALUE action to hold the profile ID
847          * 3. GENERIC VALUE action to hold the software marker ID
848          */
849         const u16 num_lg_acts = 3;
850         enum ice_status status;
851         u16 lg_act_size;
852         u16 rules_size;
853         u32 act;
854         u16 id;
855
856         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
857                 return ICE_ERR_PARAM;
858
859         /* Create two back-to-back switch rules and submit them to the HW using
860          * one memory buffer:
861          *    1. Large Action
862          *    2. Look up Tx Rx
863          */
864         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
865         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
866         lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
867         if (!lg_act)
868                 return ICE_ERR_NO_MEMORY;
869
870         rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
871
872         /* Fill in the first switch rule i.e. large action */
873         lg_act->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
874         lg_act->pdata.lg_act.index = cpu_to_le16(l_id);
875         lg_act->pdata.lg_act.size = cpu_to_le16(num_lg_acts);
876
877         /* First action VSI forwarding or VSI list forwarding depending on how
878          * many VSIs
879          */
880         id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
881                 m_ent->fltr_info.fwd_id.hw_vsi_id;
882
883         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
884         act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
885         if (m_ent->vsi_count > 1)
886                 act |= ICE_LG_ACT_VSI_LIST;
887         lg_act->pdata.lg_act.act[0] = cpu_to_le32(act);
888
889         /* Second action descriptor type */
890         act = ICE_LG_ACT_GENERIC;
891
892         act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
893         lg_act->pdata.lg_act.act[1] = cpu_to_le32(act);
894
895         act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
896                ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
897
898         /* Third action Marker value */
899         act |= ICE_LG_ACT_GENERIC;
900         act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
901                 ICE_LG_ACT_GENERIC_VALUE_M;
902
903         lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);
904
905         /* call the fill switch rule to fill the lookup Tx Rx structure */
906         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
907                          ice_aqc_opc_update_sw_rules);
908
909         /* Update the action to point to the large action ID */
910         rx_tx->pdata.lkup_tx_rx.act =
911                 cpu_to_le32(ICE_SINGLE_ACT_PTR |
912                             ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
913                              ICE_SINGLE_ACT_PTR_VAL_M));
914
915         /* Use the filter rule ID of the previously created rule with single
916          * act. Once the update happens, hardware will treat this as large
917          * action
918          */
919         rx_tx->pdata.lkup_tx_rx.index =
920                 cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
921
922         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
923                                  ice_aqc_opc_update_sw_rules, NULL);
924         if (!status) {
925                 m_ent->lg_act_idx = l_id;
926                 m_ent->sw_marker_id = sw_marker;
927         }
928
929         devm_kfree(ice_hw_to_dev(hw), lg_act);
930         return status;
931 }
932
933 /**
934  * ice_create_vsi_list_map
935  * @hw: pointer to the hardware structure
936  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
937  * @num_vsi: number of VSI handles in the array
938  * @vsi_list_id: VSI list ID generated as part of allocate resource
939  *
940  * Helper function to create a new entry of VSI list ID to VSI mapping
941  * using the given VSI list ID
942  */
943 static struct ice_vsi_list_map_info *
944 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
945                         u16 vsi_list_id)
946 {
947         struct ice_switch_info *sw = hw->switch_info;
948         struct ice_vsi_list_map_info *v_map;
949         int i;
950
951         v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
952         if (!v_map)
953                 return NULL;
954
955         v_map->vsi_list_id = vsi_list_id;
956         v_map->ref_cnt = 1;
957         for (i = 0; i < num_vsi; i++)
958                 set_bit(vsi_handle_arr[i], v_map->vsi_map);
959
960         list_add(&v_map->list_entry, &sw->vsi_list_map_head);
961         return v_map;
962 }
963
964 /**
965  * ice_update_vsi_list_rule
966  * @hw: pointer to the hardware structure
967  * @vsi_handle_arr: array of VSI handles to form a VSI list
968  * @num_vsi: number of VSI handles in the array
969  * @vsi_list_id: VSI list ID generated as part of allocate resource
970  * @remove: Boolean value to indicate if this is a remove action
971  * @opc: switch rules population command type - pass in the command opcode
972  * @lkup_type: lookup type of the filter
973  *
974  * Call AQ command to add a new switch rule or update existing switch rule
975  * using the given VSI list ID
976  */
977 static enum ice_status
978 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
979                          u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
980                          enum ice_sw_lkup_type lkup_type)
981 {
982         struct ice_aqc_sw_rules_elem *s_rule;
983         enum ice_status status;
984         u16 s_rule_size;
985         u16 rule_type;
986         int i;
987
988         if (!num_vsi)
989                 return ICE_ERR_PARAM;
990
991         if (lkup_type == ICE_SW_LKUP_MAC ||
992             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
993             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
994             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
995             lkup_type == ICE_SW_LKUP_PROMISC ||
996             lkup_type == ICE_SW_LKUP_PROMISC_VLAN)
997                 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
998                         ICE_AQC_SW_RULES_T_VSI_LIST_SET;
999         else if (lkup_type == ICE_SW_LKUP_VLAN)
1000                 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
1001                         ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
1002         else
1003                 return ICE_ERR_PARAM;
1004
1005         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
1006         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
1007         if (!s_rule)
1008                 return ICE_ERR_NO_MEMORY;
1009         for (i = 0; i < num_vsi; i++) {
1010                 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
1011                         status = ICE_ERR_PARAM;
1012                         goto exit;
1013                 }
1014                 /* AQ call requires hw_vsi_id(s) */
1015                 s_rule->pdata.vsi_list.vsi[i] =
1016                         cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
1017         }
1018
1019         s_rule->type = cpu_to_le16(rule_type);
1020         s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi);
1021         s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);
1022
1023         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
1024
1025 exit:
1026         devm_kfree(ice_hw_to_dev(hw), s_rule);
1027         return status;
1028 }
1029
1030 /**
1031  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
1032  * @hw: pointer to the HW struct
1033  * @vsi_handle_arr: array of VSI handles to form a VSI list
1034  * @num_vsi: number of VSI handles in the array
1035  * @vsi_list_id: stores the ID of the VSI list to be created
1036  * @lkup_type: switch rule filter's lookup type
1037  */
1038 static enum ice_status
1039 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
1040                          u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
1041 {
1042         enum ice_status status;
1043
1044         status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
1045                                             ice_aqc_opc_alloc_res);
1046         if (status)
1047                 return status;
1048
1049         /* Update the newly created VSI list to include the specified VSIs */
1050         return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
1051                                         *vsi_list_id, false,
1052                                         ice_aqc_opc_add_sw_rules, lkup_type);
1053 }
1054
1055 /**
1056  * ice_create_pkt_fwd_rule
1057  * @hw: pointer to the hardware structure
1058  * @f_entry: entry containing packet forwarding information
1059  *
1060  * Create switch rule with given filter information and add an entry
1061  * to the corresponding filter management list to track this switch rule
1062  * and VSI mapping
1063  */
1064 static enum ice_status
1065 ice_create_pkt_fwd_rule(struct ice_hw *hw,
1066                         struct ice_fltr_list_entry *f_entry)
1067 {
1068         struct ice_fltr_mgmt_list_entry *fm_entry;
1069         struct ice_aqc_sw_rules_elem *s_rule;
1070         enum ice_sw_lkup_type l_type;
1071         struct ice_sw_recipe *recp;
1072         enum ice_status status;
1073
1074         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1075                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1076         if (!s_rule)
1077                 return ICE_ERR_NO_MEMORY;
1078         fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
1079                                 GFP_KERNEL);
1080         if (!fm_entry) {
1081                 status = ICE_ERR_NO_MEMORY;
1082                 goto ice_create_pkt_fwd_rule_exit;
1083         }
1084
1085         fm_entry->fltr_info = f_entry->fltr_info;
1086
1087         /* Initialize all the fields for the management entry */
1088         fm_entry->vsi_count = 1;
1089         fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
1090         fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
1091         fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
1092
1093         ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
1094                          ice_aqc_opc_add_sw_rules);
1095
1096         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
1097                                  ice_aqc_opc_add_sw_rules, NULL);
1098         if (status) {
1099                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
1100                 goto ice_create_pkt_fwd_rule_exit;
1101         }
1102
1103         f_entry->fltr_info.fltr_rule_id =
1104                 le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1105         fm_entry->fltr_info.fltr_rule_id =
1106                 le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1107
1108         /* The book keeping entries will get removed when base driver
1109          * calls remove filter AQ command
1110          */
1111         l_type = fm_entry->fltr_info.lkup_type;
1112         recp = &hw->switch_info->recp_list[l_type];
1113         list_add(&fm_entry->list_entry, &recp->filt_rules);
1114
1115 ice_create_pkt_fwd_rule_exit:
1116         devm_kfree(ice_hw_to_dev(hw), s_rule);
1117         return status;
1118 }
1119
1120 /**
1121  * ice_update_pkt_fwd_rule
1122  * @hw: pointer to the hardware structure
1123  * @f_info: filter information for switch rule
1124  *
1125  * Call AQ command to update a previously created switch rule with a
1126  * VSI list ID
1127  */
1128 static enum ice_status
1129 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
1130 {
1131         struct ice_aqc_sw_rules_elem *s_rule;
1132         enum ice_status status;
1133
1134         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1135                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1136         if (!s_rule)
1137                 return ICE_ERR_NO_MEMORY;
1138
1139         ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
1140
1141         s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(f_info->fltr_rule_id);
1142
1143         /* Update switch rule with new rule set to forward VSI list */
1144         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
1145                                  ice_aqc_opc_update_sw_rules, NULL);
1146
1147         devm_kfree(ice_hw_to_dev(hw), s_rule);
1148         return status;
1149 }
1150
1151 /**
1152  * ice_update_sw_rule_bridge_mode
1153  * @hw: pointer to the HW struct
1154  *
1155  * Updates unicast switch filter rules based on VEB/VEPA mode
1156  */
1157 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
1158 {
1159         struct ice_switch_info *sw = hw->switch_info;
1160         struct ice_fltr_mgmt_list_entry *fm_entry;
1161         enum ice_status status = 0;
1162         struct list_head *rule_head;
1163         struct mutex *rule_lock; /* Lock to protect filter rule list */
1164
1165         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
1166         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
1167
1168         mutex_lock(rule_lock);
1169         list_for_each_entry(fm_entry, rule_head, list_entry) {
1170                 struct ice_fltr_info *fi = &fm_entry->fltr_info;
1171                 u8 *addr = fi->l_data.mac.mac_addr;
1172
1173                 /* Update unicast Tx rules to reflect the selected
1174                  * VEB/VEPA mode
1175                  */
1176                 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
1177                     (fi->fltr_act == ICE_FWD_TO_VSI ||
1178                      fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
1179                      fi->fltr_act == ICE_FWD_TO_Q ||
1180                      fi->fltr_act == ICE_FWD_TO_QGRP)) {
1181                         status = ice_update_pkt_fwd_rule(hw, fi);
1182                         if (status)
1183                                 break;
1184                 }
1185         }
1186
1187         mutex_unlock(rule_lock);
1188
1189         return status;
1190 }
1191
1192 /**
1193  * ice_add_update_vsi_list
1194  * @hw: pointer to the hardware structure
1195  * @m_entry: pointer to current filter management list entry
1196  * @cur_fltr: filter information from the book keeping entry
1197  * @new_fltr: filter information with the new VSI to be added
1198  *
1199  * Call AQ command to add or update previously created VSI list with new VSI.
1200  *
1201  * Helper function to do book keeping associated with adding filter information
1202  * The algorithm to do the book keeping is described below :
1203  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
1204  *      if only one VSI has been added till now
1205  *              Allocate a new VSI list and add two VSIs
1206  *              to this list using switch rule command
1207  *              Update the previously created switch rule with the
1208  *              newly created VSI list ID
1209  *      if a VSI list was previously created
1210  *              Add the new VSI to the previously created VSI list set
1211  *              using the update switch rule command
1212  */
1213 static enum ice_status
1214 ice_add_update_vsi_list(struct ice_hw *hw,
1215                         struct ice_fltr_mgmt_list_entry *m_entry,
1216                         struct ice_fltr_info *cur_fltr,
1217                         struct ice_fltr_info *new_fltr)
1218 {
1219         enum ice_status status = 0;
1220         u16 vsi_list_id = 0;
1221
1222         if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
1223              cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
1224                 return ICE_ERR_NOT_IMPL;
1225
1226         if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
1227              new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
1228             (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
1229              cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
1230                 return ICE_ERR_NOT_IMPL;
1231
1232         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
1233                 /* Only one entry existed in the mapping and it was not already
1234                  * a part of a VSI list. So, create a VSI list with the old and
1235                  * new VSIs.
1236                  */
1237                 struct ice_fltr_info tmp_fltr;
1238                 u16 vsi_handle_arr[2];
1239
1240                 /* A rule already exists with the new VSI being added */
1241                 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
1242                         return ICE_ERR_ALREADY_EXISTS;
1243
1244                 vsi_handle_arr[0] = cur_fltr->vsi_handle;
1245                 vsi_handle_arr[1] = new_fltr->vsi_handle;
1246                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
1247                                                   &vsi_list_id,
1248                                                   new_fltr->lkup_type);
1249                 if (status)
1250                         return status;
1251
1252                 tmp_fltr = *new_fltr;
1253                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
1254                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
1255                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
1256                 /* Update the previous switch rule of "MAC forward to VSI" to
1257                  * "MAC fwd to VSI list"
1258                  */
1259                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
1260                 if (status)
1261                         return status;
1262
1263                 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
1264                 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1265                 m_entry->vsi_list_info =
1266                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
1267                                                 vsi_list_id);
1268
1269                 if (!m_entry->vsi_list_info)
1270                         return ICE_ERR_NO_MEMORY;
1271
1272                 /* If this entry was large action then the large action needs
1273                  * to be updated to point to FWD to VSI list
1274                  */
1275                 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
1276                         status =
1277                             ice_add_marker_act(hw, m_entry,
1278                                                m_entry->sw_marker_id,
1279                                                m_entry->lg_act_idx);
1280         } else {
1281                 u16 vsi_handle = new_fltr->vsi_handle;
1282                 enum ice_adminq_opc opcode;
1283
1284                 if (!m_entry->vsi_list_info)
1285                         return ICE_ERR_CFG;
1286
1287                 /* A rule already exists with the new VSI being added */
1288                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
1289                         return 0;
1290
1291                 /* Update the previously created VSI list set with
1292                  * the new VSI ID passed in
1293                  */
1294                 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
1295                 opcode = ice_aqc_opc_update_sw_rules;
1296
1297                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
1298                                                   vsi_list_id, false, opcode,
1299                                                   new_fltr->lkup_type);
1300                 /* update VSI list mapping info with new VSI ID */
1301                 if (!status)
1302                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
1303         }
1304         if (!status)
1305                 m_entry->vsi_count++;
1306         return status;
1307 }
1308
1309 /**
1310  * ice_find_rule_entry - Search a rule entry
1311  * @hw: pointer to the hardware structure
1312  * @recp_id: lookup type for which the specified rule needs to be searched
1313  * @f_info: rule information
1314  *
1315  * Helper function to search for a given rule entry
1316  * Returns pointer to entry storing the rule if found
1317  */
1318 static struct ice_fltr_mgmt_list_entry *
1319 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
1320 {
1321         struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
1322         struct ice_switch_info *sw = hw->switch_info;
1323         struct list_head *list_head;
1324
1325         list_head = &sw->recp_list[recp_id].filt_rules;
1326         list_for_each_entry(list_itr, list_head, list_entry) {
1327                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
1328                             sizeof(f_info->l_data)) &&
1329                     f_info->flag == list_itr->fltr_info.flag) {
1330                         ret = list_itr;
1331                         break;
1332                 }
1333         }
1334         return ret;
1335 }
1336
1337 /**
1338  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
1339  * @hw: pointer to the hardware structure
1340  * @recp_id: lookup type for which VSI lists needs to be searched
1341  * @vsi_handle: VSI handle to be found in VSI list
1342  * @vsi_list_id: VSI list ID found containing vsi_handle
1343  *
1344  * Helper function to search a VSI list with single entry containing given VSI
1345  * handle element. This can be extended further to search VSI list with more
1346  * than 1 vsi_count. Returns pointer to VSI list entry if found.
1347  */
1348 static struct ice_vsi_list_map_info *
1349 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
1350                         u16 *vsi_list_id)
1351 {
1352         struct ice_vsi_list_map_info *map_info = NULL;
1353         struct ice_switch_info *sw = hw->switch_info;
1354         struct ice_fltr_mgmt_list_entry *list_itr;
1355         struct list_head *list_head;
1356
1357         list_head = &sw->recp_list[recp_id].filt_rules;
1358         list_for_each_entry(list_itr, list_head, list_entry) {
1359                 if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
1360                         map_info = list_itr->vsi_list_info;
1361                         if (test_bit(vsi_handle, map_info->vsi_map)) {
1362                                 *vsi_list_id = map_info->vsi_list_id;
1363                                 return map_info;
1364                         }
1365                 }
1366         }
1367         return NULL;
1368 }
1369
1370 /**
1371  * ice_add_rule_internal - add rule for a given lookup type
1372  * @hw: pointer to the hardware structure
1373  * @recp_id: lookup type (recipe ID) for which rule has to be added
1374  * @f_entry: structure containing MAC forwarding information
1375  *
1376  * Adds or updates the rule lists for a given recipe
1377  */
1378 static enum ice_status
1379 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
1380                       struct ice_fltr_list_entry *f_entry)
1381 {
1382         struct ice_switch_info *sw = hw->switch_info;
1383         struct ice_fltr_info *new_fltr, *cur_fltr;
1384         struct ice_fltr_mgmt_list_entry *m_entry;
1385         struct mutex *rule_lock; /* Lock to protect filter rule list */
1386         enum ice_status status = 0;
1387
1388         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1389                 return ICE_ERR_PARAM;
1390         f_entry->fltr_info.fwd_id.hw_vsi_id =
1391                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1392
1393         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1394
1395         mutex_lock(rule_lock);
1396         new_fltr = &f_entry->fltr_info;
1397         if (new_fltr->flag & ICE_FLTR_RX)
1398                 new_fltr->src = hw->port_info->lport;
1399         else if (new_fltr->flag & ICE_FLTR_TX)
1400                 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
1401
1402         m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
1403         if (!m_entry) {
1404                 mutex_unlock(rule_lock);
1405                 return ice_create_pkt_fwd_rule(hw, f_entry);
1406         }
1407
1408         cur_fltr = &m_entry->fltr_info;
1409         status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
1410         mutex_unlock(rule_lock);
1411
1412         return status;
1413 }
1414
1415 /**
1416  * ice_remove_vsi_list_rule
1417  * @hw: pointer to the hardware structure
1418  * @vsi_list_id: VSI list ID generated as part of allocate resource
1419  * @lkup_type: switch rule filter lookup type
1420  *
1421  * The VSI list should be emptied before this function is called to remove the
1422  * VSI list.
1423  */
1424 static enum ice_status
1425 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
1426                          enum ice_sw_lkup_type lkup_type)
1427 {
1428         struct ice_aqc_sw_rules_elem *s_rule;
1429         enum ice_status status;
1430         u16 s_rule_size;
1431
1432         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(0);
1433         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
1434         if (!s_rule)
1435                 return ICE_ERR_NO_MEMORY;
1436
1437         s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
1438         s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);
1439
1440         /* Free the vsi_list resource that we allocated. It is assumed that the
1441          * list is empty at this point.
1442          */
1443         status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
1444                                             ice_aqc_opc_free_res);
1445
1446         devm_kfree(ice_hw_to_dev(hw), s_rule);
1447         return status;
1448 }
1449
1450 /**
1451  * ice_rem_update_vsi_list
1452  * @hw: pointer to the hardware structure
1453  * @vsi_handle: VSI handle of the VSI to remove
1454  * @fm_list: filter management entry for which the VSI list management needs to
1455  *           be done
1456  */
1457 static enum ice_status
1458 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
1459                         struct ice_fltr_mgmt_list_entry *fm_list)
1460 {
1461         enum ice_sw_lkup_type lkup_type;
1462         enum ice_status status = 0;
1463         u16 vsi_list_id;
1464
1465         if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
1466             fm_list->vsi_count == 0)
1467                 return ICE_ERR_PARAM;
1468
1469         /* A rule with the VSI being removed does not exist */
1470         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
1471                 return ICE_ERR_DOES_NOT_EXIST;
1472
1473         lkup_type = fm_list->fltr_info.lkup_type;
1474         vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
1475         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
1476                                           ice_aqc_opc_update_sw_rules,
1477                                           lkup_type);
1478         if (status)
1479                 return status;
1480
1481         fm_list->vsi_count--;
1482         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
1483
1484         if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
1485                 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
1486                 struct ice_vsi_list_map_info *vsi_list_info =
1487                         fm_list->vsi_list_info;
1488                 u16 rem_vsi_handle;
1489
1490                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
1491                                                 ICE_MAX_VSI);
1492                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
1493                         return ICE_ERR_OUT_OF_RANGE;
1494
1495                 /* Make sure VSI list is empty before removing it below */
1496                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
1497                                                   vsi_list_id, true,
1498                                                   ice_aqc_opc_update_sw_rules,
1499                                                   lkup_type);
1500                 if (status)
1501                         return status;
1502
1503                 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
1504                 tmp_fltr_info.fwd_id.hw_vsi_id =
1505                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
1506                 tmp_fltr_info.vsi_handle = rem_vsi_handle;
1507                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
1508                 if (status) {
1509                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
1510                                   tmp_fltr_info.fwd_id.hw_vsi_id, status);
1511                         return status;
1512                 }
1513
1514                 fm_list->fltr_info = tmp_fltr_info;
1515         }
1516
1517         if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
1518             (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
1519                 struct ice_vsi_list_map_info *vsi_list_info =
1520                         fm_list->vsi_list_info;
1521
1522                 /* Remove the VSI list since it is no longer used */
1523                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
1524                 if (status) {
1525                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
1526                                   vsi_list_id, status);
1527                         return status;
1528                 }
1529
1530                 list_del(&vsi_list_info->list_entry);
1531                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
1532                 fm_list->vsi_list_info = NULL;
1533         }
1534
1535         return status;
1536 }
1537
1538 /**
1539  * ice_remove_rule_internal - Remove a filter rule of a given type
1540  * @hw: pointer to the hardware structure
1541  * @recp_id: recipe ID for which the rule needs to removed
1542  * @f_entry: rule entry containing filter information
1543  */
1544 static enum ice_status
1545 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
1546                          struct ice_fltr_list_entry *f_entry)
1547 {
1548         struct ice_switch_info *sw = hw->switch_info;
1549         struct ice_fltr_mgmt_list_entry *list_elem;
1550         struct mutex *rule_lock; /* Lock to protect filter rule list */
1551         enum ice_status status = 0;
1552         bool remove_rule = false;
1553         u16 vsi_handle;
1554
1555         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1556                 return ICE_ERR_PARAM;
1557         f_entry->fltr_info.fwd_id.hw_vsi_id =
1558                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1559
1560         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1561         mutex_lock(rule_lock);
1562         list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
1563         if (!list_elem) {
1564                 status = ICE_ERR_DOES_NOT_EXIST;
1565                 goto exit;
1566         }
1567
1568         if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
1569                 remove_rule = true;
1570         } else if (!list_elem->vsi_list_info) {
1571                 status = ICE_ERR_DOES_NOT_EXIST;
1572                 goto exit;
1573         } else if (list_elem->vsi_list_info->ref_cnt > 1) {
1574                 /* a ref_cnt > 1 indicates that the vsi_list is being
1575                  * shared by multiple rules. Decrement the ref_cnt and
1576                  * remove this rule, but do not modify the list, as it
1577                  * is in-use by other rules.
1578                  */
1579                 list_elem->vsi_list_info->ref_cnt--;
1580                 remove_rule = true;
1581         } else {
1582                 /* a ref_cnt of 1 indicates the vsi_list is only used
1583                  * by one rule. However, the original removal request is only
1584                  * for a single VSI. Update the vsi_list first, and only
1585                  * remove the rule if there are no further VSIs in this list.
1586                  */
1587                 vsi_handle = f_entry->fltr_info.vsi_handle;
1588                 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
1589                 if (status)
1590                         goto exit;
1591                 /* if VSI count goes to zero after updating the VSI list */
1592                 if (list_elem->vsi_count == 0)
1593                         remove_rule = true;
1594         }
1595
1596         if (remove_rule) {
1597                 /* Remove the lookup rule */
1598                 struct ice_aqc_sw_rules_elem *s_rule;
1599
1600                 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1601                                       ICE_SW_RULE_RX_TX_NO_HDR_SIZE,
1602                                       GFP_KERNEL);
1603                 if (!s_rule) {
1604                         status = ICE_ERR_NO_MEMORY;
1605                         goto exit;
1606                 }
1607
1608                 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
1609                                  ice_aqc_opc_remove_sw_rules);
1610
1611                 status = ice_aq_sw_rules(hw, s_rule,
1612                                          ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
1613                                          ice_aqc_opc_remove_sw_rules, NULL);
1614
1615                 /* Remove a book keeping from the list */
1616                 devm_kfree(ice_hw_to_dev(hw), s_rule);
1617
1618                 if (status)
1619                         goto exit;
1620
1621                 list_del(&list_elem->list_entry);
1622                 devm_kfree(ice_hw_to_dev(hw), list_elem);
1623         }
1624 exit:
1625         mutex_unlock(rule_lock);
1626         return status;
1627 }
1628
1629 /**
1630  * ice_add_mac - Add a MAC address based filter rule
1631  * @hw: pointer to the hardware structure
1632  * @m_list: list of MAC addresses and forwarding information
1633  *
1634  * IMPORTANT: When the ucast_shared flag is set to false and m_list has
1635  * multiple unicast addresses, the function assumes that all the
1636  * addresses are unique in a given add_mac call. It doesn't
1637  * check for duplicates in this case, removing duplicates from a given
1638  * list should be taken care of in the caller of this function.
1639  */
1640 enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
1641 {
1642         struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
1643         struct ice_fltr_list_entry *m_list_itr;
1644         struct list_head *rule_head;
1645         u16 total_elem_left, s_rule_size;
1646         struct ice_switch_info *sw;
1647         struct mutex *rule_lock; /* Lock to protect filter rule list */
1648         enum ice_status status = 0;
1649         u16 num_unicast = 0;
1650         u8 elem_sent;
1651
1652         if (!m_list || !hw)
1653                 return ICE_ERR_PARAM;
1654
1655         s_rule = NULL;
1656         sw = hw->switch_info;
1657         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
1658         list_for_each_entry(m_list_itr, m_list, list_entry) {
1659                 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
1660                 u16 vsi_handle;
1661                 u16 hw_vsi_id;
1662
1663                 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
1664                 vsi_handle = m_list_itr->fltr_info.vsi_handle;
1665                 if (!ice_is_vsi_valid(hw, vsi_handle))
1666                         return ICE_ERR_PARAM;
1667                 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
1668                 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
1669                 /* update the src in case it is VSI num */
1670                 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
1671                         return ICE_ERR_PARAM;
1672                 m_list_itr->fltr_info.src = hw_vsi_id;
1673                 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
1674                     is_zero_ether_addr(add))
1675                         return ICE_ERR_PARAM;
1676                 if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
1677                         /* Don't overwrite the unicast address */
1678                         mutex_lock(rule_lock);
1679                         if (ice_find_rule_entry(hw, ICE_SW_LKUP_MAC,
1680                                                 &m_list_itr->fltr_info)) {
1681                                 mutex_unlock(rule_lock);
1682                                 return ICE_ERR_ALREADY_EXISTS;
1683                         }
1684                         mutex_unlock(rule_lock);
1685                         num_unicast++;
1686                 } else if (is_multicast_ether_addr(add) ||
1687                            (is_unicast_ether_addr(add) && hw->ucast_shared)) {
1688                         m_list_itr->status =
1689                                 ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
1690                                                       m_list_itr);
1691                         if (m_list_itr->status)
1692                                 return m_list_itr->status;
1693                 }
1694         }
1695
1696         mutex_lock(rule_lock);
1697         /* Exit if no suitable entries were found for adding bulk switch rule */
1698         if (!num_unicast) {
1699                 status = 0;
1700                 goto ice_add_mac_exit;
1701         }
1702
1703         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
1704
1705         /* Allocate switch rule buffer for the bulk update for unicast */
1706         s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
1707         s_rule = devm_kcalloc(ice_hw_to_dev(hw), num_unicast, s_rule_size,
1708                               GFP_KERNEL);
1709         if (!s_rule) {
1710                 status = ICE_ERR_NO_MEMORY;
1711                 goto ice_add_mac_exit;
1712         }
1713
1714         r_iter = s_rule;
1715         list_for_each_entry(m_list_itr, m_list, list_entry) {
1716                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
1717                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
1718
1719                 if (is_unicast_ether_addr(mac_addr)) {
1720                         ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
1721                                          ice_aqc_opc_add_sw_rules);
1722                         r_iter = (struct ice_aqc_sw_rules_elem *)
1723                                 ((u8 *)r_iter + s_rule_size);
1724                 }
1725         }
1726
1727         /* Call AQ bulk switch rule update for all unicast addresses */
1728         r_iter = s_rule;
1729         /* Call AQ switch rule in AQ_MAX chunk */
1730         for (total_elem_left = num_unicast; total_elem_left > 0;
1731              total_elem_left -= elem_sent) {
1732                 struct ice_aqc_sw_rules_elem *entry = r_iter;
1733
1734                 elem_sent = min_t(u8, total_elem_left,
1735                                   (ICE_AQ_MAX_BUF_LEN / s_rule_size));
1736                 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
1737                                          elem_sent, ice_aqc_opc_add_sw_rules,
1738                                          NULL);
1739                 if (status)
1740                         goto ice_add_mac_exit;
1741                 r_iter = (struct ice_aqc_sw_rules_elem *)
1742                         ((u8 *)r_iter + (elem_sent * s_rule_size));
1743         }
1744
1745         /* Fill up rule ID based on the value returned from FW */
1746         r_iter = s_rule;
1747         list_for_each_entry(m_list_itr, m_list, list_entry) {
1748                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
1749                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
1750                 struct ice_fltr_mgmt_list_entry *fm_entry;
1751
1752                 if (is_unicast_ether_addr(mac_addr)) {
1753                         f_info->fltr_rule_id =
1754                                 le16_to_cpu(r_iter->pdata.lkup_tx_rx.index);
1755                         f_info->fltr_act = ICE_FWD_TO_VSI;
1756                         /* Create an entry to track this MAC address */
1757                         fm_entry = devm_kzalloc(ice_hw_to_dev(hw),
1758                                                 sizeof(*fm_entry), GFP_KERNEL);
1759                         if (!fm_entry) {
1760                                 status = ICE_ERR_NO_MEMORY;
1761                                 goto ice_add_mac_exit;
1762                         }
1763                         fm_entry->fltr_info = *f_info;
1764                         fm_entry->vsi_count = 1;
1765                         /* The book keeping entries will get removed when
1766                          * base driver calls remove filter AQ command
1767                          */
1768
1769                         list_add(&fm_entry->list_entry, rule_head);
1770                         r_iter = (struct ice_aqc_sw_rules_elem *)
1771                                 ((u8 *)r_iter + s_rule_size);
1772                 }
1773         }
1774
1775 ice_add_mac_exit:
1776         mutex_unlock(rule_lock);
1777         if (s_rule)
1778                 devm_kfree(ice_hw_to_dev(hw), s_rule);
1779         return status;
1780 }
1781
1782 /**
1783  * ice_add_vlan_internal - Add one VLAN based filter rule
1784  * @hw: pointer to the hardware structure
1785  * @f_entry: filter entry containing one VLAN information
1786  */
1787 static enum ice_status
1788 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
1789 {
1790         struct ice_switch_info *sw = hw->switch_info;
1791         struct ice_fltr_mgmt_list_entry *v_list_itr;
1792         struct ice_fltr_info *new_fltr, *cur_fltr;
1793         enum ice_sw_lkup_type lkup_type;
1794         u16 vsi_list_id = 0, vsi_handle;
1795         struct mutex *rule_lock; /* Lock to protect filter rule list */
1796         enum ice_status status = 0;
1797
1798         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1799                 return ICE_ERR_PARAM;
1800
1801         f_entry->fltr_info.fwd_id.hw_vsi_id =
1802                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1803         new_fltr = &f_entry->fltr_info;
1804
1805         /* VLAN ID should only be 12 bits */
1806         if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
1807                 return ICE_ERR_PARAM;
1808
1809         if (new_fltr->src_id != ICE_SRC_ID_VSI)
1810                 return ICE_ERR_PARAM;
1811
1812         new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
1813         lkup_type = new_fltr->lkup_type;
1814         vsi_handle = new_fltr->vsi_handle;
1815         rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
1816         mutex_lock(rule_lock);
1817         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
1818         if (!v_list_itr) {
1819                 struct ice_vsi_list_map_info *map_info = NULL;
1820
1821                 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
1822                         /* All VLAN pruning rules use a VSI list. Check if
1823                          * there is already a VSI list containing VSI that we
1824                          * want to add. If found, use the same vsi_list_id for
1825                          * this new VLAN rule or else create a new list.
1826                          */
1827                         map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
1828                                                            vsi_handle,
1829                                                            &vsi_list_id);
1830                         if (!map_info) {
1831                                 status = ice_create_vsi_list_rule(hw,
1832                                                                   &vsi_handle,
1833                                                                   1,
1834                                                                   &vsi_list_id,
1835                                                                   lkup_type);
1836                                 if (status)
1837                                         goto exit;
1838                         }
1839                         /* Convert the action to forwarding to a VSI list. */
1840                         new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1841                         new_fltr->fwd_id.vsi_list_id = vsi_list_id;
1842                 }
1843
1844                 status = ice_create_pkt_fwd_rule(hw, f_entry);
1845                 if (!status) {
1846                         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
1847                                                          new_fltr);
1848                         if (!v_list_itr) {
1849                                 status = ICE_ERR_DOES_NOT_EXIST;
1850                                 goto exit;
1851                         }
1852                         /* reuse VSI list for new rule and increment ref_cnt */
1853                         if (map_info) {
1854                                 v_list_itr->vsi_list_info = map_info;
1855                                 map_info->ref_cnt++;
1856                         } else {
1857                                 v_list_itr->vsi_list_info =
1858                                         ice_create_vsi_list_map(hw, &vsi_handle,
1859                                                                 1, vsi_list_id);
1860                         }
1861                 }
1862         } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
1863                 /* Update existing VSI list to add new VSI ID only if it used
1864                  * by one VLAN rule.
1865                  */
1866                 cur_fltr = &v_list_itr->fltr_info;
1867                 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
1868                                                  new_fltr);
1869         } else {
1870                 /* If VLAN rule exists and VSI list being used by this rule is
1871                  * referenced by more than 1 VLAN rule. Then create a new VSI
1872                  * list appending previous VSI with new VSI and update existing
1873                  * VLAN rule to point to new VSI list ID
1874                  */
1875                 struct ice_fltr_info tmp_fltr;
1876                 u16 vsi_handle_arr[2];
1877                 u16 cur_handle;
1878
1879                 /* Current implementation only supports reusing VSI list with
1880                  * one VSI count. We should never hit below condition
1881                  */
1882                 if (v_list_itr->vsi_count > 1 &&
1883                     v_list_itr->vsi_list_info->ref_cnt > 1) {
1884                         ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
1885                         status = ICE_ERR_CFG;
1886                         goto exit;
1887                 }
1888
1889                 cur_handle =
1890                         find_first_bit(v_list_itr->vsi_list_info->vsi_map,
1891                                        ICE_MAX_VSI);
1892
1893                 /* A rule already exists with the new VSI being added */
1894                 if (cur_handle == vsi_handle) {
1895                         status = ICE_ERR_ALREADY_EXISTS;
1896                         goto exit;
1897                 }
1898
1899                 vsi_handle_arr[0] = cur_handle;
1900                 vsi_handle_arr[1] = vsi_handle;
1901                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
1902                                                   &vsi_list_id, lkup_type);
1903                 if (status)
1904                         goto exit;
1905
1906                 tmp_fltr = v_list_itr->fltr_info;
1907                 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
1908                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
1909                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
1910                 /* Update the previous switch rule to a new VSI list which
1911                  * includes current VSI that is requested
1912                  */
1913                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
1914                 if (status)
1915                         goto exit;
1916
1917                 /* before overriding VSI list map info. decrement ref_cnt of
1918                  * previous VSI list
1919                  */
1920                 v_list_itr->vsi_list_info->ref_cnt--;
1921
1922                 /* now update to newly created list */
1923                 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
1924                 v_list_itr->vsi_list_info =
1925                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
1926                                                 vsi_list_id);
1927                 v_list_itr->vsi_count++;
1928         }
1929
1930 exit:
1931         mutex_unlock(rule_lock);
1932         return status;
1933 }
1934
1935 /**
1936  * ice_add_vlan - Add VLAN based filter rule
1937  * @hw: pointer to the hardware structure
1938  * @v_list: list of VLAN entries and forwarding information
1939  */
1940 enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
1941 {
1942         struct ice_fltr_list_entry *v_list_itr;
1943
1944         if (!v_list || !hw)
1945                 return ICE_ERR_PARAM;
1946
1947         list_for_each_entry(v_list_itr, v_list, list_entry) {
1948                 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
1949                         return ICE_ERR_PARAM;
1950                 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
1951                 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
1952                 if (v_list_itr->status)
1953                         return v_list_itr->status;
1954         }
1955         return 0;
1956 }
1957
1958 /**
1959  * ice_add_eth_mac - Add ethertype and MAC based filter rule
1960  * @hw: pointer to the hardware structure
1961  * @em_list: list of ether type MAC filter, MAC is optional
1962  *
1963  * This function requires the caller to populate the entries in
1964  * the filter list with the necessary fields (including flags to
1965  * indicate Tx or Rx rules).
1966  */
1967 enum ice_status
1968 ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
1969 {
1970         struct ice_fltr_list_entry *em_list_itr;
1971
1972         if (!em_list || !hw)
1973                 return ICE_ERR_PARAM;
1974
1975         list_for_each_entry(em_list_itr, em_list, list_entry) {
1976                 enum ice_sw_lkup_type l_type =
1977                         em_list_itr->fltr_info.lkup_type;
1978
1979                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
1980                     l_type != ICE_SW_LKUP_ETHERTYPE)
1981                         return ICE_ERR_PARAM;
1982
1983                 em_list_itr->status = ice_add_rule_internal(hw, l_type,
1984                                                             em_list_itr);
1985                 if (em_list_itr->status)
1986                         return em_list_itr->status;
1987         }
1988         return 0;
1989 }
1990
1991 /**
1992  * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
1993  * @hw: pointer to the hardware structure
1994  * @em_list: list of ethertype or ethertype MAC entries
1995  */
1996 enum ice_status
1997 ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
1998 {
1999         struct ice_fltr_list_entry *em_list_itr, *tmp;
2000
2001         if (!em_list || !hw)
2002                 return ICE_ERR_PARAM;
2003
2004         list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
2005                 enum ice_sw_lkup_type l_type =
2006                         em_list_itr->fltr_info.lkup_type;
2007
2008                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
2009                     l_type != ICE_SW_LKUP_ETHERTYPE)
2010                         return ICE_ERR_PARAM;
2011
2012                 em_list_itr->status = ice_remove_rule_internal(hw, l_type,
2013                                                                em_list_itr);
2014                 if (em_list_itr->status)
2015                         return em_list_itr->status;
2016         }
2017         return 0;
2018 }
2019
2020 /**
2021  * ice_rem_sw_rule_info
2022  * @hw: pointer to the hardware structure
2023  * @rule_head: pointer to the switch list structure that we want to delete
2024  */
2025 static void
2026 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
2027 {
2028         if (!list_empty(rule_head)) {
2029                 struct ice_fltr_mgmt_list_entry *entry;
2030                 struct ice_fltr_mgmt_list_entry *tmp;
2031
2032                 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
2033                         list_del(&entry->list_entry);
2034                         devm_kfree(ice_hw_to_dev(hw), entry);
2035                 }
2036         }
2037 }
2038
2039 /**
2040  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
2041  * @hw: pointer to the hardware structure
2042  * @vsi_handle: VSI handle to set as default
2043  * @set: true to add the above mentioned switch rule, false to remove it
2044  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
2045  *
2046  * add filter rule to set/unset given VSI as default VSI for the switch
2047  * (represented by swid)
2048  */
2049 enum ice_status
2050 ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction)
2051 {
2052         struct ice_aqc_sw_rules_elem *s_rule;
2053         struct ice_fltr_info f_info;
2054         enum ice_adminq_opc opcode;
2055         enum ice_status status;
2056         u16 s_rule_size;
2057         u16 hw_vsi_id;
2058
2059         if (!ice_is_vsi_valid(hw, vsi_handle))
2060                 return ICE_ERR_PARAM;
2061         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
2062
2063         s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
2064                 ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
2065
2066         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2067         if (!s_rule)
2068                 return ICE_ERR_NO_MEMORY;
2069
2070         memset(&f_info, 0, sizeof(f_info));
2071
2072         f_info.lkup_type = ICE_SW_LKUP_DFLT;
2073         f_info.flag = direction;
2074         f_info.fltr_act = ICE_FWD_TO_VSI;
2075         f_info.fwd_id.hw_vsi_id = hw_vsi_id;
2076
2077         if (f_info.flag & ICE_FLTR_RX) {
2078                 f_info.src = hw->port_info->lport;
2079                 f_info.src_id = ICE_SRC_ID_LPORT;
2080                 if (!set)
2081                         f_info.fltr_rule_id =
2082                                 hw->port_info->dflt_rx_vsi_rule_id;
2083         } else if (f_info.flag & ICE_FLTR_TX) {
2084                 f_info.src_id = ICE_SRC_ID_VSI;
2085                 f_info.src = hw_vsi_id;
2086                 if (!set)
2087                         f_info.fltr_rule_id =
2088                                 hw->port_info->dflt_tx_vsi_rule_id;
2089         }
2090
2091         if (set)
2092                 opcode = ice_aqc_opc_add_sw_rules;
2093         else
2094                 opcode = ice_aqc_opc_remove_sw_rules;
2095
2096         ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
2097
2098         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
2099         if (status || !(f_info.flag & ICE_FLTR_TX_RX))
2100                 goto out;
2101         if (set) {
2102                 u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
2103
2104                 if (f_info.flag & ICE_FLTR_TX) {
2105                         hw->port_info->dflt_tx_vsi_num = hw_vsi_id;
2106                         hw->port_info->dflt_tx_vsi_rule_id = index;
2107                 } else if (f_info.flag & ICE_FLTR_RX) {
2108                         hw->port_info->dflt_rx_vsi_num = hw_vsi_id;
2109                         hw->port_info->dflt_rx_vsi_rule_id = index;
2110                 }
2111         } else {
2112                 if (f_info.flag & ICE_FLTR_TX) {
2113                         hw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
2114                         hw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
2115                 } else if (f_info.flag & ICE_FLTR_RX) {
2116                         hw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
2117                         hw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
2118                 }
2119         }
2120
2121 out:
2122         devm_kfree(ice_hw_to_dev(hw), s_rule);
2123         return status;
2124 }
2125
2126 /**
2127  * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
2128  * @hw: pointer to the hardware structure
2129  * @recp_id: lookup type for which the specified rule needs to be searched
2130  * @f_info: rule information
2131  *
2132  * Helper function to search for a unicast rule entry - this is to be used
2133  * to remove unicast MAC filter that is not shared with other VSIs on the
2134  * PF switch.
2135  *
2136  * Returns pointer to entry storing the rule if found
2137  */
2138 static struct ice_fltr_mgmt_list_entry *
2139 ice_find_ucast_rule_entry(struct ice_hw *hw, u8 recp_id,
2140                           struct ice_fltr_info *f_info)
2141 {
2142         struct ice_switch_info *sw = hw->switch_info;
2143         struct ice_fltr_mgmt_list_entry *list_itr;
2144         struct list_head *list_head;
2145
2146         list_head = &sw->recp_list[recp_id].filt_rules;
2147         list_for_each_entry(list_itr, list_head, list_entry) {
2148                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
2149                             sizeof(f_info->l_data)) &&
2150                     f_info->fwd_id.hw_vsi_id ==
2151                     list_itr->fltr_info.fwd_id.hw_vsi_id &&
2152                     f_info->flag == list_itr->fltr_info.flag)
2153                         return list_itr;
2154         }
2155         return NULL;
2156 }
2157
2158 /**
2159  * ice_remove_mac - remove a MAC address based filter rule
2160  * @hw: pointer to the hardware structure
2161  * @m_list: list of MAC addresses and forwarding information
2162  *
2163  * This function removes either a MAC filter rule or a specific VSI from a
2164  * VSI list for a multicast MAC address.
2165  *
2166  * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
2167  * ice_add_mac. Caller should be aware that this call will only work if all
2168  * the entries passed into m_list were added previously. It will not attempt to
2169  * do a partial remove of entries that were found.
2170  */
2171 enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
2172 {
2173         struct ice_fltr_list_entry *list_itr, *tmp;
2174         struct mutex *rule_lock; /* Lock to protect filter rule list */
2175
2176         if (!m_list)
2177                 return ICE_ERR_PARAM;
2178
2179         rule_lock = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
2180         list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
2181                 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
2182                 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
2183                 u16 vsi_handle;
2184
2185                 if (l_type != ICE_SW_LKUP_MAC)
2186                         return ICE_ERR_PARAM;
2187
2188                 vsi_handle = list_itr->fltr_info.vsi_handle;
2189                 if (!ice_is_vsi_valid(hw, vsi_handle))
2190                         return ICE_ERR_PARAM;
2191
2192                 list_itr->fltr_info.fwd_id.hw_vsi_id =
2193                                         ice_get_hw_vsi_num(hw, vsi_handle);
2194                 if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
2195                         /* Don't remove the unicast address that belongs to
2196                          * another VSI on the switch, since it is not being
2197                          * shared...
2198                          */
2199                         mutex_lock(rule_lock);
2200                         if (!ice_find_ucast_rule_entry(hw, ICE_SW_LKUP_MAC,
2201                                                        &list_itr->fltr_info)) {
2202                                 mutex_unlock(rule_lock);
2203                                 return ICE_ERR_DOES_NOT_EXIST;
2204                         }
2205                         mutex_unlock(rule_lock);
2206                 }
2207                 list_itr->status = ice_remove_rule_internal(hw,
2208                                                             ICE_SW_LKUP_MAC,
2209                                                             list_itr);
2210                 if (list_itr->status)
2211                         return list_itr->status;
2212         }
2213         return 0;
2214 }
2215
2216 /**
2217  * ice_remove_vlan - Remove VLAN based filter rule
2218  * @hw: pointer to the hardware structure
2219  * @v_list: list of VLAN entries and forwarding information
2220  */
2221 enum ice_status
2222 ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
2223 {
2224         struct ice_fltr_list_entry *v_list_itr, *tmp;
2225
2226         if (!v_list || !hw)
2227                 return ICE_ERR_PARAM;
2228
2229         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
2230                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
2231
2232                 if (l_type != ICE_SW_LKUP_VLAN)
2233                         return ICE_ERR_PARAM;
2234                 v_list_itr->status = ice_remove_rule_internal(hw,
2235                                                               ICE_SW_LKUP_VLAN,
2236                                                               v_list_itr);
2237                 if (v_list_itr->status)
2238                         return v_list_itr->status;
2239         }
2240         return 0;
2241 }
2242
2243 /**
2244  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
2245  * @fm_entry: filter entry to inspect
2246  * @vsi_handle: VSI handle to compare with filter info
2247  */
2248 static bool
2249 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
2250 {
2251         return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
2252                  fm_entry->fltr_info.vsi_handle == vsi_handle) ||
2253                 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
2254                  fm_entry->vsi_list_info &&
2255                  (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
2256 }
2257
2258 /**
2259  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
2260  * @hw: pointer to the hardware structure
2261  * @vsi_handle: VSI handle to remove filters from
2262  * @vsi_list_head: pointer to the list to add entry to
2263  * @fi: pointer to fltr_info of filter entry to copy & add
2264  *
2265  * Helper function, used when creating a list of filters to remove from
2266  * a specific VSI. The entry added to vsi_list_head is a COPY of the
2267  * original filter entry, with the exception of fltr_info.fltr_act and
2268  * fltr_info.fwd_id fields. These are set such that later logic can
2269  * extract which VSI to remove the fltr from, and pass on that information.
2270  */
2271 static enum ice_status
2272 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
2273                                struct list_head *vsi_list_head,
2274                                struct ice_fltr_info *fi)
2275 {
2276         struct ice_fltr_list_entry *tmp;
2277
2278         /* this memory is freed up in the caller function
2279          * once filters for this VSI are removed
2280          */
2281         tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
2282         if (!tmp)
2283                 return ICE_ERR_NO_MEMORY;
2284
2285         tmp->fltr_info = *fi;
2286
2287         /* Overwrite these fields to indicate which VSI to remove filter from,
2288          * so find and remove logic can extract the information from the
2289          * list entries. Note that original entries will still have proper
2290          * values.
2291          */
2292         tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
2293         tmp->fltr_info.vsi_handle = vsi_handle;
2294         tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
2295
2296         list_add(&tmp->list_entry, vsi_list_head);
2297
2298         return 0;
2299 }
2300
2301 /**
2302  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
2303  * @hw: pointer to the hardware structure
2304  * @vsi_handle: VSI handle to remove filters from
2305  * @lkup_list_head: pointer to the list that has certain lookup type filters
2306  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
2307  *
2308  * Locates all filters in lkup_list_head that are used by the given VSI,
2309  * and adds COPIES of those entries to vsi_list_head (intended to be used
2310  * to remove the listed filters).
2311  * Note that this means all entries in vsi_list_head must be explicitly
2312  * deallocated by the caller when done with list.
2313  */
2314 static enum ice_status
2315 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
2316                          struct list_head *lkup_list_head,
2317                          struct list_head *vsi_list_head)
2318 {
2319         struct ice_fltr_mgmt_list_entry *fm_entry;
2320         enum ice_status status = 0;
2321
2322         /* check to make sure VSI ID is valid and within boundary */
2323         if (!ice_is_vsi_valid(hw, vsi_handle))
2324                 return ICE_ERR_PARAM;
2325
2326         list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
2327                 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
2328                         continue;
2329
2330                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
2331                                                         vsi_list_head,
2332                                                         &fm_entry->fltr_info);
2333                 if (status)
2334                         return status;
2335         }
2336         return status;
2337 }
2338
2339 /**
2340  * ice_determine_promisc_mask
2341  * @fi: filter info to parse
2342  *
2343  * Helper function to determine which ICE_PROMISC_ mask corresponds
2344  * to given filter into.
2345  */
2346 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
2347 {
2348         u16 vid = fi->l_data.mac_vlan.vlan_id;
2349         u8 *macaddr = fi->l_data.mac.mac_addr;
2350         bool is_tx_fltr = false;
2351         u8 promisc_mask = 0;
2352
2353         if (fi->flag == ICE_FLTR_TX)
2354                 is_tx_fltr = true;
2355
2356         if (is_broadcast_ether_addr(macaddr))
2357                 promisc_mask |= is_tx_fltr ?
2358                         ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
2359         else if (is_multicast_ether_addr(macaddr))
2360                 promisc_mask |= is_tx_fltr ?
2361                         ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
2362         else if (is_unicast_ether_addr(macaddr))
2363                 promisc_mask |= is_tx_fltr ?
2364                         ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
2365         if (vid)
2366                 promisc_mask |= is_tx_fltr ?
2367                         ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
2368
2369         return promisc_mask;
2370 }
2371
2372 /**
2373  * ice_remove_promisc - Remove promisc based filter rules
2374  * @hw: pointer to the hardware structure
2375  * @recp_id: recipe ID for which the rule needs to removed
2376  * @v_list: list of promisc entries
2377  */
2378 static enum ice_status
2379 ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
2380                    struct list_head *v_list)
2381 {
2382         struct ice_fltr_list_entry *v_list_itr, *tmp;
2383
2384         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
2385                 v_list_itr->status =
2386                         ice_remove_rule_internal(hw, recp_id, v_list_itr);
2387                 if (v_list_itr->status)
2388                         return v_list_itr->status;
2389         }
2390         return 0;
2391 }
2392
2393 /**
2394  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
2395  * @hw: pointer to the hardware structure
2396  * @vsi_handle: VSI handle to clear mode
2397  * @promisc_mask: mask of promiscuous config bits to clear
2398  * @vid: VLAN ID to clear VLAN promiscuous
2399  */
2400 enum ice_status
2401 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
2402                       u16 vid)
2403 {
2404         struct ice_switch_info *sw = hw->switch_info;
2405         struct ice_fltr_list_entry *fm_entry, *tmp;
2406         struct list_head remove_list_head;
2407         struct ice_fltr_mgmt_list_entry *itr;
2408         struct list_head *rule_head;
2409         struct mutex *rule_lock;        /* Lock to protect filter rule list */
2410         enum ice_status status = 0;
2411         u8 recipe_id;
2412
2413         if (!ice_is_vsi_valid(hw, vsi_handle))
2414                 return ICE_ERR_PARAM;
2415
2416         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
2417                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
2418         else
2419                 recipe_id = ICE_SW_LKUP_PROMISC;
2420
2421         rule_head = &sw->recp_list[recipe_id].filt_rules;
2422         rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
2423
2424         INIT_LIST_HEAD(&remove_list_head);
2425
2426         mutex_lock(rule_lock);
2427         list_for_each_entry(itr, rule_head, list_entry) {
2428                 struct ice_fltr_info *fltr_info;
2429                 u8 fltr_promisc_mask = 0;
2430
2431                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
2432                         continue;
2433                 fltr_info = &itr->fltr_info;
2434
2435                 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
2436                     vid != fltr_info->l_data.mac_vlan.vlan_id)
2437                         continue;
2438
2439                 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
2440
2441                 /* Skip if filter is not completely specified by given mask */
2442                 if (fltr_promisc_mask & ~promisc_mask)
2443                         continue;
2444
2445                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
2446                                                         &remove_list_head,
2447                                                         fltr_info);
2448                 if (status) {
2449                         mutex_unlock(rule_lock);
2450                         goto free_fltr_list;
2451                 }
2452         }
2453         mutex_unlock(rule_lock);
2454
2455         status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
2456
2457 free_fltr_list:
2458         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
2459                 list_del(&fm_entry->list_entry);
2460                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
2461         }
2462
2463         return status;
2464 }
2465
2466 /**
2467  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
2468  * @hw: pointer to the hardware structure
2469  * @vsi_handle: VSI handle to configure
2470  * @promisc_mask: mask of promiscuous config bits
2471  * @vid: VLAN ID to set VLAN promiscuous
2472  */
2473 enum ice_status
2474 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
2475 {
2476         enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
2477         struct ice_fltr_list_entry f_list_entry;
2478         struct ice_fltr_info new_fltr;
2479         enum ice_status status = 0;
2480         bool is_tx_fltr;
2481         u16 hw_vsi_id;
2482         int pkt_type;
2483         u8 recipe_id;
2484
2485         if (!ice_is_vsi_valid(hw, vsi_handle))
2486                 return ICE_ERR_PARAM;
2487         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
2488
2489         memset(&new_fltr, 0, sizeof(new_fltr));
2490
2491         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
2492                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
2493                 new_fltr.l_data.mac_vlan.vlan_id = vid;
2494                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
2495         } else {
2496                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
2497                 recipe_id = ICE_SW_LKUP_PROMISC;
2498         }
2499
2500         /* Separate filters must be set for each direction/packet type
2501          * combination, so we will loop over the mask value, store the
2502          * individual type, and clear it out in the input mask as it
2503          * is found.
2504          */
2505         while (promisc_mask) {
2506                 u8 *mac_addr;
2507
2508                 pkt_type = 0;
2509                 is_tx_fltr = false;
2510
2511                 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
2512                         promisc_mask &= ~ICE_PROMISC_UCAST_RX;
2513                         pkt_type = UCAST_FLTR;
2514                 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
2515                         promisc_mask &= ~ICE_PROMISC_UCAST_TX;
2516                         pkt_type = UCAST_FLTR;
2517                         is_tx_fltr = true;
2518                 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
2519                         promisc_mask &= ~ICE_PROMISC_MCAST_RX;
2520                         pkt_type = MCAST_FLTR;
2521                 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
2522                         promisc_mask &= ~ICE_PROMISC_MCAST_TX;
2523                         pkt_type = MCAST_FLTR;
2524                         is_tx_fltr = true;
2525                 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
2526                         promisc_mask &= ~ICE_PROMISC_BCAST_RX;
2527                         pkt_type = BCAST_FLTR;
2528                 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
2529                         promisc_mask &= ~ICE_PROMISC_BCAST_TX;
2530                         pkt_type = BCAST_FLTR;
2531                         is_tx_fltr = true;
2532                 }
2533
2534                 /* Check for VLAN promiscuous flag */
2535                 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
2536                         promisc_mask &= ~ICE_PROMISC_VLAN_RX;
2537                 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
2538                         promisc_mask &= ~ICE_PROMISC_VLAN_TX;
2539                         is_tx_fltr = true;
2540                 }
2541
2542                 /* Set filter DA based on packet type */
2543                 mac_addr = new_fltr.l_data.mac.mac_addr;
2544                 if (pkt_type == BCAST_FLTR) {
2545                         eth_broadcast_addr(mac_addr);
2546                 } else if (pkt_type == MCAST_FLTR ||
2547                            pkt_type == UCAST_FLTR) {
2548                         /* Use the dummy ether header DA */
2549                         ether_addr_copy(mac_addr, dummy_eth_header);
2550                         if (pkt_type == MCAST_FLTR)
2551                                 mac_addr[0] |= 0x1;     /* Set multicast bit */
2552                 }
2553
2554                 /* Need to reset this to zero for all iterations */
2555                 new_fltr.flag = 0;
2556                 if (is_tx_fltr) {
2557                         new_fltr.flag |= ICE_FLTR_TX;
2558                         new_fltr.src = hw_vsi_id;
2559                 } else {
2560                         new_fltr.flag |= ICE_FLTR_RX;
2561                         new_fltr.src = hw->port_info->lport;
2562                 }
2563
2564                 new_fltr.fltr_act = ICE_FWD_TO_VSI;
2565                 new_fltr.vsi_handle = vsi_handle;
2566                 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
2567                 f_list_entry.fltr_info = new_fltr;
2568
2569                 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
2570                 if (status)
2571                         goto set_promisc_exit;
2572         }
2573
2574 set_promisc_exit:
2575         return status;
2576 }
2577
2578 /**
2579  * ice_set_vlan_vsi_promisc
2580  * @hw: pointer to the hardware structure
2581  * @vsi_handle: VSI handle to configure
2582  * @promisc_mask: mask of promiscuous config bits
2583  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
2584  *
2585  * Configure VSI with all associated VLANs to given promiscuous mode(s)
2586  */
2587 enum ice_status
2588 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
2589                          bool rm_vlan_promisc)
2590 {
2591         struct ice_switch_info *sw = hw->switch_info;
2592         struct ice_fltr_list_entry *list_itr, *tmp;
2593         struct list_head vsi_list_head;
2594         struct list_head *vlan_head;
2595         struct mutex *vlan_lock; /* Lock to protect filter rule list */
2596         enum ice_status status;
2597         u16 vlan_id;
2598
2599         INIT_LIST_HEAD(&vsi_list_head);
2600         vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
2601         vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
2602         mutex_lock(vlan_lock);
2603         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
2604                                           &vsi_list_head);
2605         mutex_unlock(vlan_lock);
2606         if (status)
2607                 goto free_fltr_list;
2608
2609         list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
2610                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
2611                 if (rm_vlan_promisc)
2612                         status = ice_clear_vsi_promisc(hw, vsi_handle,
2613                                                        promisc_mask, vlan_id);
2614                 else
2615                         status = ice_set_vsi_promisc(hw, vsi_handle,
2616                                                      promisc_mask, vlan_id);
2617                 if (status)
2618                         break;
2619         }
2620
2621 free_fltr_list:
2622         list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
2623                 list_del(&list_itr->list_entry);
2624                 devm_kfree(ice_hw_to_dev(hw), list_itr);
2625         }
2626         return status;
2627 }
2628
2629 /**
2630  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
2631  * @hw: pointer to the hardware structure
2632  * @vsi_handle: VSI handle to remove filters from
2633  * @lkup: switch rule filter lookup type
2634  */
2635 static void
2636 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
2637                          enum ice_sw_lkup_type lkup)
2638 {
2639         struct ice_switch_info *sw = hw->switch_info;
2640         struct ice_fltr_list_entry *fm_entry;
2641         struct list_head remove_list_head;
2642         struct list_head *rule_head;
2643         struct ice_fltr_list_entry *tmp;
2644         struct mutex *rule_lock;        /* Lock to protect filter rule list */
2645         enum ice_status status;
2646
2647         INIT_LIST_HEAD(&remove_list_head);
2648         rule_lock = &sw->recp_list[lkup].filt_rule_lock;
2649         rule_head = &sw->recp_list[lkup].filt_rules;
2650         mutex_lock(rule_lock);
2651         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
2652                                           &remove_list_head);
2653         mutex_unlock(rule_lock);
2654         if (status)
2655                 goto free_fltr_list;
2656
2657         switch (lkup) {
2658         case ICE_SW_LKUP_MAC:
2659                 ice_remove_mac(hw, &remove_list_head);
2660                 break;
2661         case ICE_SW_LKUP_VLAN:
2662                 ice_remove_vlan(hw, &remove_list_head);
2663                 break;
2664         case ICE_SW_LKUP_PROMISC:
2665         case ICE_SW_LKUP_PROMISC_VLAN:
2666                 ice_remove_promisc(hw, lkup, &remove_list_head);
2667                 break;
2668         case ICE_SW_LKUP_MAC_VLAN:
2669         case ICE_SW_LKUP_ETHERTYPE:
2670         case ICE_SW_LKUP_ETHERTYPE_MAC:
2671         case ICE_SW_LKUP_DFLT:
2672         case ICE_SW_LKUP_LAST:
2673         default:
2674                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
2675                 break;
2676         }
2677
2678 free_fltr_list:
2679         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
2680                 list_del(&fm_entry->list_entry);
2681                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
2682         }
2683 }
2684
2685 /**
2686  * ice_remove_vsi_fltr - Remove all filters for a VSI
2687  * @hw: pointer to the hardware structure
2688  * @vsi_handle: VSI handle to remove filters from
2689  */
2690 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
2691 {
2692         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
2693         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
2694         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
2695         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
2696         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
2697         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
2698         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
2699         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
2700 }
2701
2702 /**
2703  * ice_alloc_res_cntr - allocating resource counter
2704  * @hw: pointer to the hardware structure
2705  * @type: type of resource
2706  * @alloc_shared: if set it is shared else dedicated
2707  * @num_items: number of entries requested for FD resource type
2708  * @counter_id: counter index returned by AQ call
2709  */
2710 enum ice_status
2711 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
2712                    u16 *counter_id)
2713 {
2714         struct ice_aqc_alloc_free_res_elem *buf;
2715         enum ice_status status;
2716         u16 buf_len;
2717
2718         /* Allocate resource */
2719         buf_len = struct_size(buf, elem, 1);
2720         buf = kzalloc(buf_len, GFP_KERNEL);
2721         if (!buf)
2722                 return ICE_ERR_NO_MEMORY;
2723
2724         buf->num_elems = cpu_to_le16(num_items);
2725         buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
2726                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
2727
2728         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
2729                                        ice_aqc_opc_alloc_res, NULL);
2730         if (status)
2731                 goto exit;
2732
2733         *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
2734
2735 exit:
2736         kfree(buf);
2737         return status;
2738 }
2739
2740 /**
2741  * ice_free_res_cntr - free resource counter
2742  * @hw: pointer to the hardware structure
2743  * @type: type of resource
2744  * @alloc_shared: if set it is shared else dedicated
2745  * @num_items: number of entries to be freed for FD resource type
2746  * @counter_id: counter ID resource which needs to be freed
2747  */
2748 enum ice_status
2749 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
2750                   u16 counter_id)
2751 {
2752         struct ice_aqc_alloc_free_res_elem *buf;
2753         enum ice_status status;
2754         u16 buf_len;
2755
2756         /* Free resource */
2757         buf_len = struct_size(buf, elem, 1);
2758         buf = kzalloc(buf_len, GFP_KERNEL);
2759         if (!buf)
2760                 return ICE_ERR_NO_MEMORY;
2761
2762         buf->num_elems = cpu_to_le16(num_items);
2763         buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
2764                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
2765         buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
2766
2767         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
2768                                        ice_aqc_opc_free_res, NULL);
2769         if (status)
2770                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
2771
2772         kfree(buf);
2773         return status;
2774 }
2775
2776 /**
2777  * ice_replay_vsi_fltr - Replay filters for requested VSI
2778  * @hw: pointer to the hardware structure
2779  * @vsi_handle: driver VSI handle
2780  * @recp_id: Recipe ID for which rules need to be replayed
2781  * @list_head: list for which filters need to be replayed
2782  *
2783  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
2784  * It is required to pass valid VSI handle.
2785  */
2786 static enum ice_status
2787 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
2788                     struct list_head *list_head)
2789 {
2790         struct ice_fltr_mgmt_list_entry *itr;
2791         enum ice_status status = 0;
2792         u16 hw_vsi_id;
2793
2794         if (list_empty(list_head))
2795                 return status;
2796         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
2797
2798         list_for_each_entry(itr, list_head, list_entry) {
2799                 struct ice_fltr_list_entry f_entry;
2800
2801                 f_entry.fltr_info = itr->fltr_info;
2802                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
2803                     itr->fltr_info.vsi_handle == vsi_handle) {
2804                         /* update the src in case it is VSI num */
2805                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
2806                                 f_entry.fltr_info.src = hw_vsi_id;
2807                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
2808                         if (status)
2809                                 goto end;
2810                         continue;
2811                 }
2812                 if (!itr->vsi_list_info ||
2813                     !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
2814                         continue;
2815                 /* Clearing it so that the logic can add it back */
2816                 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
2817                 f_entry.fltr_info.vsi_handle = vsi_handle;
2818                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
2819                 /* update the src in case it is VSI num */
2820                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
2821                         f_entry.fltr_info.src = hw_vsi_id;
2822                 if (recp_id == ICE_SW_LKUP_VLAN)
2823                         status = ice_add_vlan_internal(hw, &f_entry);
2824                 else
2825                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
2826                 if (status)
2827                         goto end;
2828         }
2829 end:
2830         return status;
2831 }
2832
2833 /**
2834  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
2835  * @hw: pointer to the hardware structure
2836  * @vsi_handle: driver VSI handle
2837  *
2838  * Replays filters for requested VSI via vsi_handle.
2839  */
2840 enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
2841 {
2842         struct ice_switch_info *sw = hw->switch_info;
2843         enum ice_status status = 0;
2844         u8 i;
2845
2846         for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
2847                 struct list_head *head;
2848
2849                 head = &sw->recp_list[i].filt_replay_rules;
2850                 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
2851                 if (status)
2852                         return status;
2853         }
2854         return status;
2855 }
2856
2857 /**
2858  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
2859  * @hw: pointer to the HW struct
2860  *
2861  * Deletes the filter replay rules.
2862  */
2863 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
2864 {
2865         struct ice_switch_info *sw = hw->switch_info;
2866         u8 i;
2867
2868         if (!sw)
2869                 return;
2870
2871         for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
2872                 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
2873                         struct list_head *l_head;
2874
2875                         l_head = &sw->recp_list[i].filt_replay_rules;
2876                         ice_rem_sw_rule_info(hw, l_head);
2877                 }
2878         }
2879 }