1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Intel Corporation. */
5 #include "ice_switch.h"
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
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) }
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
27 #define DUMMY_ETH_HDR_LEN 16
28 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
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])))
46 * ice_init_def_sw_recp - initialize the recipe book keeping tables
47 * @hw: pointer to the HW struct
49 * Allocate memory for the entire recipe table and initialize the structures/
50 * entries corresponding to basic recipes.
52 enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
54 struct ice_sw_recipe *recps;
57 recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
58 sizeof(*recps), GFP_KERNEL);
60 return ICE_ERR_NO_MEMORY;
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);
69 hw->switch_info->recp_list = recps;
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
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.
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.
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.
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)
104 struct ice_aqc_get_sw_cfg *cmd;
105 struct ice_aq_desc desc;
106 enum ice_status status;
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);
112 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
114 *req_desc = le16_to_cpu(cmd->element);
115 *num_elems = le16_to_cpu(cmd->num_elems);
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
127 * Add a VSI context to the hardware (0x0210)
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)
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;
138 cmd = &desc.params.vsi_cmd;
139 res = &desc.params.add_update_free_vsi_res;
141 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
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;
148 cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
150 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
152 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
153 sizeof(vsi_ctx->info), cd);
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);
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
171 * Free VSI context info from hardware (0x0213)
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)
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;
182 cmd = &desc.params.vsi_cmd;
183 resp = &desc.params.add_update_free_vsi_res;
185 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
187 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
189 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
191 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
193 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
194 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
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
206 * Update VSI context in the hardware (0x0211)
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)
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;
217 cmd = &desc.params.vsi_cmd;
218 resp = &desc.params.add_update_free_vsi_res;
220 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
222 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
224 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
226 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
227 sizeof(vsi_ctx->info), cd);
230 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
231 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
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
242 * check whether the VSI is valid or not
244 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
246 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
250 * ice_get_hw_vsi_num - return the HW VSI number
251 * @hw: pointer to the HW struct
252 * @vsi_handle: VSI handle
254 * return the HW VSI number
255 * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
257 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
259 return hw->vsi_ctx[vsi_handle]->vsi_num;
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
267 * return the VSI context entry for a given VSI handle
269 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
271 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
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
280 * save the VSI context entry for a given VSI handle
283 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
285 hw->vsi_ctx[vsi_handle] = vsi;
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
293 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
295 struct ice_vsi_ctx *vsi;
298 vsi = ice_get_vsi_ctx(hw, vsi_handle);
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;
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;
314 * ice_clear_vsi_ctx - clear the VSI context entry
315 * @hw: pointer to the HW struct
316 * @vsi_handle: VSI handle
318 * clear the VSI context entry
320 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
322 struct ice_vsi_ctx *vsi;
324 vsi = ice_get_vsi_ctx(hw, vsi_handle);
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;
333 * ice_clear_all_vsi_ctx - clear all the VSI context entries
334 * @hw: pointer to the HW struct
336 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
340 for (i = 0; i < ICE_MAX_VSI; i++)
341 ice_clear_vsi_ctx(hw, i);
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
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.
356 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
357 struct ice_sq_cd *cd)
359 struct ice_vsi_ctx *tmp_vsi_ctx;
360 enum ice_status status;
362 if (vsi_handle >= ICE_MAX_VSI)
363 return ICE_ERR_PARAM;
364 status = ice_aq_add_vsi(hw, vsi_ctx, cd);
367 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
369 /* Create a new VSI context */
370 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
371 sizeof(*tmp_vsi_ctx), GFP_KERNEL);
373 ice_aq_free_vsi(hw, vsi_ctx, false, cd);
374 return ICE_ERR_NO_MEMORY;
376 *tmp_vsi_ctx = *vsi_ctx;
377 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
379 /* update with new HW VSI num */
380 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
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
394 * Free VSI context info from hardware as well as from VSI handle list
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)
400 enum ice_status status;
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);
407 ice_clear_vsi_ctx(hw, vsi_handle);
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
418 * Update VSI context in the hardware
421 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
422 struct ice_sq_cd *cd)
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);
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
437 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
439 struct ice_vsi_ctx *ctx;
441 ctx = ice_get_vsi_ctx(hw, vsi_handle);
446 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
448 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
450 return ice_status_to_errno(ice_update_vsi(hw, vsi_handle, ctx, NULL));
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
460 * allocates or free a VSI list resource
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)
467 struct ice_aqc_alloc_free_res_elem *sw_buf;
468 struct ice_aqc_res_elem *vsi_ele;
469 enum ice_status status;
472 buf_len = struct_size(sw_buf, elem, 1);
473 sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
475 return ICE_ERR_NO_MEMORY;
476 sw_buf->num_elems = cpu_to_le16(1);
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) {
487 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
489 status = ICE_ERR_PARAM;
490 goto ice_aq_alloc_free_vsi_list_exit;
493 if (opc == ice_aqc_opc_free_res)
494 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
496 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
498 goto ice_aq_alloc_free_vsi_list_exit;
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);
505 ice_aq_alloc_free_vsi_list_exit:
506 devm_kfree(ice_hw_to_dev(hw), sw_buf);
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
519 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
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)
525 struct ice_aq_desc desc;
526 enum ice_status status;
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;
533 ice_fill_dflt_direct_cmd_desc(&desc, opc);
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;
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
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)
559 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
560 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
562 pi->pf_vf_num = pf_vf_num;
564 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
565 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
568 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
573 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
574 * @hw: pointer to the hardware structure
576 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
578 struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
579 enum ice_status status;
584 rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN,
588 return ICE_ERR_NO_MEMORY;
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
596 struct ice_aqc_get_sw_cfg_resp_elem *ele;
598 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
599 &req_desc, &num_elems, NULL);
604 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
605 u16 pf_vf_num, swid, vsi_port_num;
609 vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
610 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
612 pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
613 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
615 swid = le16_to_cpu(ele->swid);
617 if (le16_to_cpu(ele->pf_vf_num) &
618 ICE_AQC_GET_SW_CONF_RESP_IS_VF)
621 res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
622 ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
624 if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
625 /* FW VSI is not needed. Just continue. */
629 ice_init_port_info(hw->port_info, vsi_port_num,
630 res_type, swid, pf_vf_num, is_vf);
632 } while (req_desc && !status);
634 devm_kfree(ice_hw_to_dev(hw), rbuf);
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
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.
647 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
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.
659 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
662 /* Set lan_en to TRUE if
663 * 1. The switch is a VEB AND
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.
674 * The switch is a VEPA.
676 * In all other cases, the LAN enable has to be set to false.
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)))
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
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)
707 u16 vlan_id = ICE_MAX_VLAN_ID + 1;
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;
723 eth_hdr_sz = sizeof(dummy_eth_header);
724 eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
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);
730 switch (f_info->fltr_act) {
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;
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;
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;
752 case ICE_DROP_PACKET:
753 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
754 ICE_SINGLE_ACT_VALID_BIT;
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;
770 act |= ICE_SINGLE_ACT_LB_ENABLE;
772 act |= ICE_SINGLE_ACT_LAN_ENABLE;
774 switch (f_info->lkup_type) {
775 case ICE_SW_LKUP_MAC:
776 daddr = f_info->l_data.mac.mac_addr;
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;
786 case ICE_SW_LKUP_ETHERTYPE_MAC:
787 daddr = f_info->l_data.ethertype_mac.mac_addr;
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);
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;
797 case ICE_SW_LKUP_PROMISC_VLAN:
798 vlan_id = f_info->l_data.mac_vlan.vlan_id;
800 case ICE_SW_LKUP_PROMISC:
801 daddr = f_info->l_data.mac_vlan.mac_addr;
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);
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);
817 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
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);
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);
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
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
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)
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
849 const u16 num_lg_acts = 3;
850 enum ice_status status;
856 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
857 return ICE_ERR_PARAM;
859 /* Create two back-to-back switch rules and submit them to the HW using
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);
868 return ICE_ERR_NO_MEMORY;
870 rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
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);
877 /* First action VSI forwarding or VSI list forwarding depending on how
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;
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);
889 /* Second action descriptor type */
890 act = ICE_LG_ACT_GENERIC;
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);
895 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
896 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
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;
903 lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);
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);
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));
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
919 rx_tx->pdata.lkup_tx_rx.index =
920 cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
922 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
923 ice_aqc_opc_update_sw_rules, NULL);
925 m_ent->lg_act_idx = l_id;
926 m_ent->sw_marker_id = sw_marker;
929 devm_kfree(ice_hw_to_dev(hw), lg_act);
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
940 * Helper function to create a new entry of VSI list ID to VSI mapping
941 * using the given VSI list ID
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,
947 struct ice_switch_info *sw = hw->switch_info;
948 struct ice_vsi_list_map_info *v_map;
951 v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
955 v_map->vsi_list_id = vsi_list_id;
957 for (i = 0; i < num_vsi; i++)
958 set_bit(vsi_handle_arr[i], v_map->vsi_map);
960 list_add(&v_map->list_entry, &sw->vsi_list_map_head);
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
974 * Call AQ command to add a new switch rule or update existing switch rule
975 * using the given VSI list ID
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)
982 struct ice_aqc_sw_rules_elem *s_rule;
983 enum ice_status status;
989 return ICE_ERR_PARAM;
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;
1003 return ICE_ERR_PARAM;
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);
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;
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]));
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);
1023 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
1026 devm_kfree(ice_hw_to_dev(hw), s_rule);
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
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)
1042 enum ice_status status;
1044 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
1045 ice_aqc_opc_alloc_res);
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);
1056 * ice_create_pkt_fwd_rule
1057 * @hw: pointer to the hardware structure
1058 * @f_entry: entry containing packet forwarding information
1060 * Create switch rule with given filter information and add an entry
1061 * to the corresponding filter management list to track this switch rule
1064 static enum ice_status
1065 ice_create_pkt_fwd_rule(struct ice_hw *hw,
1066 struct ice_fltr_list_entry *f_entry)
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;
1074 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1075 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1077 return ICE_ERR_NO_MEMORY;
1078 fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
1081 status = ICE_ERR_NO_MEMORY;
1082 goto ice_create_pkt_fwd_rule_exit;
1085 fm_entry->fltr_info = f_entry->fltr_info;
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;
1093 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
1094 ice_aqc_opc_add_sw_rules);
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);
1099 devm_kfree(ice_hw_to_dev(hw), fm_entry);
1100 goto ice_create_pkt_fwd_rule_exit;
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);
1108 /* The book keeping entries will get removed when base driver
1109 * calls remove filter AQ command
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);
1115 ice_create_pkt_fwd_rule_exit:
1116 devm_kfree(ice_hw_to_dev(hw), s_rule);
1121 * ice_update_pkt_fwd_rule
1122 * @hw: pointer to the hardware structure
1123 * @f_info: filter information for switch rule
1125 * Call AQ command to update a previously created switch rule with a
1128 static enum ice_status
1129 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
1131 struct ice_aqc_sw_rules_elem *s_rule;
1132 enum ice_status status;
1134 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1135 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
1137 return ICE_ERR_NO_MEMORY;
1139 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
1141 s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(f_info->fltr_rule_id);
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);
1147 devm_kfree(ice_hw_to_dev(hw), s_rule);
1152 * ice_update_sw_rule_bridge_mode
1153 * @hw: pointer to the HW struct
1155 * Updates unicast switch filter rules based on VEB/VEPA mode
1157 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
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 */
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;
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;
1173 /* Update unicast Tx rules to reflect the selected
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);
1187 mutex_unlock(rule_lock);
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
1199 * Call AQ command to add or update previously created VSI list with new VSI.
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
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)
1219 enum ice_status status = 0;
1220 u16 vsi_list_id = 0;
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;
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;
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
1237 struct ice_fltr_info tmp_fltr;
1238 u16 vsi_handle_arr[2];
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;
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,
1248 new_fltr->lkup_type);
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"
1259 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
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,
1269 if (!m_entry->vsi_list_info)
1270 return ICE_ERR_NO_MEMORY;
1272 /* If this entry was large action then the large action needs
1273 * to be updated to point to FWD to VSI list
1275 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
1277 ice_add_marker_act(hw, m_entry,
1278 m_entry->sw_marker_id,
1279 m_entry->lg_act_idx);
1281 u16 vsi_handle = new_fltr->vsi_handle;
1282 enum ice_adminq_opc opcode;
1284 if (!m_entry->vsi_list_info)
1287 /* A rule already exists with the new VSI being added */
1288 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
1291 /* Update the previously created VSI list set with
1292 * the new VSI ID passed in
1294 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
1295 opcode = ice_aqc_opc_update_sw_rules;
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 */
1302 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
1305 m_entry->vsi_count++;
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
1315 * Helper function to search for a given rule entry
1316 * Returns pointer to entry storing the rule if found
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)
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;
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) {
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
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.
1348 static struct ice_vsi_list_map_info *
1349 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
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;
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;
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
1376 * Adds or updates the rule lists for a given recipe
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)
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;
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);
1393 rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
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;
1402 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
1404 mutex_unlock(rule_lock);
1405 return ice_create_pkt_fwd_rule(hw, f_entry);
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);
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
1421 * The VSI list should be emptied before this function is called to remove the
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)
1428 struct ice_aqc_sw_rules_elem *s_rule;
1429 enum ice_status status;
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);
1435 return ICE_ERR_NO_MEMORY;
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);
1440 /* Free the vsi_list resource that we allocated. It is assumed that the
1441 * list is empty at this point.
1443 status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
1444 ice_aqc_opc_free_res);
1446 devm_kfree(ice_hw_to_dev(hw), s_rule);
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
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)
1461 enum ice_sw_lkup_type lkup_type;
1462 enum ice_status status = 0;
1465 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
1466 fm_list->vsi_count == 0)
1467 return ICE_ERR_PARAM;
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;
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,
1481 fm_list->vsi_count--;
1482 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
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;
1490 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
1492 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
1493 return ICE_ERR_OUT_OF_RANGE;
1495 /* Make sure VSI list is empty before removing it below */
1496 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
1498 ice_aqc_opc_update_sw_rules,
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);
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);
1514 fm_list->fltr_info = tmp_fltr_info;
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;
1522 /* Remove the VSI list since it is no longer used */
1523 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
1525 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
1526 vsi_list_id, status);
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;
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
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)
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;
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);
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);
1564 status = ICE_ERR_DOES_NOT_EXIST;
1568 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
1570 } else if (!list_elem->vsi_list_info) {
1571 status = ICE_ERR_DOES_NOT_EXIST;
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.
1579 list_elem->vsi_list_info->ref_cnt--;
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.
1587 vsi_handle = f_entry->fltr_info.vsi_handle;
1588 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
1591 /* if VSI count goes to zero after updating the VSI list */
1592 if (list_elem->vsi_count == 0)
1597 /* Remove the lookup rule */
1598 struct ice_aqc_sw_rules_elem *s_rule;
1600 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
1601 ICE_SW_RULE_RX_TX_NO_HDR_SIZE,
1604 status = ICE_ERR_NO_MEMORY;
1608 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
1609 ice_aqc_opc_remove_sw_rules);
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);
1615 /* Remove a book keeping from the list */
1616 devm_kfree(ice_hw_to_dev(hw), s_rule);
1621 list_del(&list_elem->list_entry);
1622 devm_kfree(ice_hw_to_dev(hw), list_elem);
1625 mutex_unlock(rule_lock);
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
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.
1640 enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
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;
1653 return ICE_ERR_PARAM;
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];
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;
1684 mutex_unlock(rule_lock);
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,
1691 if (m_list_itr->status)
1692 return m_list_itr->status;
1696 mutex_lock(rule_lock);
1697 /* Exit if no suitable entries were found for adding bulk switch rule */
1700 goto ice_add_mac_exit;
1703 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
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,
1710 status = ICE_ERR_NO_MEMORY;
1711 goto ice_add_mac_exit;
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];
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);
1727 /* Call AQ bulk switch rule update for all unicast addresses */
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;
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,
1740 goto ice_add_mac_exit;
1741 r_iter = (struct ice_aqc_sw_rules_elem *)
1742 ((u8 *)r_iter + (elem_sent * s_rule_size));
1745 /* Fill up rule ID based on the value returned from FW */
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;
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);
1760 status = ICE_ERR_NO_MEMORY;
1761 goto ice_add_mac_exit;
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
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);
1776 mutex_unlock(rule_lock);
1778 devm_kfree(ice_hw_to_dev(hw), s_rule);
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
1787 static enum ice_status
1788 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
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;
1798 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1799 return ICE_ERR_PARAM;
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;
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;
1809 if (new_fltr->src_id != ICE_SRC_ID_VSI)
1810 return ICE_ERR_PARAM;
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);
1819 struct ice_vsi_list_map_info *map_info = NULL;
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.
1827 map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
1831 status = ice_create_vsi_list_rule(hw,
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;
1844 status = ice_create_pkt_fwd_rule(hw, f_entry);
1846 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
1849 status = ICE_ERR_DOES_NOT_EXIST;
1852 /* reuse VSI list for new rule and increment ref_cnt */
1854 v_list_itr->vsi_list_info = map_info;
1855 map_info->ref_cnt++;
1857 v_list_itr->vsi_list_info =
1858 ice_create_vsi_list_map(hw, &vsi_handle,
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
1866 cur_fltr = &v_list_itr->fltr_info;
1867 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
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
1875 struct ice_fltr_info tmp_fltr;
1876 u16 vsi_handle_arr[2];
1879 /* Current implementation only supports reusing VSI list with
1880 * one VSI count. We should never hit below condition
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;
1890 find_first_bit(v_list_itr->vsi_list_info->vsi_map,
1893 /* A rule already exists with the new VSI being added */
1894 if (cur_handle == vsi_handle) {
1895 status = ICE_ERR_ALREADY_EXISTS;
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);
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
1913 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
1917 /* before overriding VSI list map info. decrement ref_cnt of
1920 v_list_itr->vsi_list_info->ref_cnt--;
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,
1927 v_list_itr->vsi_count++;
1931 mutex_unlock(rule_lock);
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
1940 enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
1942 struct ice_fltr_list_entry *v_list_itr;
1945 return ICE_ERR_PARAM;
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;
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
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).
1968 ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
1970 struct ice_fltr_list_entry *em_list_itr;
1972 if (!em_list || !hw)
1973 return ICE_ERR_PARAM;
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;
1979 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
1980 l_type != ICE_SW_LKUP_ETHERTYPE)
1981 return ICE_ERR_PARAM;
1983 em_list_itr->status = ice_add_rule_internal(hw, l_type,
1985 if (em_list_itr->status)
1986 return em_list_itr->status;
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
1997 ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
1999 struct ice_fltr_list_entry *em_list_itr, *tmp;
2001 if (!em_list || !hw)
2002 return ICE_ERR_PARAM;
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;
2008 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
2009 l_type != ICE_SW_LKUP_ETHERTYPE)
2010 return ICE_ERR_PARAM;
2012 em_list_itr->status = ice_remove_rule_internal(hw, l_type,
2014 if (em_list_itr->status)
2015 return em_list_itr->status;
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
2026 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
2028 if (!list_empty(rule_head)) {
2029 struct ice_fltr_mgmt_list_entry *entry;
2030 struct ice_fltr_mgmt_list_entry *tmp;
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);
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
2046 * add filter rule to set/unset given VSI as default VSI for the switch
2047 * (represented by swid)
2050 ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction)
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;
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);
2063 s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
2064 ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
2066 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2068 return ICE_ERR_NO_MEMORY;
2070 memset(&f_info, 0, sizeof(f_info));
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;
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;
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;
2087 f_info.fltr_rule_id =
2088 hw->port_info->dflt_tx_vsi_rule_id;
2092 opcode = ice_aqc_opc_add_sw_rules;
2094 opcode = ice_aqc_opc_remove_sw_rules;
2096 ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
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))
2102 u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
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;
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;
2122 devm_kfree(ice_hw_to_dev(hw), s_rule);
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
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
2136 * Returns pointer to entry storing the rule if found
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)
2142 struct ice_switch_info *sw = hw->switch_info;
2143 struct ice_fltr_mgmt_list_entry *list_itr;
2144 struct list_head *list_head;
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)
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
2163 * This function removes either a MAC filter rule or a specific VSI from a
2164 * VSI list for a multicast MAC address.
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.
2171 enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
2173 struct ice_fltr_list_entry *list_itr, *tmp;
2174 struct mutex *rule_lock; /* Lock to protect filter rule list */
2177 return ICE_ERR_PARAM;
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];
2185 if (l_type != ICE_SW_LKUP_MAC)
2186 return ICE_ERR_PARAM;
2188 vsi_handle = list_itr->fltr_info.vsi_handle;
2189 if (!ice_is_vsi_valid(hw, vsi_handle))
2190 return ICE_ERR_PARAM;
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
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;
2205 mutex_unlock(rule_lock);
2207 list_itr->status = ice_remove_rule_internal(hw,
2210 if (list_itr->status)
2211 return list_itr->status;
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
2222 ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
2224 struct ice_fltr_list_entry *v_list_itr, *tmp;
2227 return ICE_ERR_PARAM;
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;
2232 if (l_type != ICE_SW_LKUP_VLAN)
2233 return ICE_ERR_PARAM;
2234 v_list_itr->status = ice_remove_rule_internal(hw,
2237 if (v_list_itr->status)
2238 return v_list_itr->status;
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
2249 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
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))));
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
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.
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)
2276 struct ice_fltr_list_entry *tmp;
2278 /* this memory is freed up in the caller function
2279 * once filters for this VSI are removed
2281 tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
2283 return ICE_ERR_NO_MEMORY;
2285 tmp->fltr_info = *fi;
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
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);
2296 list_add(&tmp->list_entry, vsi_list_head);
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
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.
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)
2319 struct ice_fltr_mgmt_list_entry *fm_entry;
2320 enum ice_status status = 0;
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;
2326 list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
2327 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
2330 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
2332 &fm_entry->fltr_info);
2340 * ice_determine_promisc_mask
2341 * @fi: filter info to parse
2343 * Helper function to determine which ICE_PROMISC_ mask corresponds
2344 * to given filter into.
2346 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
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;
2353 if (fi->flag == ICE_FLTR_TX)
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;
2366 promisc_mask |= is_tx_fltr ?
2367 ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
2369 return promisc_mask;
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
2378 static enum ice_status
2379 ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
2380 struct list_head *v_list)
2382 struct ice_fltr_list_entry *v_list_itr, *tmp;
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;
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
2401 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
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;
2413 if (!ice_is_vsi_valid(hw, vsi_handle))
2414 return ICE_ERR_PARAM;
2416 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
2417 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
2419 recipe_id = ICE_SW_LKUP_PROMISC;
2421 rule_head = &sw->recp_list[recipe_id].filt_rules;
2422 rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
2424 INIT_LIST_HEAD(&remove_list_head);
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;
2431 if (!ice_vsi_uses_fltr(itr, vsi_handle))
2433 fltr_info = &itr->fltr_info;
2435 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
2436 vid != fltr_info->l_data.mac_vlan.vlan_id)
2439 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
2441 /* Skip if filter is not completely specified by given mask */
2442 if (fltr_promisc_mask & ~promisc_mask)
2445 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
2449 mutex_unlock(rule_lock);
2450 goto free_fltr_list;
2453 mutex_unlock(rule_lock);
2455 status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
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);
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
2474 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
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;
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);
2489 memset(&new_fltr, 0, sizeof(new_fltr));
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;
2496 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
2497 recipe_id = ICE_SW_LKUP_PROMISC;
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
2505 while (promisc_mask) {
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;
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;
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;
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;
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 */
2554 /* Need to reset this to zero for all iterations */
2557 new_fltr.flag |= ICE_FLTR_TX;
2558 new_fltr.src = hw_vsi_id;
2560 new_fltr.flag |= ICE_FLTR_RX;
2561 new_fltr.src = hw->port_info->lport;
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;
2569 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
2571 goto set_promisc_exit;
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
2585 * Configure VSI with all associated VLANs to given promiscuous mode(s)
2588 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
2589 bool rm_vlan_promisc)
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;
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,
2605 mutex_unlock(vlan_lock);
2607 goto free_fltr_list;
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);
2615 status = ice_set_vsi_promisc(hw, vsi_handle,
2616 promisc_mask, vlan_id);
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);
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
2636 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
2637 enum ice_sw_lkup_type lkup)
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;
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,
2653 mutex_unlock(rule_lock);
2655 goto free_fltr_list;
2658 case ICE_SW_LKUP_MAC:
2659 ice_remove_mac(hw, &remove_list_head);
2661 case ICE_SW_LKUP_VLAN:
2662 ice_remove_vlan(hw, &remove_list_head);
2664 case ICE_SW_LKUP_PROMISC:
2665 case ICE_SW_LKUP_PROMISC_VLAN:
2666 ice_remove_promisc(hw, lkup, &remove_list_head);
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:
2674 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
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);
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
2690 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
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);
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
2711 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
2714 struct ice_aqc_alloc_free_res_elem *buf;
2715 enum ice_status status;
2718 /* Allocate resource */
2719 buf_len = struct_size(buf, elem, 1);
2720 buf = kzalloc(buf_len, GFP_KERNEL);
2722 return ICE_ERR_NO_MEMORY;
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);
2728 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
2729 ice_aqc_opc_alloc_res, NULL);
2733 *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
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
2749 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
2752 struct ice_aqc_alloc_free_res_elem *buf;
2753 enum ice_status status;
2757 buf_len = struct_size(buf, elem, 1);
2758 buf = kzalloc(buf_len, GFP_KERNEL);
2760 return ICE_ERR_NO_MEMORY;
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);
2767 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
2768 ice_aqc_opc_free_res, NULL);
2770 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
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
2783 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
2784 * It is required to pass valid VSI handle.
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)
2790 struct ice_fltr_mgmt_list_entry *itr;
2791 enum ice_status status = 0;
2794 if (list_empty(list_head))
2796 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
2798 list_for_each_entry(itr, list_head, list_entry) {
2799 struct ice_fltr_list_entry f_entry;
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);
2812 if (!itr->vsi_list_info ||
2813 !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
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);
2825 status = ice_add_rule_internal(hw, recp_id, &f_entry);
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
2838 * Replays filters for requested VSI via vsi_handle.
2840 enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
2842 struct ice_switch_info *sw = hw->switch_info;
2843 enum ice_status status = 0;
2846 for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
2847 struct list_head *head;
2849 head = &sw->recp_list[i].filt_replay_rules;
2850 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
2858 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
2859 * @hw: pointer to the HW struct
2861 * Deletes the filter replay rules.
2863 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
2865 struct ice_switch_info *sw = hw->switch_info;
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;
2875 l_head = &sw->recp_list[i].filt_replay_rules;
2876 ice_rem_sw_rule_info(hw, l_head);