aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>2018-09-19 20:23:12 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-02 10:11:57 -0400
commit5726ca0e5eaad0f194979e66c29c1d22029f1041 (patch)
treefe663c8f698de552d93dd2a053a5bdf09ee33a34
parent024926def6ca95819442699fbecc1fe376253fb9 (diff)
ice: Expand use of VSI handles part 1/2
A VSI handle is just a number the driver maintains to uniquely identify a VSI. A VSI handle is backed by a VSI number in the hardware. When interacting when the hardware, VSI handles are converted into VSI numbers. In commit 0f9d5027a749 ("ice: Refactor VSI allocation, deletion and rebuild flow"), VSI handles were introduced but it was used only when creating and deleting VSIs. This patch is part one of two patches that expands the use of VSI handles across the rest of the driver. Also in this patch, certain parts of the code had to be refactored to correctly use VSI handles. Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c28
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c4
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.c462
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.h34
4 files changed, 328 insertions, 200 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 95588fe0e22f..b44ccdb56952 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1290,10 +1290,10 @@ int ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,
1290 return -ENOMEM; 1290 return -ENOMEM;
1291 1291
1292 tmp->fltr_info.flag = ICE_FLTR_TX; 1292 tmp->fltr_info.flag = ICE_FLTR_TX;
1293 tmp->fltr_info.src = vsi->vsi_num; 1293 tmp->fltr_info.src_id = ICE_SRC_ID_VSI;
1294 tmp->fltr_info.lkup_type = ICE_SW_LKUP_MAC; 1294 tmp->fltr_info.lkup_type = ICE_SW_LKUP_MAC;
1295 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 1295 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1296 tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num; 1296 tmp->fltr_info.vsi_handle = vsi->idx;
1297 ether_addr_copy(tmp->fltr_info.l_data.mac.mac_addr, macaddr); 1297 ether_addr_copy(tmp->fltr_info.l_data.mac.mac_addr, macaddr);
1298 1298
1299 INIT_LIST_HEAD(&tmp->list_entry); 1299 INIT_LIST_HEAD(&tmp->list_entry);
@@ -1394,8 +1394,8 @@ int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid)
1394 tmp->fltr_info.lkup_type = ICE_SW_LKUP_VLAN; 1394 tmp->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
1395 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 1395 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1396 tmp->fltr_info.flag = ICE_FLTR_TX; 1396 tmp->fltr_info.flag = ICE_FLTR_TX;
1397 tmp->fltr_info.src = vsi->vsi_num; 1397 tmp->fltr_info.src_id = ICE_SRC_ID_VSI;
1398 tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num; 1398 tmp->fltr_info.vsi_handle = vsi->idx;
1399 tmp->fltr_info.l_data.vlan.vlan_id = vid; 1399 tmp->fltr_info.l_data.vlan.vlan_id = vid;
1400 1400
1401 INIT_LIST_HEAD(&tmp->list_entry); 1401 INIT_LIST_HEAD(&tmp->list_entry);
@@ -1431,11 +1431,11 @@ int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
1431 return -ENOMEM; 1431 return -ENOMEM;
1432 1432
1433 list->fltr_info.lkup_type = ICE_SW_LKUP_VLAN; 1433 list->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
1434 list->fltr_info.fwd_id.vsi_id = vsi->vsi_num; 1434 list->fltr_info.vsi_handle = vsi->idx;
1435 list->fltr_info.fltr_act = ICE_FWD_TO_VSI; 1435 list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1436 list->fltr_info.l_data.vlan.vlan_id = vid; 1436 list->fltr_info.l_data.vlan.vlan_id = vid;
1437 list->fltr_info.flag = ICE_FLTR_TX; 1437 list->fltr_info.flag = ICE_FLTR_TX;
1438 list->fltr_info.src = vsi->vsi_num; 1438 list->fltr_info.src_id = ICE_SRC_ID_VSI;
1439 1439
1440 INIT_LIST_HEAD(&list->list_entry); 1440 INIT_LIST_HEAD(&list->list_entry);
1441 list_add(&list->list_entry, &tmp_add_list); 1441 list_add(&list->list_entry, &tmp_add_list);
@@ -1636,9 +1636,8 @@ int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
1636 ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL; 1636 ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
1637 1637
1638 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); 1638 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
1639 ctxt.vsi_num = vsi->vsi_num;
1640 1639
1641 status = ice_aq_update_vsi(hw, &ctxt, NULL); 1640 status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
1642 if (status) { 1641 if (status) {
1643 dev_err(dev, "update VSI for VLAN insert failed, err %d aq_err %d\n", 1642 dev_err(dev, "update VSI for VLAN insert failed, err %d aq_err %d\n",
1644 status, hw->adminq.sq_last_status); 1643 status, hw->adminq.sq_last_status);
@@ -1677,9 +1676,8 @@ int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
1677 ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL; 1676 ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
1678 1677
1679 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); 1678 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
1680 ctxt.vsi_num = vsi->vsi_num;
1681 1679
1682 status = ice_aq_update_vsi(hw, &ctxt, NULL); 1680 status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
1683 if (status) { 1681 if (status) {
1684 dev_err(dev, "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n", 1682 dev_err(dev, "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n",
1685 ena, status, hw->adminq.sq_last_status); 1683 ena, status, hw->adminq.sq_last_status);
@@ -1829,11 +1827,11 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena)
1829 1827
1830 ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID | 1828 ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID |
1831 ICE_AQ_VSI_PROP_SW_VALID); 1829 ICE_AQ_VSI_PROP_SW_VALID);
1832 ctxt->vsi_num = vsi->vsi_num; 1830
1833 status = ice_aq_update_vsi(&vsi->back->hw, ctxt, NULL); 1831 status = ice_update_vsi(&vsi->back->hw, vsi->idx, ctxt, NULL);
1834 if (status) { 1832 if (status) {
1835 netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI %d failed, err = %d, aq_err = %d\n", 1833 netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %d, aq_err = %d\n",
1836 ena ? "Ena" : "Dis", vsi->vsi_num, status, 1834 ena ? "Ena" : "Dis", vsi->idx, vsi->vsi_num, status,
1837 vsi->back->hw.adminq.sq_last_status); 1835 vsi->back->hw.adminq.sq_last_status);
1838 goto err_out; 1836 goto err_out;
1839 } 1837 }
@@ -2267,7 +2265,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
2267 ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx); 2265 ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
2268 pf->num_avail_msix += vsi->num_q_vectors; 2266 pf->num_avail_msix += vsi->num_q_vectors;
2269 2267
2270 ice_remove_vsi_fltr(&pf->hw, vsi->vsi_num); 2268 ice_remove_vsi_fltr(&pf->hw, vsi->idx);
2271 ice_vsi_delete(vsi); 2269 ice_vsi_delete(vsi);
2272 ice_vsi_free_q_vectors(vsi); 2270 ice_vsi_free_q_vectors(vsi);
2273 ice_vsi_clear_rings(vsi); 2271 ice_vsi_clear_rings(vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index a3513acd272b..5fc5455e3a4d 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3426,9 +3426,9 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode)
3426 else 3426 else
3427 /* change from VEB to VEPA mode */ 3427 /* change from VEB to VEPA mode */
3428 ctxt.info.sw_flags &= ~ICE_AQ_VSI_SW_FLAG_ALLOW_LB; 3428 ctxt.info.sw_flags &= ~ICE_AQ_VSI_SW_FLAG_ALLOW_LB;
3429 ctxt.vsi_num = vsi->vsi_num;
3430 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SW_VALID); 3429 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SW_VALID);
3431 status = ice_aq_update_vsi(hw, &ctxt, NULL); 3430
3431 status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
3432 if (status) { 3432 if (status) {
3433 dev_err(dev, "update VSI for bridge mode failed, bmode = %d err %d aq_err %d\n", 3433 dev_err(dev, "update VSI for bridge mode failed, bmode = %d err %d aq_err %d\n",
3434 bmode, status, hw->adminq.sq_last_status); 3434 bmode, status, hw->adminq.sq_last_status);
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 65b4e1cca6be..4e3ed541db3d 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -247,7 +247,7 @@ ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
247 * 247 *
248 * Update VSI context in the hardware (0x0211) 248 * Update VSI context in the hardware (0x0211)
249 */ 249 */
250enum ice_status 250static enum ice_status
251ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 251ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
252 struct ice_sq_cd *cd) 252 struct ice_sq_cd *cd)
253{ 253{
@@ -277,65 +277,6 @@ ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
277} 277}
278 278
279/** 279/**
280 * ice_update_fltr_vsi_map - update given filter VSI map
281 * @list_head: list for which filters needs to be updated
282 * @list_lock: filter lock which needs to be updated
283 * @old_vsi_num: old VSI HW id
284 * @new_vsi_num: new VSI HW id
285 *
286 * update the VSI map for a given filter list
287 */
288static void
289ice_update_fltr_vsi_map(struct list_head *list_head,
290 struct mutex *list_lock, u16 old_vsi_num,
291 u16 new_vsi_num)
292{
293 struct ice_fltr_mgmt_list_entry *itr;
294
295 mutex_lock(list_lock);
296 if (list_empty(list_head))
297 goto exit_update_map;
298
299 list_for_each_entry(itr, list_head, list_entry) {
300 if (itr->vsi_list_info &&
301 test_bit(old_vsi_num, itr->vsi_list_info->vsi_map)) {
302 clear_bit(old_vsi_num, itr->vsi_list_info->vsi_map);
303 set_bit(new_vsi_num, itr->vsi_list_info->vsi_map);
304 } else if (itr->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
305 itr->fltr_info.fwd_id.vsi_id == old_vsi_num) {
306 itr->fltr_info.fwd_id.vsi_id = new_vsi_num;
307 itr->fltr_info.src = new_vsi_num;
308 }
309 }
310exit_update_map:
311 mutex_unlock(list_lock);
312}
313
314/**
315 * ice_update_all_fltr_vsi_map - update all filters VSI map
316 * @hw: pointer to the hardware structure
317 * @old_vsi_num: old VSI HW id
318 * @new_vsi_num: new VSI HW id
319 *
320 * update all filters VSI map
321 */
322static void
323ice_update_all_fltr_vsi_map(struct ice_hw *hw, u16 old_vsi_num, u16 new_vsi_num)
324{
325 struct ice_switch_info *sw = hw->switch_info;
326 u8 i;
327
328 for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
329 struct list_head *head = &sw->recp_list[i].filt_rules;
330 struct mutex *lock; /* Lock to protect filter rule list */
331
332 lock = &sw->recp_list[i].filt_rule_lock;
333 ice_update_fltr_vsi_map(head, lock, old_vsi_num,
334 new_vsi_num);
335 }
336}
337
338/**
339 * ice_is_vsi_valid - check whether the VSI is valid or not 280 * ice_is_vsi_valid - check whether the VSI is valid or not
340 * @hw: pointer to the hw struct 281 * @hw: pointer to the hw struct
341 * @vsi_handle: VSI handle 282 * @vsi_handle: VSI handle
@@ -440,12 +381,8 @@ ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
440 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 381 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
441 } else { 382 } else {
442 /* update with new HW VSI num */ 383 /* update with new HW VSI num */
443 if (tmp_vsi_ctx->vsi_num != vsi_ctx->vsi_num) { 384 if (tmp_vsi_ctx->vsi_num != vsi_ctx->vsi_num)
444 /* update all filter lists with new HW VSI num */
445 ice_update_all_fltr_vsi_map(hw, tmp_vsi_ctx->vsi_num,
446 vsi_ctx->vsi_num);
447 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 385 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
448 }
449 } 386 }
450 387
451 return status; 388 return status;
@@ -477,6 +414,25 @@ ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
477} 414}
478 415
479/** 416/**
417 * ice_update_vsi
418 * @hw: pointer to the hw struct
419 * @vsi_handle: unique VSI handle
420 * @vsi_ctx: pointer to a VSI context struct
421 * @cd: pointer to command details structure or NULL
422 *
423 * Update VSI context in the hardware
424 */
425enum ice_status
426ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
427 struct ice_sq_cd *cd)
428{
429 if (!ice_is_vsi_valid(hw, vsi_handle))
430 return ICE_ERR_PARAM;
431 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
432 return ice_aq_update_vsi(hw, vsi_ctx, cd);
433}
434
435/**
480 * ice_aq_alloc_free_vsi_list 436 * ice_aq_alloc_free_vsi_list
481 * @hw: pointer to the hw struct 437 * @hw: pointer to the hw struct
482 * @vsi_list_id: VSI list id returned or used for lookup 438 * @vsi_list_id: VSI list id returned or used for lookup
@@ -716,7 +672,7 @@ ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
716 672
717 switch (f_info->fltr_act) { 673 switch (f_info->fltr_act) {
718 case ICE_FWD_TO_VSI: 674 case ICE_FWD_TO_VSI:
719 act |= (f_info->fwd_id.vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 675 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
720 ICE_SINGLE_ACT_VSI_ID_M; 676 ICE_SINGLE_ACT_VSI_ID_M;
721 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 677 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
722 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 678 act |= ICE_SINGLE_ACT_VSI_FORWARDING |
@@ -832,8 +788,8 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
832 enum ice_status status; 788 enum ice_status status;
833 u16 lg_act_size; 789 u16 lg_act_size;
834 u16 rules_size; 790 u16 rules_size;
835 u16 vsi_info;
836 u32 act; 791 u32 act;
792 u16 id;
837 793
838 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 794 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
839 return ICE_ERR_PARAM; 795 return ICE_ERR_PARAM;
@@ -859,12 +815,11 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
859 /* First action VSI forwarding or VSI list forwarding depending on how 815 /* First action VSI forwarding or VSI list forwarding depending on how
860 * many VSIs 816 * many VSIs
861 */ 817 */
862 vsi_info = (m_ent->vsi_count > 1) ? 818 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
863 m_ent->fltr_info.fwd_id.vsi_list_id : 819 m_ent->fltr_info.fwd_id.hw_vsi_id;
864 m_ent->fltr_info.fwd_id.vsi_id;
865 820
866 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 821 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
867 act |= (vsi_info << ICE_LG_ACT_VSI_LIST_ID_S) & 822 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
868 ICE_LG_ACT_VSI_LIST_ID_M; 823 ICE_LG_ACT_VSI_LIST_ID_M;
869 if (m_ent->vsi_count > 1) 824 if (m_ent->vsi_count > 1)
870 act |= ICE_LG_ACT_VSI_LIST; 825 act |= ICE_LG_ACT_VSI_LIST;
@@ -917,15 +872,15 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
917/** 872/**
918 * ice_create_vsi_list_map 873 * ice_create_vsi_list_map
919 * @hw: pointer to the hardware structure 874 * @hw: pointer to the hardware structure
920 * @vsi_array: array of VSIs to form a VSI list 875 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
921 * @num_vsi: num VSI in the array 876 * @num_vsi: number of VSI handles in the array
922 * @vsi_list_id: VSI list id generated as part of allocate resource 877 * @vsi_list_id: VSI list id generated as part of allocate resource
923 * 878 *
924 * Helper function to create a new entry of VSI list id to VSI mapping 879 * Helper function to create a new entry of VSI list id to VSI mapping
925 * using the given VSI list id 880 * using the given VSI list id
926 */ 881 */
927static struct ice_vsi_list_map_info * 882static struct ice_vsi_list_map_info *
928ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi, 883ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
929 u16 vsi_list_id) 884 u16 vsi_list_id)
930{ 885{
931 struct ice_switch_info *sw = hw->switch_info; 886 struct ice_switch_info *sw = hw->switch_info;
@@ -937,9 +892,9 @@ ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
937 return NULL; 892 return NULL;
938 893
939 v_map->vsi_list_id = vsi_list_id; 894 v_map->vsi_list_id = vsi_list_id;
940 895 v_map->ref_cnt = 1;
941 for (i = 0; i < num_vsi; i++) 896 for (i = 0; i < num_vsi; i++)
942 set_bit(vsi_array[i], v_map->vsi_map); 897 set_bit(vsi_handle_arr[i], v_map->vsi_map);
943 898
944 list_add(&v_map->list_entry, &sw->vsi_list_map_head); 899 list_add(&v_map->list_entry, &sw->vsi_list_map_head);
945 return v_map; 900 return v_map;
@@ -948,8 +903,8 @@ ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
948/** 903/**
949 * ice_update_vsi_list_rule 904 * ice_update_vsi_list_rule
950 * @hw: pointer to the hardware structure 905 * @hw: pointer to the hardware structure
951 * @vsi_array: array of VSIs to form a VSI list 906 * @vsi_handle_arr: array of VSI handles to form a VSI list
952 * @num_vsi: num VSI in the array 907 * @num_vsi: number of VSI handles in the array
953 * @vsi_list_id: VSI list id generated as part of allocate resource 908 * @vsi_list_id: VSI list id generated as part of allocate resource
954 * @remove: Boolean value to indicate if this is a remove action 909 * @remove: Boolean value to indicate if this is a remove action
955 * @opc: switch rules population command type - pass in the command opcode 910 * @opc: switch rules population command type - pass in the command opcode
@@ -959,7 +914,7 @@ ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
959 * using the given VSI list id 914 * using the given VSI list id
960 */ 915 */
961static enum ice_status 916static enum ice_status
962ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi, 917ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
963 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 918 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
964 enum ice_sw_lkup_type lkup_type) 919 enum ice_sw_lkup_type lkup_type)
965{ 920{
@@ -990,9 +945,15 @@ ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
990 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 945 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
991 if (!s_rule) 946 if (!s_rule)
992 return ICE_ERR_NO_MEMORY; 947 return ICE_ERR_NO_MEMORY;
993 948 for (i = 0; i < num_vsi; i++) {
994 for (i = 0; i < num_vsi; i++) 949 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
995 s_rule->pdata.vsi_list.vsi[i] = cpu_to_le16(vsi_array[i]); 950 status = ICE_ERR_PARAM;
951 goto exit;
952 }
953 /* AQ call requires hw_vsi_id(s) */
954 s_rule->pdata.vsi_list.vsi[i] =
955 cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
956 }
996 957
997 s_rule->type = cpu_to_le16(type); 958 s_rule->type = cpu_to_le16(type);
998 s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi); 959 s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi);
@@ -1000,6 +961,7 @@ ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
1000 961
1001 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 962 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
1002 963
964exit:
1003 devm_kfree(ice_hw_to_dev(hw), s_rule); 965 devm_kfree(ice_hw_to_dev(hw), s_rule);
1004 return status; 966 return status;
1005} 967}
@@ -1007,21 +969,16 @@ ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
1007/** 969/**
1008 * ice_create_vsi_list_rule - Creates and populates a VSI list rule 970 * ice_create_vsi_list_rule - Creates and populates a VSI list rule
1009 * @hw: pointer to the hw struct 971 * @hw: pointer to the hw struct
1010 * @vsi_array: array of VSIs to form a VSI list 972 * @vsi_handle_arr: array of VSI handles to form a VSI list
1011 * @num_vsi: number of VSIs in the array 973 * @num_vsi: number of VSI handles in the array
1012 * @vsi_list_id: stores the ID of the VSI list to be created 974 * @vsi_list_id: stores the ID of the VSI list to be created
1013 * @lkup_type: switch rule filter's lookup type 975 * @lkup_type: switch rule filter's lookup type
1014 */ 976 */
1015static enum ice_status 977static enum ice_status
1016ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi, 978ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
1017 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 979 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
1018{ 980{
1019 enum ice_status status; 981 enum ice_status status;
1020 int i;
1021
1022 for (i = 0; i < num_vsi; i++)
1023 if (vsi_array[i] >= ICE_MAX_VSI)
1024 return ICE_ERR_OUT_OF_RANGE;
1025 982
1026 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 983 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
1027 ice_aqc_opc_alloc_res); 984 ice_aqc_opc_alloc_res);
@@ -1029,9 +986,9 @@ ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_array, u16 num_vsi,
1029 return status; 986 return status;
1030 987
1031 /* Update the newly created VSI list to include the specified VSIs */ 988 /* Update the newly created VSI list to include the specified VSIs */
1032 return ice_update_vsi_list_rule(hw, vsi_array, num_vsi, *vsi_list_id, 989 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
1033 false, ice_aqc_opc_add_sw_rules, 990 *vsi_list_id, false,
1034 lkup_type); 991 ice_aqc_opc_add_sw_rules, lkup_type);
1035} 992}
1036 993
1037/** 994/**
@@ -1217,15 +1174,15 @@ ice_add_update_vsi_list(struct ice_hw *hw,
1217 * new VSIs. 1174 * new VSIs.
1218 */ 1175 */
1219 struct ice_fltr_info tmp_fltr; 1176 struct ice_fltr_info tmp_fltr;
1220 u16 vsi_id_arr[2]; 1177 u16 vsi_handle_arr[2];
1221 1178
1222 /* A rule already exists with the new VSI being added */ 1179 /* A rule already exists with the new VSI being added */
1223 if (cur_fltr->fwd_id.vsi_id == new_fltr->fwd_id.vsi_id) 1180 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
1224 return ICE_ERR_ALREADY_EXISTS; 1181 return ICE_ERR_ALREADY_EXISTS;
1225 1182
1226 vsi_id_arr[0] = cur_fltr->fwd_id.vsi_id; 1183 vsi_handle_arr[0] = cur_fltr->vsi_handle;
1227 vsi_id_arr[1] = new_fltr->fwd_id.vsi_id; 1184 vsi_handle_arr[1] = new_fltr->vsi_handle;
1228 status = ice_create_vsi_list_rule(hw, &vsi_id_arr[0], 2, 1185 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
1229 &vsi_list_id, 1186 &vsi_list_id,
1230 new_fltr->lkup_type); 1187 new_fltr->lkup_type);
1231 if (status) 1188 if (status)
@@ -1245,7 +1202,7 @@ ice_add_update_vsi_list(struct ice_hw *hw,
1245 cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 1202 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
1246 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 1203 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1247 m_entry->vsi_list_info = 1204 m_entry->vsi_list_info =
1248 ice_create_vsi_list_map(hw, &vsi_id_arr[0], 2, 1205 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
1249 vsi_list_id); 1206 vsi_list_id);
1250 1207
1251 /* If this entry was large action then the large action needs 1208 /* If this entry was large action then the large action needs
@@ -1257,11 +1214,11 @@ ice_add_update_vsi_list(struct ice_hw *hw,
1257 m_entry->sw_marker_id, 1214 m_entry->sw_marker_id,
1258 m_entry->lg_act_idx); 1215 m_entry->lg_act_idx);
1259 } else { 1216 } else {
1260 u16 vsi_id = new_fltr->fwd_id.vsi_id; 1217 u16 vsi_handle = new_fltr->vsi_handle;
1261 enum ice_adminq_opc opcode; 1218 enum ice_adminq_opc opcode;
1262 1219
1263 /* A rule already exists with the new VSI being added */ 1220 /* A rule already exists with the new VSI being added */
1264 if (test_bit(vsi_id, m_entry->vsi_list_info->vsi_map)) 1221 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
1265 return 0; 1222 return 0;
1266 1223
1267 /* Update the previously created VSI list set with 1224 /* Update the previously created VSI list set with
@@ -1270,12 +1227,12 @@ ice_add_update_vsi_list(struct ice_hw *hw,
1270 vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 1227 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
1271 opcode = ice_aqc_opc_update_sw_rules; 1228 opcode = ice_aqc_opc_update_sw_rules;
1272 1229
1273 status = ice_update_vsi_list_rule(hw, &vsi_id, 1, vsi_list_id, 1230 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
1274 false, opcode, 1231 vsi_list_id, false, opcode,
1275 new_fltr->lkup_type); 1232 new_fltr->lkup_type);
1276 /* update VSI list mapping info with new VSI id */ 1233 /* update VSI list mapping info with new VSI id */
1277 if (!status) 1234 if (!status)
1278 set_bit(vsi_id, m_entry->vsi_list_info->vsi_map); 1235 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
1279 } 1236 }
1280 if (!status) 1237 if (!status)
1281 m_entry->vsi_count++; 1238 m_entry->vsi_count++;
@@ -1311,6 +1268,39 @@ ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
1311} 1268}
1312 1269
1313/** 1270/**
1271 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
1272 * @hw: pointer to the hardware structure
1273 * @recp_id: lookup type for which VSI lists needs to be searched
1274 * @vsi_handle: VSI handle to be found in VSI list
1275 * @vsi_list_id: VSI list id found containing vsi_handle
1276 *
1277 * Helper function to search a VSI list with single entry containing given VSI
1278 * handle element. This can be extended further to search VSI list with more
1279 * than 1 vsi_count. Returns pointer to VSI list entry if found.
1280 */
1281static struct ice_vsi_list_map_info *
1282ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
1283 u16 *vsi_list_id)
1284{
1285 struct ice_vsi_list_map_info *map_info = NULL;
1286 struct ice_switch_info *sw = hw->switch_info;
1287 struct ice_fltr_mgmt_list_entry *list_itr;
1288 struct list_head *list_head;
1289
1290 list_head = &sw->recp_list[recp_id].filt_rules;
1291 list_for_each_entry(list_itr, list_head, list_entry) {
1292 if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
1293 map_info = list_itr->vsi_list_info;
1294 if (test_bit(vsi_handle, map_info->vsi_map)) {
1295 *vsi_list_id = map_info->vsi_list_id;
1296 return map_info;
1297 }
1298 }
1299 }
1300 return NULL;
1301}
1302
1303/**
1314 * ice_add_rule_internal - add rule for a given lookup type 1304 * ice_add_rule_internal - add rule for a given lookup type
1315 * @hw: pointer to the hardware structure 1305 * @hw: pointer to the hardware structure
1316 * @recp_id: lookup type (recipe id) for which rule has to be added 1306 * @recp_id: lookup type (recipe id) for which rule has to be added
@@ -1328,6 +1318,11 @@ ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
1328 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1318 struct mutex *rule_lock; /* Lock to protect filter rule list */
1329 enum ice_status status = 0; 1319 enum ice_status status = 0;
1330 1320
1321 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1322 return ICE_ERR_PARAM;
1323 f_entry->fltr_info.fwd_id.hw_vsi_id =
1324 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1325
1331 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 1326 rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1332 1327
1333 mutex_lock(rule_lock); 1328 mutex_lock(rule_lock);
@@ -1335,7 +1330,7 @@ ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
1335 if (new_fltr->flag & ICE_FLTR_RX) 1330 if (new_fltr->flag & ICE_FLTR_RX)
1336 new_fltr->src = hw->port_info->lport; 1331 new_fltr->src = hw->port_info->lport;
1337 else if (new_fltr->flag & ICE_FLTR_TX) 1332 else if (new_fltr->flag & ICE_FLTR_TX)
1338 new_fltr->src = f_entry->fltr_info.fwd_id.vsi_id; 1333 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
1339 1334
1340 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr); 1335 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
1341 if (!m_entry) { 1336 if (!m_entry) {
@@ -1388,12 +1383,12 @@ ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
1388/** 1383/**
1389 * ice_rem_update_vsi_list 1384 * ice_rem_update_vsi_list
1390 * @hw: pointer to the hardware structure 1385 * @hw: pointer to the hardware structure
1391 * @vsi_id: ID of the VSI to remove 1386 * @vsi_handle: VSI handle of the VSI to remove
1392 * @fm_list: filter management entry for which the VSI list management needs to 1387 * @fm_list: filter management entry for which the VSI list management needs to
1393 * be done 1388 * be done
1394 */ 1389 */
1395static enum ice_status 1390static enum ice_status
1396ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_id, 1391ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
1397 struct ice_fltr_mgmt_list_entry *fm_list) 1392 struct ice_fltr_mgmt_list_entry *fm_list)
1398{ 1393{
1399 enum ice_sw_lkup_type lkup_type; 1394 enum ice_sw_lkup_type lkup_type;
@@ -1405,33 +1400,31 @@ ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_id,
1405 return ICE_ERR_PARAM; 1400 return ICE_ERR_PARAM;
1406 1401
1407 /* A rule with the VSI being removed does not exist */ 1402 /* A rule with the VSI being removed does not exist */
1408 if (!test_bit(vsi_id, fm_list->vsi_list_info->vsi_map)) 1403 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
1409 return ICE_ERR_DOES_NOT_EXIST; 1404 return ICE_ERR_DOES_NOT_EXIST;
1410 1405
1411 lkup_type = fm_list->fltr_info.lkup_type; 1406 lkup_type = fm_list->fltr_info.lkup_type;
1412 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 1407 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
1413 1408 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
1414 status = ice_update_vsi_list_rule(hw, &vsi_id, 1, vsi_list_id, true,
1415 ice_aqc_opc_update_sw_rules, 1409 ice_aqc_opc_update_sw_rules,
1416 lkup_type); 1410 lkup_type);
1417 if (status) 1411 if (status)
1418 return status; 1412 return status;
1419 1413
1420 fm_list->vsi_count--; 1414 fm_list->vsi_count--;
1421 clear_bit(vsi_id, fm_list->vsi_list_info->vsi_map); 1415 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
1422 1416
1423 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 1417 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
1424 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 1418 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
1425 struct ice_vsi_list_map_info *vsi_list_info = 1419 struct ice_vsi_list_map_info *vsi_list_info =
1426 fm_list->vsi_list_info; 1420 fm_list->vsi_list_info;
1427 u16 rem_vsi_id; 1421 u16 rem_vsi_handle;
1428 1422
1429 rem_vsi_id = find_first_bit(vsi_list_info->vsi_map, 1423 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
1430 ICE_MAX_VSI); 1424 ICE_MAX_VSI);
1431 if (rem_vsi_id == ICE_MAX_VSI) 1425 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
1432 return ICE_ERR_OUT_OF_RANGE; 1426 return ICE_ERR_OUT_OF_RANGE;
1433 1427 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
1434 status = ice_update_vsi_list_rule(hw, &rem_vsi_id, 1,
1435 vsi_list_id, true, 1428 vsi_list_id, true,
1436 ice_aqc_opc_update_sw_rules, 1429 ice_aqc_opc_update_sw_rules,
1437 lkup_type); 1430 lkup_type);
@@ -1445,7 +1438,9 @@ ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_id,
1445 1438
1446 /* Change the list entry action from VSI_LIST to VSI */ 1439 /* Change the list entry action from VSI_LIST to VSI */
1447 fm_list->fltr_info.fltr_act = ICE_FWD_TO_VSI; 1440 fm_list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1448 fm_list->fltr_info.fwd_id.vsi_id = rem_vsi_id; 1441 fm_list->fltr_info.fwd_id.hw_vsi_id =
1442 ice_get_hw_vsi_num(hw, rem_vsi_handle);
1443 fm_list->fltr_info.vsi_handle = rem_vsi_handle;
1449 1444
1450 list_del(&vsi_list_info->list_entry); 1445 list_del(&vsi_list_info->list_entry);
1451 devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 1446 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
@@ -1470,7 +1465,12 @@ ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
1470 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1465 struct mutex *rule_lock; /* Lock to protect filter rule list */
1471 enum ice_status status = 0; 1466 enum ice_status status = 0;
1472 bool remove_rule = false; 1467 bool remove_rule = false;
1473 u16 vsi_id; 1468 u16 vsi_handle;
1469
1470 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1471 return ICE_ERR_PARAM;
1472 f_entry->fltr_info.fwd_id.hw_vsi_id =
1473 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1474 1474
1475 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 1475 rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
1476 mutex_lock(rule_lock); 1476 mutex_lock(rule_lock);
@@ -1482,9 +1482,14 @@ ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
1482 1482
1483 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 1483 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
1484 remove_rule = true; 1484 remove_rule = true;
1485 } else if (!list_elem->vsi_list_info) {
1486 status = ICE_ERR_DOES_NOT_EXIST;
1487 goto exit;
1485 } else { 1488 } else {
1486 vsi_id = f_entry->fltr_info.fwd_id.vsi_id; 1489 if (list_elem->vsi_list_info->ref_cnt > 1)
1487 status = ice_rem_update_vsi_list(hw, vsi_id, list_elem); 1490 list_elem->vsi_list_info->ref_cnt--;
1491 vsi_handle = f_entry->fltr_info.vsi_handle;
1492 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
1488 if (status) 1493 if (status)
1489 goto exit; 1494 goto exit;
1490 /* if vsi count goes to zero after updating the vsi list */ 1495 /* if vsi count goes to zero after updating the vsi list */
@@ -1556,8 +1561,19 @@ ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
1556 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 1561 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
1557 list_for_each_entry(m_list_itr, m_list, list_entry) { 1562 list_for_each_entry(m_list_itr, m_list, list_entry) {
1558 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 1563 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
1564 u16 vsi_handle;
1565 u16 hw_vsi_id;
1559 1566
1560 m_list_itr->fltr_info.flag = ICE_FLTR_TX; 1567 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
1568 vsi_handle = m_list_itr->fltr_info.vsi_handle;
1569 if (!ice_is_vsi_valid(hw, vsi_handle))
1570 return ICE_ERR_PARAM;
1571 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
1572 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
1573 /* update the src in case it is vsi num */
1574 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
1575 return ICE_ERR_PARAM;
1576 m_list_itr->fltr_info.src = hw_vsi_id;
1561 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 1577 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
1562 is_zero_ether_addr(add)) 1578 is_zero_ether_addr(add))
1563 return ICE_ERR_PARAM; 1579 return ICE_ERR_PARAM;
@@ -1676,57 +1692,145 @@ static enum ice_status
1676ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) 1692ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
1677{ 1693{
1678 struct ice_switch_info *sw = hw->switch_info; 1694 struct ice_switch_info *sw = hw->switch_info;
1679 struct ice_fltr_info *new_fltr, *cur_fltr;
1680 struct ice_fltr_mgmt_list_entry *v_list_itr; 1695 struct ice_fltr_mgmt_list_entry *v_list_itr;
1696 struct ice_fltr_info *new_fltr, *cur_fltr;
1697 enum ice_sw_lkup_type lkup_type;
1698 u16 vsi_list_id = 0, vsi_handle;
1681 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1699 struct mutex *rule_lock; /* Lock to protect filter rule list */
1682 enum ice_status status = 0; 1700 enum ice_status status = 0;
1683 1701
1702 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
1703 return ICE_ERR_PARAM;
1704
1705 f_entry->fltr_info.fwd_id.hw_vsi_id =
1706 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
1684 new_fltr = &f_entry->fltr_info; 1707 new_fltr = &f_entry->fltr_info;
1708
1685 /* VLAN id should only be 12 bits */ 1709 /* VLAN id should only be 12 bits */
1686 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 1710 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
1687 return ICE_ERR_PARAM; 1711 return ICE_ERR_PARAM;
1688 1712
1713 if (new_fltr->src_id != ICE_SRC_ID_VSI)
1714 return ICE_ERR_PARAM;
1715
1716 new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
1717 lkup_type = new_fltr->lkup_type;
1718 vsi_handle = new_fltr->vsi_handle;
1689 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 1719 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
1690 mutex_lock(rule_lock); 1720 mutex_lock(rule_lock);
1691 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr); 1721 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
1692 if (!v_list_itr) { 1722 if (!v_list_itr) {
1693 u16 vsi_id = ICE_VSI_INVAL_ID; 1723 struct ice_vsi_list_map_info *map_info = NULL;
1694 u16 vsi_list_id = 0;
1695 1724
1696 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 1725 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
1697 enum ice_sw_lkup_type lkup_type = new_fltr->lkup_type; 1726 /* All VLAN pruning rules use a VSI list. Check if
1698 1727 * there is already a VSI list containing VSI that we
1699 /* All VLAN pruning rules use a VSI list. 1728 * want to add. If found, use the same vsi_list_id for
1700 * Convert the action to forwarding to a VSI list. 1729 * this new VLAN rule or else create a new list.
1701 */ 1730 */
1702 vsi_id = new_fltr->fwd_id.vsi_id; 1731 map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
1703 status = ice_create_vsi_list_rule(hw, &vsi_id, 1, 1732 vsi_handle,
1704 &vsi_list_id, 1733 &vsi_list_id);
1705 lkup_type); 1734 if (!map_info) {
1706 if (status) 1735 status = ice_create_vsi_list_rule(hw,
1707 goto exit; 1736 &vsi_handle,
1737 1,
1738 &vsi_list_id,
1739 lkup_type);
1740 if (status)
1741 goto exit;
1742 }
1743 /* Convert the action to forwarding to a VSI list. */
1708 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 1744 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
1709 new_fltr->fwd_id.vsi_list_id = vsi_list_id; 1745 new_fltr->fwd_id.vsi_list_id = vsi_list_id;
1710 } 1746 }
1711 1747
1712 status = ice_create_pkt_fwd_rule(hw, f_entry); 1748 status = ice_create_pkt_fwd_rule(hw, f_entry);
1713 if (!status && vsi_id != ICE_VSI_INVAL_ID) { 1749 if (!status) {
1714 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, 1750 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
1715 new_fltr); 1751 new_fltr);
1716 if (!v_list_itr) { 1752 if (!v_list_itr) {
1717 status = ICE_ERR_DOES_NOT_EXIST; 1753 status = ICE_ERR_DOES_NOT_EXIST;
1718 goto exit; 1754 goto exit;
1719 } 1755 }
1720 v_list_itr->vsi_list_info = 1756 /* reuse VSI list for new rule and increment ref_cnt */
1721 ice_create_vsi_list_map(hw, &vsi_id, 1, 1757 if (map_info) {
1722 vsi_list_id); 1758 v_list_itr->vsi_list_info = map_info;
1759 map_info->ref_cnt++;
1760 } else {
1761 v_list_itr->vsi_list_info =
1762 ice_create_vsi_list_map(hw, &vsi_handle,
1763 1, vsi_list_id);
1764 }
1723 } 1765 }
1766 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
1767 /* Update existing VSI list to add new VSI id only if it used
1768 * by one VLAN rule.
1769 */
1770 cur_fltr = &v_list_itr->fltr_info;
1771 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
1772 new_fltr);
1773 } else {
1774 /* If VLAN rule exists and VSI list being used by this rule is
1775 * referenced by more than 1 VLAN rule. Then create a new VSI
1776 * list appending previous VSI with new VSI and update existing
1777 * VLAN rule to point to new VSI list id
1778 */
1779 struct ice_fltr_info tmp_fltr;
1780 u16 vsi_handle_arr[2];
1781 u16 cur_handle;
1724 1782
1725 goto exit; 1783 /* Current implementation only supports reusing VSI list with
1726 } 1784 * one VSI count. We should never hit below condition
1785 */
1786 if (v_list_itr->vsi_count > 1 &&
1787 v_list_itr->vsi_list_info->ref_cnt > 1) {
1788 ice_debug(hw, ICE_DBG_SW,
1789 "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
1790 status = ICE_ERR_CFG;
1791 goto exit;
1792 }
1727 1793
1728 cur_fltr = &v_list_itr->fltr_info; 1794 cur_handle =
1729 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, new_fltr); 1795 find_first_bit(v_list_itr->vsi_list_info->vsi_map,
1796 ICE_MAX_VSI);
1797
1798 /* A rule already exists with the new VSI being added */
1799 if (cur_handle == vsi_handle) {
1800 status = ICE_ERR_ALREADY_EXISTS;
1801 goto exit;
1802 }
1803
1804 vsi_handle_arr[0] = cur_handle;
1805 vsi_handle_arr[1] = vsi_handle;
1806 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
1807 &vsi_list_id, lkup_type);
1808 if (status)
1809 goto exit;
1810
1811 tmp_fltr = v_list_itr->fltr_info;
1812 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
1813 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
1814 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
1815 /* Update the previous switch rule to a new VSI list which
1816 * includes current VSI thats requested
1817 */
1818 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
1819 if (status)
1820 goto exit;
1821
1822 /* before overriding VSI list map info. decrement ref_cnt of
1823 * previous VSI list
1824 */
1825 v_list_itr->vsi_list_info->ref_cnt--;
1826
1827 /* now update to newly created list */
1828 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
1829 v_list_itr->vsi_list_info =
1830 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
1831 vsi_list_id);
1832 v_list_itr->vsi_count++;
1833 }
1730 1834
1731exit: 1835exit:
1732 mutex_unlock(rule_lock); 1836 mutex_unlock(rule_lock);
@@ -1779,7 +1883,7 @@ ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
1779/** 1883/**
1780 * ice_cfg_dflt_vsi - change state of VSI to set/clear default 1884 * ice_cfg_dflt_vsi - change state of VSI to set/clear default
1781 * @hw: pointer to the hardware structure 1885 * @hw: pointer to the hardware structure
1782 * @vsi_id: number of VSI to set as default 1886 * @vsi_handle: VSI handle to set as default
1783 * @set: true to add the above mentioned switch rule, false to remove it 1887 * @set: true to add the above mentioned switch rule, false to remove it
1784 * @direction: ICE_FLTR_RX or ICE_FLTR_TX 1888 * @direction: ICE_FLTR_RX or ICE_FLTR_TX
1785 * 1889 *
@@ -1787,13 +1891,18 @@ ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
1787 * (represented by swid) 1891 * (represented by swid)
1788 */ 1892 */
1789enum ice_status 1893enum ice_status
1790ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction) 1894ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction)
1791{ 1895{
1792 struct ice_aqc_sw_rules_elem *s_rule; 1896 struct ice_aqc_sw_rules_elem *s_rule;
1793 struct ice_fltr_info f_info; 1897 struct ice_fltr_info f_info;
1794 enum ice_adminq_opc opcode; 1898 enum ice_adminq_opc opcode;
1795 enum ice_status status; 1899 enum ice_status status;
1796 u16 s_rule_size; 1900 u16 s_rule_size;
1901 u16 hw_vsi_id;
1902
1903 if (!ice_is_vsi_valid(hw, vsi_handle))
1904 return ICE_ERR_PARAM;
1905 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
1797 1906
1798 s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE : 1907 s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
1799 ICE_SW_RULE_RX_TX_NO_HDR_SIZE; 1908 ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
@@ -1806,15 +1915,17 @@ ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction)
1806 f_info.lkup_type = ICE_SW_LKUP_DFLT; 1915 f_info.lkup_type = ICE_SW_LKUP_DFLT;
1807 f_info.flag = direction; 1916 f_info.flag = direction;
1808 f_info.fltr_act = ICE_FWD_TO_VSI; 1917 f_info.fltr_act = ICE_FWD_TO_VSI;
1809 f_info.fwd_id.vsi_id = vsi_id; 1918 f_info.fwd_id.hw_vsi_id = hw_vsi_id;
1810 1919
1811 if (f_info.flag & ICE_FLTR_RX) { 1920 if (f_info.flag & ICE_FLTR_RX) {
1812 f_info.src = hw->port_info->lport; 1921 f_info.src = hw->port_info->lport;
1922 f_info.src_id = ICE_SRC_ID_LPORT;
1813 if (!set) 1923 if (!set)
1814 f_info.fltr_rule_id = 1924 f_info.fltr_rule_id =
1815 hw->port_info->dflt_rx_vsi_rule_id; 1925 hw->port_info->dflt_rx_vsi_rule_id;
1816 } else if (f_info.flag & ICE_FLTR_TX) { 1926 } else if (f_info.flag & ICE_FLTR_TX) {
1817 f_info.src = vsi_id; 1927 f_info.src_id = ICE_SRC_ID_VSI;
1928 f_info.src = hw_vsi_id;
1818 if (!set) 1929 if (!set)
1819 f_info.fltr_rule_id = 1930 f_info.fltr_rule_id =
1820 hw->port_info->dflt_tx_vsi_rule_id; 1931 hw->port_info->dflt_tx_vsi_rule_id;
@@ -1834,10 +1945,10 @@ ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction)
1834 u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index); 1945 u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
1835 1946
1836 if (f_info.flag & ICE_FLTR_TX) { 1947 if (f_info.flag & ICE_FLTR_TX) {
1837 hw->port_info->dflt_tx_vsi_num = vsi_id; 1948 hw->port_info->dflt_tx_vsi_num = hw_vsi_id;
1838 hw->port_info->dflt_tx_vsi_rule_id = index; 1949 hw->port_info->dflt_tx_vsi_rule_id = index;
1839 } else if (f_info.flag & ICE_FLTR_RX) { 1950 } else if (f_info.flag & ICE_FLTR_RX) {
1840 hw->port_info->dflt_rx_vsi_num = vsi_id; 1951 hw->port_info->dflt_rx_vsi_num = hw_vsi_id;
1841 hw->port_info->dflt_rx_vsi_rule_id = index; 1952 hw->port_info->dflt_rx_vsi_rule_id = index;
1842 } 1953 }
1843 } else { 1954 } else {
@@ -1920,21 +2031,21 @@ ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
1920/** 2031/**
1921 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 2032 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
1922 * @fm_entry: filter entry to inspect 2033 * @fm_entry: filter entry to inspect
1923 * @vsi_id: ID of VSI to compare with filter info 2034 * @vsi_handle: VSI handle to compare with filter info
1924 */ 2035 */
1925static bool 2036static bool
1926ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_id) 2037ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
1927{ 2038{
1928 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 2039 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
1929 fm_entry->fltr_info.fwd_id.vsi_id == vsi_id) || 2040 fm_entry->fltr_info.vsi_handle == vsi_handle) ||
1930 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 2041 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
1931 (test_bit(vsi_id, fm_entry->vsi_list_info->vsi_map)))); 2042 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
1932} 2043}
1933 2044
1934/** 2045/**
1935 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 2046 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
1936 * @hw: pointer to the hardware structure 2047 * @hw: pointer to the hardware structure
1937 * @vsi_id: ID of VSI to remove filters from 2048 * @vsi_handle: VSI handle to remove filters from
1938 * @vsi_list_head: pointer to the list to add entry to 2049 * @vsi_list_head: pointer to the list to add entry to
1939 * @fi: pointer to fltr_info of filter entry to copy & add 2050 * @fi: pointer to fltr_info of filter entry to copy & add
1940 * 2051 *
@@ -1945,7 +2056,7 @@ ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_id)
1945 * extract which VSI to remove the fltr from, and pass on that information. 2056 * extract which VSI to remove the fltr from, and pass on that information.
1946 */ 2057 */
1947static enum ice_status 2058static enum ice_status
1948ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id, 2059ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
1949 struct list_head *vsi_list_head, 2060 struct list_head *vsi_list_head,
1950 struct ice_fltr_info *fi) 2061 struct ice_fltr_info *fi)
1951{ 2062{
@@ -1966,7 +2077,8 @@ ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1966 * values. 2077 * values.
1967 */ 2078 */
1968 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 2079 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
1969 tmp->fltr_info.fwd_id.vsi_id = vsi_id; 2080 tmp->fltr_info.vsi_handle = vsi_handle;
2081 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
1970 2082
1971 list_add(&tmp->list_entry, vsi_list_head); 2083 list_add(&tmp->list_entry, vsi_list_head);
1972 2084
@@ -1976,9 +2088,9 @@ ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1976/** 2088/**
1977 * ice_add_to_vsi_fltr_list - Add VSI filters to the list 2089 * ice_add_to_vsi_fltr_list - Add VSI filters to the list
1978 * @hw: pointer to the hardware structure 2090 * @hw: pointer to the hardware structure
1979 * @vsi_id: ID of VSI to remove filters from 2091 * @vsi_handle: VSI handle to remove filters from
1980 * @lkup_list_head: pointer to the list that has certain lookup type filters 2092 * @lkup_list_head: pointer to the list that has certain lookup type filters
1981 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_id 2093 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
1982 * 2094 *
1983 * Locates all filters in lkup_list_head that are used by the given VSI, 2095 * Locates all filters in lkup_list_head that are used by the given VSI,
1984 * and adds COPIES of those entries to vsi_list_head (intended to be used 2096 * and adds COPIES of those entries to vsi_list_head (intended to be used
@@ -1987,7 +2099,7 @@ ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1987 * deallocated by the caller when done with list. 2099 * deallocated by the caller when done with list.
1988 */ 2100 */
1989static enum ice_status 2101static enum ice_status
1990ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id, 2102ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
1991 struct list_head *lkup_list_head, 2103 struct list_head *lkup_list_head,
1992 struct list_head *vsi_list_head) 2104 struct list_head *vsi_list_head)
1993{ 2105{
@@ -1995,17 +2107,17 @@ ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
1995 enum ice_status status = 0; 2107 enum ice_status status = 0;
1996 2108
1997 /* check to make sure VSI id is valid and within boundary */ 2109 /* check to make sure VSI id is valid and within boundary */
1998 if (vsi_id >= ICE_MAX_VSI) 2110 if (!ice_is_vsi_valid(hw, vsi_handle))
1999 return ICE_ERR_PARAM; 2111 return ICE_ERR_PARAM;
2000 2112
2001 list_for_each_entry(fm_entry, lkup_list_head, list_entry) { 2113 list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
2002 struct ice_fltr_info *fi; 2114 struct ice_fltr_info *fi;
2003 2115
2004 fi = &fm_entry->fltr_info; 2116 fi = &fm_entry->fltr_info;
2005 if (!ice_vsi_uses_fltr(fm_entry, vsi_id)) 2117 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
2006 continue; 2118 continue;
2007 2119
2008 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_id, 2120 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
2009 vsi_list_head, fi); 2121 vsi_list_head, fi);
2010 if (status) 2122 if (status)
2011 return status; 2123 return status;
@@ -2016,11 +2128,11 @@ ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_id,
2016/** 2128/**
2017 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 2129 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
2018 * @hw: pointer to the hardware structure 2130 * @hw: pointer to the hardware structure
2019 * @vsi_id: ID of VSI to remove filters from 2131 * @vsi_handle: VSI handle to remove filters from
2020 * @lkup: switch rule filter lookup type 2132 * @lkup: switch rule filter lookup type
2021 */ 2133 */
2022static void 2134static void
2023ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_id, 2135ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
2024 enum ice_sw_lkup_type lkup) 2136 enum ice_sw_lkup_type lkup)
2025{ 2137{
2026 struct ice_switch_info *sw = hw->switch_info; 2138 struct ice_switch_info *sw = hw->switch_info;
@@ -2035,7 +2147,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_id,
2035 rule_lock = &sw->recp_list[lkup].filt_rule_lock; 2147 rule_lock = &sw->recp_list[lkup].filt_rule_lock;
2036 rule_head = &sw->recp_list[lkup].filt_rules; 2148 rule_head = &sw->recp_list[lkup].filt_rules;
2037 mutex_lock(rule_lock); 2149 mutex_lock(rule_lock);
2038 status = ice_add_to_vsi_fltr_list(hw, vsi_id, rule_head, 2150 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
2039 &remove_list_head); 2151 &remove_list_head);
2040 mutex_unlock(rule_lock); 2152 mutex_unlock(rule_lock);
2041 if (status) 2153 if (status)
@@ -2069,18 +2181,18 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_id,
2069/** 2181/**
2070 * ice_remove_vsi_fltr - Remove all filters for a VSI 2182 * ice_remove_vsi_fltr - Remove all filters for a VSI
2071 * @hw: pointer to the hardware structure 2183 * @hw: pointer to the hardware structure
2072 * @vsi_id: ID of VSI to remove filters from 2184 * @vsi_handle: VSI handle to remove filters from
2073 */ 2185 */
2074void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id) 2186void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
2075{ 2187{
2076 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_MAC); 2188 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
2077 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_MAC_VLAN); 2189 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
2078 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_PROMISC); 2190 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
2079 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_VLAN); 2191 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
2080 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_DFLT); 2192 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
2081 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_ETHERTYPE); 2193 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
2082 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_ETHERTYPE_MAC); 2194 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
2083 ice_remove_vsi_lkup_fltr(hw, vsi_id, ICE_SW_LKUP_PROMISC_VLAN); 2195 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
2084} 2196}
2085 2197
2086/** 2198/**
@@ -2129,7 +2241,7 @@ ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct list_head *list_head)
2129 break; 2241 break;
2130 2242
2131 clear_bit(vsi, itr->vsi_list_info->vsi_map); 2243 clear_bit(vsi, itr->vsi_list_info->vsi_map);
2132 f_entry.fltr_info.fwd_id.vsi_id = vsi; 2244 f_entry.fltr_info.fwd_id.hw_vsi_id = vsi;
2133 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 2245 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
2134 if (recp_id == ICE_SW_LKUP_VLAN) 2246 if (recp_id == ICE_SW_LKUP_VLAN)
2135 status = ice_add_vlan_internal(hw, &f_entry); 2247 status = ice_add_vlan_internal(hw, &f_entry);
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h
index e12940e70000..c188bbc3de2a 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.h
+++ b/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -42,6 +42,14 @@ enum ice_sw_lkup_type {
42 ICE_SW_LKUP_LAST 42 ICE_SW_LKUP_LAST
43}; 43};
44 44
45/* type of filter src id */
46enum ice_src_id {
47 ICE_SRC_ID_UNKNOWN = 0,
48 ICE_SRC_ID_VSI,
49 ICE_SRC_ID_QUEUE,
50 ICE_SRC_ID_LPORT,
51};
52
45struct ice_fltr_info { 53struct ice_fltr_info {
46 /* Look up information: how to look up packet */ 54 /* Look up information: how to look up packet */
47 enum ice_sw_lkup_type lkup_type; 55 enum ice_sw_lkup_type lkup_type;
@@ -56,6 +64,7 @@ struct ice_fltr_info {
56 64
57 /* Source VSI for LOOKUP_TX or source port for LOOKUP_RX */ 65 /* Source VSI for LOOKUP_TX or source port for LOOKUP_RX */
58 u16 src; 66 u16 src;
67 enum ice_src_id src_id;
59 68
60 union { 69 union {
61 struct { 70 struct {
@@ -77,7 +86,10 @@ struct ice_fltr_info {
77 u16 ethertype; 86 u16 ethertype;
78 u8 mac_addr[ETH_ALEN]; /* optional */ 87 u8 mac_addr[ETH_ALEN]; /* optional */
79 } ethertype_mac; 88 } ethertype_mac;
80 } l_data; 89 } l_data; /* Make sure to zero out the memory of l_data before using
90 * it or only set the data associated with lookup match
91 * rest everything should be zero
92 */
81 93
82 /* Depending on filter action */ 94 /* Depending on filter action */
83 union { 95 union {
@@ -85,12 +97,16 @@ struct ice_fltr_info {
85 * queue id in case of ICE_FWD_TO_QGRP. 97 * queue id in case of ICE_FWD_TO_QGRP.
86 */ 98 */
87 u16 q_id:11; 99 u16 q_id:11;
88 u16 vsi_id:10; 100 u16 hw_vsi_id:10;
89 u16 vsi_list_id:10; 101 u16 vsi_list_id:10;
90 } fwd_id; 102 } fwd_id;
91 103
104 /* Sw VSI handle */
105 u16 vsi_handle;
106
92 /* Set to num_queues if action is ICE_FWD_TO_QGRP. This field 107 /* Set to num_queues if action is ICE_FWD_TO_QGRP. This field
93 * determines the range of queues the packet needs to be forwarded to 108 * determines the range of queues the packet needs to be forwarded to.
109 * Note that qgrp_size must be set to a power of 2.
94 */ 110 */
95 u8 qgrp_size; 111 u8 qgrp_size;
96 112
@@ -129,6 +145,8 @@ struct ice_vsi_list_map_info {
129 struct list_head list_entry; 145 struct list_head list_entry;
130 DECLARE_BITMAP(vsi_map, ICE_MAX_VSI); 146 DECLARE_BITMAP(vsi_map, ICE_MAX_VSI);
131 u16 vsi_list_id; 147 u16 vsi_list_id;
148 /* counter to track how many rules are reusing this VSI list */
149 u16 ref_cnt;
132}; 150};
133 151
134struct ice_fltr_list_entry { 152struct ice_fltr_list_entry {
@@ -159,25 +177,25 @@ struct ice_fltr_mgmt_list_entry {
159 177
160/* VSI related commands */ 178/* VSI related commands */
161enum ice_status 179enum ice_status
162ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
163 struct ice_sq_cd *cd);
164enum ice_status
165ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 180ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
166 struct ice_sq_cd *cd); 181 struct ice_sq_cd *cd);
167enum ice_status 182enum ice_status
168ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 183ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
169 bool keep_vsi_alloc, struct ice_sq_cd *cd); 184 bool keep_vsi_alloc, struct ice_sq_cd *cd);
185enum ice_status
186ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
187 struct ice_sq_cd *cd);
170enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw); 188enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw);
171 189
172/* Switch/bridge related commands */ 190/* Switch/bridge related commands */
173enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw); 191enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw);
174enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_lst); 192enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_lst);
175enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst); 193enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst);
176void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id); 194void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle);
177enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *m_list); 195enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);
178enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list); 196enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);
179enum ice_status 197enum ice_status
180ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction); 198ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction);
181 199
182enum ice_status ice_replay_all_fltr(struct ice_hw *hw); 200enum ice_status ice_replay_all_fltr(struct ice_hw *hw);
183 201