Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next -queue

Tony Nguyen says:

====================
i40e: Simplify VSI and VEB handling

Ivan Vecera says:

The series simplifies handling of VSIs and VEBs by introducing for-each
iterating macros, 'find' helper functions. Also removes the VEB
recursion because the VEBs cannot have sub-VEBs according datasheet and
fixes the support for floating VEBs.

The series content:
Patch 1 - Uses existing helper function for find FDIR VSI instead of loop
Patch 2 - Adds and uses macros to iterate VSI and VEB arrays
Patch 3 - Adds 2 helper functions to find VSIs and VEBs by their SEID
Patch 4 - Fixes broken support for floating VEBs
Patch 5 - Removes VEB recursion and simplifies VEB handling
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+373 -390
+87 -6
drivers/net/ethernet/intel/i40e/i40e.h
··· 687 687 }; 688 688 689 689 /** 690 + * __i40e_pf_next_vsi - get next valid VSI 691 + * @pf: pointer to the PF struct 692 + * @idx: pointer to start position number 693 + * 694 + * Find and return next non-NULL VSI pointer in pf->vsi array and 695 + * updates idx position. Returns NULL if no VSI is found. 696 + **/ 697 + static __always_inline struct i40e_vsi * 698 + __i40e_pf_next_vsi(struct i40e_pf *pf, int *idx) 699 + { 700 + while (*idx < pf->num_alloc_vsi) { 701 + if (pf->vsi[*idx]) 702 + return pf->vsi[*idx]; 703 + (*idx)++; 704 + } 705 + return NULL; 706 + } 707 + 708 + #define i40e_pf_for_each_vsi(_pf, _i, _vsi) \ 709 + for (_i = 0, _vsi = __i40e_pf_next_vsi(_pf, &_i); \ 710 + _vsi; \ 711 + _i++, _vsi = __i40e_pf_next_vsi(_pf, &_i)) 712 + 713 + /** 714 + * __i40e_pf_next_veb - get next valid VEB 715 + * @pf: pointer to the PF struct 716 + * @idx: pointer to start position number 717 + * 718 + * Find and return next non-NULL VEB pointer in pf->veb array and 719 + * updates idx position. Returns NULL if no VEB is found. 720 + **/ 721 + static __always_inline struct i40e_veb * 722 + __i40e_pf_next_veb(struct i40e_pf *pf, int *idx) 723 + { 724 + while (*idx < I40E_MAX_VEB) { 725 + if (pf->veb[*idx]) 726 + return pf->veb[*idx]; 727 + (*idx)++; 728 + } 729 + return NULL; 730 + } 731 + 732 + #define i40e_pf_for_each_veb(_pf, _i, _veb) \ 733 + for (_i = 0, _veb = __i40e_pf_next_veb(_pf, &_i); \ 734 + _veb; \ 735 + _i++, _veb = __i40e_pf_next_veb(_pf, &_i)) 736 + 737 + /** 690 738 * i40e_mac_to_hkey - Convert a 6-byte MAC Address to a u64 hash key 691 739 * @macaddr: the MAC Address as the base key 692 740 * ··· 783 735 struct i40e_veb { 784 736 struct i40e_pf *pf; 785 737 u16 idx; 786 - u16 veb_idx; /* index of VEB parent */ 787 738 u16 seid; 788 739 u16 uplink_seid; 789 740 u16 stats_idx; /* index of VEB parent */ ··· 1167 1120 static inline struct i40e_vsi * 1168 1121 i40e_find_vsi_by_type(struct i40e_pf *pf, u16 type) 1169 1122 { 1123 + struct i40e_vsi *vsi; 1170 1124 int i; 1171 1125 1172 - for (i = 0; i < pf->num_alloc_vsi; i++) { 1173 - struct i40e_vsi *vsi = pf->vsi[i]; 1174 - 1175 - if (vsi && vsi->type == type) 1126 + i40e_pf_for_each_vsi(pf, i, vsi) 1127 + if (vsi->type == type) 1176 1128 return vsi; 1177 - } 1178 1129 1179 1130 return NULL; 1180 1131 } ··· 1353 1308 } 1354 1309 1355 1310 struct device *i40e_hw_to_dev(struct i40e_hw *hw); 1311 + 1312 + /** 1313 + * i40e_pf_get_vsi_by_seid - find VSI by SEID 1314 + * @pf: pointer to a PF 1315 + * @seid: SEID of the VSI 1316 + **/ 1317 + static inline struct i40e_vsi * 1318 + i40e_pf_get_vsi_by_seid(struct i40e_pf *pf, u16 seid) 1319 + { 1320 + struct i40e_vsi *vsi; 1321 + int i; 1322 + 1323 + i40e_pf_for_each_vsi(pf, i, vsi) 1324 + if (vsi->seid == seid) 1325 + return vsi; 1326 + 1327 + return NULL; 1328 + } 1329 + 1330 + /** 1331 + * i40e_pf_get_veb_by_seid - find VEB by SEID 1332 + * @pf: pointer to a PF 1333 + * @seid: SEID of the VSI 1334 + **/ 1335 + static inline struct i40e_veb * 1336 + i40e_pf_get_veb_by_seid(struct i40e_pf *pf, u16 seid) 1337 + { 1338 + struct i40e_veb *veb; 1339 + int i; 1340 + 1341 + i40e_pf_for_each_veb(pf, i, veb) 1342 + if (veb->seid == seid) 1343 + return veb; 1344 + 1345 + return NULL; 1346 + } 1356 1347 1357 1348 #endif /* _I40E_H_ */
+5 -5
drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c
··· 947 947 static void i40e_dcbnl_del_app(struct i40e_pf *pf, 948 948 struct i40e_dcb_app_priority_table *app) 949 949 { 950 + struct i40e_vsi *vsi; 950 951 int v, err; 951 952 952 - for (v = 0; v < pf->num_alloc_vsi; v++) { 953 - if (pf->vsi[v] && pf->vsi[v]->netdev) { 954 - err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app); 953 + i40e_pf_for_each_vsi(pf, v, vsi) 954 + if (vsi->netdev) { 955 + err = i40e_dcbnl_vsi_del_app(vsi, app); 955 956 dev_dbg(&pf->pdev->dev, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n", 956 - pf->vsi[v]->seid, err, app->selector, 957 + vsi->seid, err, app->selector, 957 958 app->protocolid, app->priority); 958 959 } 959 - } 960 960 } 961 961 962 962 /**
+41 -56
drivers/net/ethernet/intel/i40e/i40e_debugfs.c
··· 24 24 **/ 25 25 static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid) 26 26 { 27 - int i; 28 - 29 - if (seid < 0) 27 + if (seid < 0) { 30 28 dev_info(&pf->pdev->dev, "%d: bad seid\n", seid); 31 - else 32 - for (i = 0; i < pf->num_alloc_vsi; i++) 33 - if (pf->vsi[i] && (pf->vsi[i]->seid == seid)) 34 - return pf->vsi[i]; 35 29 36 - return NULL; 37 - } 30 + return NULL; 31 + } 38 32 39 - /** 40 - * i40e_dbg_find_veb - searches for the veb with the given seid 41 - * @pf: the PF structure to search for the veb 42 - * @seid: seid of the veb it is searching for 43 - **/ 44 - static struct i40e_veb *i40e_dbg_find_veb(struct i40e_pf *pf, int seid) 45 - { 46 - int i; 47 - 48 - for (i = 0; i < I40E_MAX_VEB; i++) 49 - if (pf->veb[i] && pf->veb[i]->seid == seid) 50 - return pf->veb[i]; 51 - return NULL; 33 + return i40e_pf_get_vsi_by_seid(pf, seid); 52 34 } 53 35 54 36 /************************************************************** ··· 635 653 **/ 636 654 static void i40e_dbg_dump_vsi_no_seid(struct i40e_pf *pf) 637 655 { 656 + struct i40e_vsi *vsi; 638 657 int i; 639 658 640 - for (i = 0; i < pf->num_alloc_vsi; i++) 641 - if (pf->vsi[i]) 642 - dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n", 643 - i, pf->vsi[i]->seid); 659 + i40e_pf_for_each_vsi(pf, i, vsi) 660 + dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n", i, vsi->seid); 644 661 } 645 662 646 663 /** ··· 677 696 { 678 697 struct i40e_veb *veb; 679 698 680 - veb = i40e_dbg_find_veb(pf, seid); 699 + veb = i40e_pf_get_veb_by_seid(pf, seid); 681 700 if (!veb) { 682 701 dev_info(&pf->pdev->dev, "can't find veb %d\n", seid); 683 702 return; 684 703 } 685 704 dev_info(&pf->pdev->dev, 686 - "veb idx=%d,%d stats_ic=%d seid=%d uplink=%d mode=%s\n", 687 - veb->idx, veb->veb_idx, veb->stats_idx, veb->seid, 688 - veb->uplink_seid, 705 + "veb idx=%d stats_ic=%d seid=%d uplink=%d mode=%s\n", 706 + veb->idx, veb->stats_idx, veb->seid, veb->uplink_seid, 689 707 veb->bridge_mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB"); 690 708 i40e_dbg_dump_eth_stats(pf, &veb->stats); 691 709 } ··· 698 718 struct i40e_veb *veb; 699 719 int i; 700 720 701 - for (i = 0; i < I40E_MAX_VEB; i++) { 702 - veb = pf->veb[i]; 703 - if (veb) 704 - i40e_dbg_dump_veb_seid(pf, veb->seid); 705 - } 721 + i40e_pf_for_each_veb(pf, i, veb) 722 + i40e_dbg_dump_veb_seid(pf, veb->seid); 706 723 } 707 724 708 725 /** ··· 828 851 829 852 } else if (strncmp(cmd_buf, "add relay", 9) == 0) { 830 853 struct i40e_veb *veb; 831 - int uplink_seid, i; 854 + u8 enabled_tc = 0x1; 855 + int uplink_seid; 832 856 833 857 cnt = sscanf(&cmd_buf[9], "%i %i", &uplink_seid, &vsi_seid); 834 - if (cnt != 2) { 858 + if (cnt == 0) { 859 + uplink_seid = 0; 860 + vsi_seid = 0; 861 + } else if (cnt != 2) { 835 862 dev_info(&pf->pdev->dev, 836 863 "add relay: bad command string, cnt=%d\n", 837 864 cnt); ··· 847 866 goto command_write_done; 848 867 } 849 868 850 - vsi = i40e_dbg_find_vsi(pf, vsi_seid); 851 - if (!vsi) { 852 - dev_info(&pf->pdev->dev, 853 - "add relay: VSI %d not found\n", vsi_seid); 854 - goto command_write_done; 855 - } 856 - 857 - for (i = 0; i < I40E_MAX_VEB; i++) 858 - if (pf->veb[i] && pf->veb[i]->seid == uplink_seid) 859 - break; 860 - if (i >= I40E_MAX_VEB && uplink_seid != 0 && 861 - uplink_seid != pf->mac_seid) { 869 + if (uplink_seid != 0 && uplink_seid != pf->mac_seid) { 862 870 dev_info(&pf->pdev->dev, 863 871 "add relay: relay uplink %d not found\n", 864 872 uplink_seid); 865 873 goto command_write_done; 874 + } else if (uplink_seid) { 875 + vsi = i40e_pf_get_vsi_by_seid(pf, vsi_seid); 876 + if (!vsi) { 877 + dev_info(&pf->pdev->dev, 878 + "add relay: VSI %d not found\n", 879 + vsi_seid); 880 + goto command_write_done; 881 + } 882 + enabled_tc = vsi->tc_config.enabled_tc; 883 + } else if (vsi_seid) { 884 + dev_info(&pf->pdev->dev, 885 + "add relay: VSI must be 0 for floating relay\n"); 886 + goto command_write_done; 866 887 } 867 888 868 - veb = i40e_veb_setup(pf, 0, uplink_seid, vsi_seid, 869 - vsi->tc_config.enabled_tc); 889 + veb = i40e_veb_setup(pf, 0, uplink_seid, vsi_seid, enabled_tc); 870 890 if (veb) 871 891 dev_info(&pf->pdev->dev, "added relay %d\n", veb->seid); 872 892 else 873 893 dev_info(&pf->pdev->dev, "add relay failed\n"); 874 894 875 895 } else if (strncmp(cmd_buf, "del relay", 9) == 0) { 896 + struct i40e_veb *veb; 876 897 int i; 898 + 877 899 cnt = sscanf(&cmd_buf[9], "%i", &veb_seid); 878 900 if (cnt != 1) { 879 901 dev_info(&pf->pdev->dev, ··· 890 906 } 891 907 892 908 /* find the veb */ 893 - for (i = 0; i < I40E_MAX_VEB; i++) 894 - if (pf->veb[i] && pf->veb[i]->seid == veb_seid) 909 + i40e_pf_for_each_veb(pf, i, veb) 910 + if (veb->seid == veb_seid) 895 911 break; 912 + 896 913 if (i >= I40E_MAX_VEB) { 897 914 dev_info(&pf->pdev->dev, 898 915 "del relay: relay %d not found\n", veb_seid); ··· 901 916 } 902 917 903 918 dev_info(&pf->pdev->dev, "deleting relay %d\n", veb_seid); 904 - i40e_veb_release(pf->veb[i]); 919 + i40e_veb_release(veb); 905 920 } else if (strncmp(cmd_buf, "add pvid", 8) == 0) { 906 921 unsigned int v; 907 922 int ret; ··· 1236 1251 if (cnt == 0) { 1237 1252 int i; 1238 1253 1239 - for (i = 0; i < pf->num_alloc_vsi; i++) 1240 - i40e_vsi_reset_stats(pf->vsi[i]); 1254 + i40e_pf_for_each_vsi(pf, i, vsi) 1255 + i40e_vsi_reset_stats(vsi); 1241 1256 dev_info(&pf->pdev->dev, "vsi clear stats called for all vsi's\n"); 1242 1257 } else if (cnt == 1) { 1243 1258 vsi = i40e_dbg_find_vsi(pf, vsi_seid);
+240 -323
drivers/net/ethernet/intel/i40e/i40e_main.c
··· 310 310 **/ 311 311 struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id) 312 312 { 313 + struct i40e_vsi *vsi; 313 314 int i; 314 315 315 - for (i = 0; i < pf->num_alloc_vsi; i++) 316 - if (pf->vsi[i] && (pf->vsi[i]->id == id)) 317 - return pf->vsi[i]; 316 + i40e_pf_for_each_vsi(pf, i, vsi) 317 + if (vsi->id == id) 318 + return vsi; 318 319 319 320 return NULL; 320 321 } ··· 553 552 **/ 554 553 void i40e_pf_reset_stats(struct i40e_pf *pf) 555 554 { 555 + struct i40e_veb *veb; 556 556 int i; 557 557 558 558 memset(&pf->stats, 0, sizeof(pf->stats)); 559 559 memset(&pf->stats_offsets, 0, sizeof(pf->stats_offsets)); 560 560 pf->stat_offsets_loaded = false; 561 561 562 - for (i = 0; i < I40E_MAX_VEB; i++) { 563 - if (pf->veb[i]) { 564 - memset(&pf->veb[i]->stats, 0, 565 - sizeof(pf->veb[i]->stats)); 566 - memset(&pf->veb[i]->stats_offsets, 0, 567 - sizeof(pf->veb[i]->stats_offsets)); 568 - memset(&pf->veb[i]->tc_stats, 0, 569 - sizeof(pf->veb[i]->tc_stats)); 570 - memset(&pf->veb[i]->tc_stats_offsets, 0, 571 - sizeof(pf->veb[i]->tc_stats_offsets)); 572 - pf->veb[i]->stat_offsets_loaded = false; 573 - } 562 + i40e_pf_for_each_veb(pf, i, veb) { 563 + memset(&veb->stats, 0, sizeof(veb->stats)); 564 + memset(&veb->stats_offsets, 0, sizeof(veb->stats_offsets)); 565 + memset(&veb->tc_stats, 0, sizeof(veb->tc_stats)); 566 + memset(&veb->tc_stats_offsets, 0, sizeof(veb->tc_stats_offsets)); 567 + veb->stat_offsets_loaded = false; 574 568 } 575 569 pf->hw_csum_rx_error = 0; 576 570 } ··· 2875 2879 **/ 2876 2880 static void i40e_sync_filters_subtask(struct i40e_pf *pf) 2877 2881 { 2882 + struct i40e_vsi *vsi; 2878 2883 int v; 2879 2884 2880 2885 if (!pf) ··· 2887 2890 return; 2888 2891 } 2889 2892 2890 - for (v = 0; v < pf->num_alloc_vsi; v++) { 2891 - if (pf->vsi[v] && 2892 - (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED) && 2893 - !test_bit(__I40E_VSI_RELEASING, pf->vsi[v]->state)) { 2894 - int ret = i40e_sync_vsi_filters(pf->vsi[v]); 2893 + i40e_pf_for_each_vsi(pf, v, vsi) { 2894 + if ((vsi->flags & I40E_VSI_FLAG_FILTER_CHANGED) && 2895 + !test_bit(__I40E_VSI_RELEASING, vsi->state)) { 2896 + int ret = i40e_sync_vsi_filters(vsi); 2895 2897 2896 2898 if (ret) { 2897 2899 /* come back and try again later */ ··· 5162 5166 **/ 5163 5167 static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) 5164 5168 { 5169 + struct i40e_vsi *vsi; 5165 5170 int i; 5166 5171 5167 5172 if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) ··· 5172 5175 I40E_IWARP_IRQ_PILE_ID); 5173 5176 5174 5177 i40e_put_lump(pf->irq_pile, 0, I40E_PILE_VALID_BIT-1); 5175 - for (i = 0; i < pf->num_alloc_vsi; i++) 5176 - if (pf->vsi[i]) 5177 - i40e_vsi_free_q_vectors(pf->vsi[i]); 5178 + 5179 + i40e_pf_for_each_vsi(pf, i, vsi) 5180 + i40e_vsi_free_q_vectors(vsi); 5181 + 5178 5182 i40e_reset_interrupt_capability(pf); 5179 5183 } 5180 5184 ··· 5272 5274 **/ 5273 5275 static void i40e_pf_quiesce_all_vsi(struct i40e_pf *pf) 5274 5276 { 5277 + struct i40e_vsi *vsi; 5275 5278 int v; 5276 5279 5277 - for (v = 0; v < pf->num_alloc_vsi; v++) { 5278 - if (pf->vsi[v]) 5279 - i40e_quiesce_vsi(pf->vsi[v]); 5280 - } 5280 + i40e_pf_for_each_vsi(pf, v, vsi) 5281 + i40e_quiesce_vsi(vsi); 5281 5282 } 5282 5283 5283 5284 /** ··· 5285 5288 **/ 5286 5289 static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf) 5287 5290 { 5291 + struct i40e_vsi *vsi; 5288 5292 int v; 5289 5293 5290 - for (v = 0; v < pf->num_alloc_vsi; v++) { 5291 - if (pf->vsi[v]) 5292 - i40e_unquiesce_vsi(pf->vsi[v]); 5293 - } 5294 + i40e_pf_for_each_vsi(pf, v, vsi) 5295 + i40e_unquiesce_vsi(vsi); 5294 5296 } 5295 5297 5296 5298 /** ··· 5350 5354 **/ 5351 5355 static int i40e_pf_wait_queues_disabled(struct i40e_pf *pf) 5352 5356 { 5357 + struct i40e_vsi *vsi; 5353 5358 int v, ret = 0; 5354 5359 5355 - for (v = 0; v < pf->num_alloc_vsi; v++) { 5356 - if (pf->vsi[v]) { 5357 - ret = i40e_vsi_wait_queues_disabled(pf->vsi[v]); 5358 - if (ret) 5359 - break; 5360 - } 5360 + i40e_pf_for_each_vsi(pf, v, vsi) { 5361 + ret = i40e_vsi_wait_queues_disabled(vsi); 5362 + if (ret) 5363 + break; 5361 5364 } 5362 5365 5363 5366 return ret; ··· 6773 6778 **/ 6774 6779 static void i40e_dcb_reconfigure(struct i40e_pf *pf) 6775 6780 { 6781 + struct i40e_vsi *vsi; 6782 + struct i40e_veb *veb; 6776 6783 u8 tc_map = 0; 6777 6784 int ret; 6778 - u8 v; 6785 + int v; 6779 6786 6780 6787 /* Enable the TCs available on PF to all VEBs */ 6781 6788 tc_map = i40e_pf_get_tc_map(pf); 6782 6789 if (tc_map == I40E_DEFAULT_TRAFFIC_CLASS) 6783 6790 return; 6784 6791 6785 - for (v = 0; v < I40E_MAX_VEB; v++) { 6786 - if (!pf->veb[v]) 6787 - continue; 6788 - ret = i40e_veb_config_tc(pf->veb[v], tc_map); 6792 + i40e_pf_for_each_veb(pf, v, veb) { 6793 + ret = i40e_veb_config_tc(veb, tc_map); 6789 6794 if (ret) { 6790 6795 dev_info(&pf->pdev->dev, 6791 6796 "Failed configuring TC for VEB seid=%d\n", 6792 - pf->veb[v]->seid); 6797 + veb->seid); 6793 6798 /* Will try to configure as many components */ 6794 6799 } 6795 6800 } 6796 6801 6797 6802 /* Update each VSI */ 6798 - for (v = 0; v < pf->num_alloc_vsi; v++) { 6799 - if (!pf->vsi[v]) 6800 - continue; 6801 - 6803 + i40e_pf_for_each_vsi(pf, v, vsi) { 6802 6804 /* - Enable all TCs for the LAN VSI 6803 6805 * - For all others keep them at TC0 for now 6804 6806 */ ··· 6804 6812 else 6805 6813 tc_map = I40E_DEFAULT_TRAFFIC_CLASS; 6806 6814 6807 - ret = i40e_vsi_config_tc(pf->vsi[v], tc_map); 6815 + ret = i40e_vsi_config_tc(vsi, tc_map); 6808 6816 if (ret) { 6809 6817 dev_info(&pf->pdev->dev, 6810 6818 "Failed configuring TC for VSI seid=%d\n", 6811 - pf->vsi[v]->seid); 6819 + vsi->seid); 6812 6820 /* Will try to configure as many components */ 6813 6821 } else { 6814 6822 /* Re-configure VSI vectors based on updated TC map */ 6815 - i40e_vsi_map_rings_to_vectors(pf->vsi[v]); 6816 - if (pf->vsi[v]->netdev) 6817 - i40e_dcbnl_set_all(pf->vsi[v]); 6823 + i40e_vsi_map_rings_to_vectors(vsi); 6824 + if (vsi->netdev) 6825 + i40e_dcbnl_set_all(vsi); 6818 6826 } 6819 6827 } 6820 6828 } ··· 9249 9257 **/ 9250 9258 void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired) 9251 9259 { 9260 + struct i40e_vsi *vsi; 9252 9261 u32 val; 9262 + int i; 9253 9263 9254 9264 /* do the biggest reset indicated */ 9255 9265 if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) { ··· 9307 9313 "FW LLDP is enabled\n"); 9308 9314 9309 9315 } else if (reset_flags & BIT_ULL(__I40E_REINIT_REQUESTED)) { 9310 - int v; 9311 - 9312 9316 /* Find the VSI(s) that requested a re-init */ 9313 - dev_info(&pf->pdev->dev, 9314 - "VSI reinit requested\n"); 9315 - for (v = 0; v < pf->num_alloc_vsi; v++) { 9316 - struct i40e_vsi *vsi = pf->vsi[v]; 9317 + dev_info(&pf->pdev->dev, "VSI reinit requested\n"); 9317 9318 9318 - if (vsi != NULL && 9319 - test_and_clear_bit(__I40E_VSI_REINIT_REQUESTED, 9319 + i40e_pf_for_each_vsi(pf, i, vsi) { 9320 + if (test_and_clear_bit(__I40E_VSI_REINIT_REQUESTED, 9320 9321 vsi->state)) 9321 - i40e_vsi_reinit_locked(pf->vsi[v]); 9322 + i40e_vsi_reinit_locked(vsi); 9322 9323 } 9323 9324 } else if (reset_flags & BIT_ULL(__I40E_DOWN_REQUESTED)) { 9324 - int v; 9325 - 9326 9325 /* Find the VSI(s) that needs to be brought down */ 9327 9326 dev_info(&pf->pdev->dev, "VSI down requested\n"); 9328 - for (v = 0; v < pf->num_alloc_vsi; v++) { 9329 - struct i40e_vsi *vsi = pf->vsi[v]; 9330 9327 9331 - if (vsi != NULL && 9332 - test_and_clear_bit(__I40E_VSI_DOWN_REQUESTED, 9328 + i40e_pf_for_each_vsi(pf, i, vsi) { 9329 + if (test_and_clear_bit(__I40E_VSI_DOWN_REQUESTED, 9333 9330 vsi->state)) { 9334 9331 set_bit(__I40E_VSI_DOWN, vsi->state); 9335 9332 i40e_down(vsi); ··· 9873 9888 **/ 9874 9889 static void i40e_veb_link_event(struct i40e_veb *veb, bool link_up) 9875 9890 { 9891 + struct i40e_vsi *vsi; 9876 9892 struct i40e_pf *pf; 9877 9893 int i; 9878 9894 ··· 9881 9895 return; 9882 9896 pf = veb->pf; 9883 9897 9884 - /* depth first... */ 9885 - for (i = 0; i < I40E_MAX_VEB; i++) 9886 - if (pf->veb[i] && (pf->veb[i]->uplink_seid == veb->seid)) 9887 - i40e_veb_link_event(pf->veb[i], link_up); 9888 - 9889 - /* ... now the local VSIs */ 9890 - for (i = 0; i < pf->num_alloc_vsi; i++) 9891 - if (pf->vsi[i] && (pf->vsi[i]->uplink_seid == veb->seid)) 9892 - i40e_vsi_link_event(pf->vsi[i], link_up); 9898 + /* Send link event to contained VSIs */ 9899 + i40e_pf_for_each_vsi(pf, i, vsi) 9900 + if (vsi->uplink_seid == veb->seid) 9901 + i40e_vsi_link_event(vsi, link_up); 9893 9902 } 9894 9903 9895 9904 /** ··· 9976 9995 **/ 9977 9996 static void i40e_watchdog_subtask(struct i40e_pf *pf) 9978 9997 { 9998 + struct i40e_vsi *vsi; 9999 + struct i40e_veb *veb; 9979 10000 int i; 9980 10001 9981 10002 /* if interface is down do nothing */ ··· 9998 10015 /* Update the stats for active netdevs so the network stack 9999 10016 * can look at updated numbers whenever it cares to 10000 10017 */ 10001 - for (i = 0; i < pf->num_alloc_vsi; i++) 10002 - if (pf->vsi[i] && pf->vsi[i]->netdev) 10003 - i40e_update_stats(pf->vsi[i]); 10018 + i40e_pf_for_each_vsi(pf, i, vsi) 10019 + if (vsi->netdev) 10020 + i40e_update_stats(vsi); 10004 10021 10005 10022 if (test_bit(I40E_FLAG_VEB_STATS_ENA, pf->flags)) { 10006 10023 /* Update the stats for the active switching components */ 10007 - for (i = 0; i < I40E_MAX_VEB; i++) 10008 - if (pf->veb[i]) 10009 - i40e_update_veb_stats(pf->veb[i]); 10024 + i40e_pf_for_each_veb(pf, i, veb) 10025 + i40e_update_veb_stats(veb); 10010 10026 } 10011 10027 10012 10028 i40e_ptp_rx_hang(pf); ··· 10350 10368 } 10351 10369 10352 10370 /** 10353 - * i40e_reconstitute_veb - rebuild the VEB and anything connected to it 10371 + * i40e_reconstitute_veb - rebuild the VEB and VSIs connected to it 10354 10372 * @veb: pointer to the VEB instance 10355 10373 * 10356 - * This is a recursive function that first builds the attached VSIs then 10357 - * recurses in to build the next layer of VEB. We track the connections 10358 - * through our own index numbers because the seid's from the HW could 10359 - * change across the reset. 10374 + * This is a function that builds the attached VSIs. We track the connections 10375 + * through our own index numbers because the seid's from the HW could change 10376 + * across the reset. 10360 10377 **/ 10361 10378 static int i40e_reconstitute_veb(struct i40e_veb *veb) 10362 10379 { 10363 10380 struct i40e_vsi *ctl_vsi = NULL; 10364 10381 struct i40e_pf *pf = veb->pf; 10365 - int v, veb_idx; 10366 - int ret; 10382 + struct i40e_vsi *vsi; 10383 + int v, ret; 10367 10384 10368 - /* build VSI that owns this VEB, temporarily attached to base VEB */ 10369 - for (v = 0; v < pf->num_alloc_vsi && !ctl_vsi; v++) { 10370 - if (pf->vsi[v] && 10371 - pf->vsi[v]->veb_idx == veb->idx && 10372 - pf->vsi[v]->flags & I40E_VSI_FLAG_VEB_OWNER) { 10373 - ctl_vsi = pf->vsi[v]; 10374 - break; 10385 + /* As we do not maintain PV (port virtualizer) switch element then 10386 + * there can be only one non-floating VEB that have uplink to MAC SEID 10387 + * and its control VSI is the main one. 10388 + */ 10389 + if (WARN_ON(veb->uplink_seid && veb->uplink_seid != pf->mac_seid)) { 10390 + dev_err(&pf->pdev->dev, 10391 + "Invalid uplink SEID for VEB %d\n", veb->idx); 10392 + return -ENOENT; 10393 + } 10394 + 10395 + if (veb->uplink_seid == pf->mac_seid) { 10396 + /* Check that the LAN VSI has VEB owning flag set */ 10397 + ctl_vsi = pf->vsi[pf->lan_vsi]; 10398 + 10399 + if (WARN_ON(ctl_vsi->veb_idx != veb->idx || 10400 + !(ctl_vsi->flags & I40E_VSI_FLAG_VEB_OWNER))) { 10401 + dev_err(&pf->pdev->dev, 10402 + "Invalid control VSI for VEB %d\n", veb->idx); 10403 + return -ENOENT; 10375 10404 } 10405 + 10406 + /* Add the control VSI to switch */ 10407 + ret = i40e_add_vsi(ctl_vsi); 10408 + if (ret) { 10409 + dev_err(&pf->pdev->dev, 10410 + "Rebuild of owner VSI for VEB %d failed: %d\n", 10411 + veb->idx, ret); 10412 + return ret; 10413 + } 10414 + 10415 + i40e_vsi_reset_stats(ctl_vsi); 10376 10416 } 10377 - if (!ctl_vsi) { 10378 - dev_info(&pf->pdev->dev, 10379 - "missing owner VSI for veb_idx %d\n", veb->idx); 10380 - ret = -ENOENT; 10381 - goto end_reconstitute; 10382 - } 10383 - if (ctl_vsi != pf->vsi[pf->lan_vsi]) 10384 - ctl_vsi->uplink_seid = pf->vsi[pf->lan_vsi]->uplink_seid; 10385 - ret = i40e_add_vsi(ctl_vsi); 10386 - if (ret) { 10387 - dev_info(&pf->pdev->dev, 10388 - "rebuild of veb_idx %d owner VSI failed: %d\n", 10389 - veb->idx, ret); 10390 - goto end_reconstitute; 10391 - } 10392 - i40e_vsi_reset_stats(ctl_vsi); 10393 10417 10394 10418 /* create the VEB in the switch and move the VSI onto the VEB */ 10395 10419 ret = i40e_add_veb(veb, ctl_vsi); 10396 10420 if (ret) 10397 - goto end_reconstitute; 10421 + return ret; 10398 10422 10399 - if (test_bit(I40E_FLAG_VEB_MODE_ENA, pf->flags)) 10400 - veb->bridge_mode = BRIDGE_MODE_VEB; 10401 - else 10402 - veb->bridge_mode = BRIDGE_MODE_VEPA; 10403 - i40e_config_bridge_mode(veb); 10423 + if (veb->uplink_seid) { 10424 + if (test_bit(I40E_FLAG_VEB_MODE_ENA, pf->flags)) 10425 + veb->bridge_mode = BRIDGE_MODE_VEB; 10426 + else 10427 + veb->bridge_mode = BRIDGE_MODE_VEPA; 10428 + i40e_config_bridge_mode(veb); 10429 + } 10404 10430 10405 10431 /* create the remaining VSIs attached to this VEB */ 10406 - for (v = 0; v < pf->num_alloc_vsi; v++) { 10407 - if (!pf->vsi[v] || pf->vsi[v] == ctl_vsi) 10432 + i40e_pf_for_each_vsi(pf, v, vsi) { 10433 + if (vsi == ctl_vsi) 10408 10434 continue; 10409 10435 10410 - if (pf->vsi[v]->veb_idx == veb->idx) { 10411 - struct i40e_vsi *vsi = pf->vsi[v]; 10412 - 10436 + if (vsi->veb_idx == veb->idx) { 10413 10437 vsi->uplink_seid = veb->seid; 10414 10438 ret = i40e_add_vsi(vsi); 10415 10439 if (ret) { 10416 10440 dev_info(&pf->pdev->dev, 10417 10441 "rebuild of vsi_idx %d failed: %d\n", 10418 10442 v, ret); 10419 - goto end_reconstitute; 10443 + return ret; 10420 10444 } 10421 10445 i40e_vsi_reset_stats(vsi); 10422 10446 } 10423 10447 } 10424 10448 10425 - /* create any VEBs attached to this VEB - RECURSION */ 10426 - for (veb_idx = 0; veb_idx < I40E_MAX_VEB; veb_idx++) { 10427 - if (pf->veb[veb_idx] && pf->veb[veb_idx]->veb_idx == veb->idx) { 10428 - pf->veb[veb_idx]->uplink_seid = veb->seid; 10429 - ret = i40e_reconstitute_veb(pf->veb[veb_idx]); 10430 - if (ret) 10431 - break; 10432 - } 10433 - } 10434 - 10435 - end_reconstitute: 10436 10449 return ret; 10437 10450 } 10438 10451 ··· 10695 10718 static void i40e_prep_for_reset(struct i40e_pf *pf) 10696 10719 { 10697 10720 struct i40e_hw *hw = &pf->hw; 10721 + struct i40e_vsi *vsi; 10698 10722 int ret = 0; 10699 10723 u32 v; 10700 10724 ··· 10710 10732 /* quiesce the VSIs and their queues that are not already DOWN */ 10711 10733 i40e_pf_quiesce_all_vsi(pf); 10712 10734 10713 - for (v = 0; v < pf->num_alloc_vsi; v++) { 10714 - if (pf->vsi[v]) { 10715 - i40e_clean_xps_state(pf->vsi[v]); 10716 - pf->vsi[v]->seid = 0; 10717 - } 10735 + i40e_pf_for_each_vsi(pf, v, vsi) { 10736 + i40e_clean_xps_state(vsi); 10737 + vsi->seid = 0; 10718 10738 } 10719 10739 10720 10740 i40e_shutdown_adminq(&pf->hw); ··· 10826 10850 const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf); 10827 10851 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 10828 10852 struct i40e_hw *hw = &pf->hw; 10853 + struct i40e_veb *veb; 10829 10854 int ret; 10830 10855 u32 val; 10831 10856 int v; ··· 10968 10991 */ 10969 10992 if (vsi->uplink_seid != pf->mac_seid) { 10970 10993 dev_dbg(&pf->pdev->dev, "attempting to rebuild switch\n"); 10971 - /* find the one VEB connected to the MAC, and find orphans */ 10972 - for (v = 0; v < I40E_MAX_VEB; v++) { 10973 - if (!pf->veb[v]) 10994 + 10995 + /* Rebuild VEBs */ 10996 + i40e_pf_for_each_veb(pf, v, veb) { 10997 + ret = i40e_reconstitute_veb(veb); 10998 + if (!ret) 10974 10999 continue; 10975 11000 10976 - if (pf->veb[v]->uplink_seid == pf->mac_seid || 10977 - pf->veb[v]->uplink_seid == 0) { 10978 - ret = i40e_reconstitute_veb(pf->veb[v]); 10979 - 10980 - if (!ret) 10981 - continue; 10982 - 10983 - /* If Main VEB failed, we're in deep doodoo, 10984 - * so give up rebuilding the switch and set up 10985 - * for minimal rebuild of PF VSI. 10986 - * If orphan failed, we'll report the error 10987 - * but try to keep going. 10988 - */ 10989 - if (pf->veb[v]->uplink_seid == pf->mac_seid) { 10990 - dev_info(&pf->pdev->dev, 10991 - "rebuild of switch failed: %d, will try to set up simple PF connection\n", 10992 - ret); 10993 - vsi->uplink_seid = pf->mac_seid; 10994 - break; 10995 - } else if (pf->veb[v]->uplink_seid == 0) { 10996 - dev_info(&pf->pdev->dev, 10997 - "rebuild of orphan VEB failed: %d\n", 10998 - ret); 10999 - } 11001 + /* If Main VEB failed, we're in deep doodoo, 11002 + * so give up rebuilding the switch and set up 11003 + * for minimal rebuild of PF VSI. 11004 + * If orphan failed, we'll report the error 11005 + * but try to keep going. 11006 + */ 11007 + if (veb->uplink_seid == pf->mac_seid) { 11008 + dev_info(&pf->pdev->dev, 11009 + "rebuild of switch failed: %d, will try to set up simple PF connection\n", 11010 + ret); 11011 + vsi->uplink_seid = pf->mac_seid; 11012 + break; 11013 + } else if (veb->uplink_seid == 0) { 11014 + dev_info(&pf->pdev->dev, 11015 + "rebuild of orphan VEB failed: %d\n", 11016 + ret); 11000 11017 } 11001 11018 } 11002 11019 } ··· 12069 12098 */ 12070 12099 static int i40e_restore_interrupt_scheme(struct i40e_pf *pf) 12071 12100 { 12101 + struct i40e_vsi *vsi; 12072 12102 int err, i; 12073 12103 12074 12104 /* We cleared the MSI and MSI-X flags when disabling the old interrupt ··· 12086 12114 /* Now that we've re-acquired IRQs, we need to remap the vectors and 12087 12115 * rings together again. 12088 12116 */ 12089 - for (i = 0; i < pf->num_alloc_vsi; i++) { 12090 - if (pf->vsi[i]) { 12091 - err = i40e_vsi_alloc_q_vectors(pf->vsi[i]); 12092 - if (err) 12093 - goto err_unwind; 12094 - i40e_vsi_map_rings_to_vectors(pf->vsi[i]); 12095 - } 12117 + i40e_pf_for_each_vsi(pf, i, vsi) { 12118 + err = i40e_vsi_alloc_q_vectors(vsi); 12119 + if (err) 12120 + goto err_unwind; 12121 + 12122 + i40e_vsi_map_rings_to_vectors(vsi); 12096 12123 } 12097 12124 12098 12125 err = i40e_setup_misc_vector(pf); ··· 13093 13122 struct i40e_netdev_priv *np = netdev_priv(dev); 13094 13123 struct i40e_vsi *vsi = np->vsi; 13095 13124 struct i40e_pf *pf = vsi->back; 13096 - struct i40e_veb *veb = NULL; 13097 13125 struct nlattr *attr, *br_spec; 13098 - int i, rem; 13126 + struct i40e_veb *veb; 13127 + int rem; 13099 13128 13100 13129 /* Only for PF VSI for now */ 13101 13130 if (vsi->seid != pf->vsi[pf->lan_vsi]->seid) 13102 13131 return -EOPNOTSUPP; 13103 13132 13104 13133 /* Find the HW bridge for PF VSI */ 13105 - for (i = 0; i < I40E_MAX_VEB && !veb; i++) { 13106 - if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid) 13107 - veb = pf->veb[i]; 13108 - } 13134 + veb = i40e_pf_get_veb_by_seid(pf, vsi->uplink_seid); 13109 13135 13110 13136 br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); 13111 13137 if (!br_spec) ··· 13167 13199 struct i40e_netdev_priv *np = netdev_priv(dev); 13168 13200 struct i40e_vsi *vsi = np->vsi; 13169 13201 struct i40e_pf *pf = vsi->back; 13170 - struct i40e_veb *veb = NULL; 13171 - int i; 13202 + struct i40e_veb *veb; 13172 13203 13173 13204 /* Only for PF VSI for now */ 13174 13205 if (vsi->seid != pf->vsi[pf->lan_vsi]->seid) 13175 13206 return -EOPNOTSUPP; 13176 13207 13177 13208 /* Find the HW bridge for the PF VSI */ 13178 - for (i = 0; i < I40E_MAX_VEB && !veb; i++) { 13179 - if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid) 13180 - veb = pf->veb[i]; 13181 - } 13182 - 13209 + veb = i40e_pf_get_veb_by_seid(pf, vsi->uplink_seid); 13183 13210 if (!veb) 13184 13211 return 0; 13185 13212 ··· 14108 14145 { 14109 14146 struct i40e_mac_filter *f; 14110 14147 struct hlist_node *h; 14111 - struct i40e_veb *veb = NULL; 14148 + struct i40e_veb *veb; 14112 14149 struct i40e_pf *pf; 14113 14150 u16 uplink_seid; 14114 14151 int i, n, bkt; ··· 14172 14209 14173 14210 /* If this was the last thing on the VEB, except for the 14174 14211 * controlling VSI, remove the VEB, which puts the controlling 14175 - * VSI onto the next level down in the switch. 14212 + * VSI onto the uplink port. 14176 14213 * 14177 14214 * Well, okay, there's one more exception here: don't remove 14178 - * the orphan VEBs yet. We'll wait for an explicit remove request 14215 + * the floating VEBs yet. We'll wait for an explicit remove request 14179 14216 * from up the network stack. 14180 14217 */ 14181 - for (n = 0, i = 0; i < pf->num_alloc_vsi; i++) { 14182 - if (pf->vsi[i] && 14183 - pf->vsi[i]->uplink_seid == uplink_seid && 14184 - (pf->vsi[i]->flags & I40E_VSI_FLAG_VEB_OWNER) == 0) { 14185 - n++; /* count the VSIs */ 14186 - } 14218 + veb = i40e_pf_get_veb_by_seid(pf, uplink_seid); 14219 + if (veb && veb->uplink_seid) { 14220 + n = 0; 14221 + 14222 + /* Count non-controlling VSIs present on the VEB */ 14223 + i40e_pf_for_each_vsi(pf, i, vsi) 14224 + if (vsi->uplink_seid == uplink_seid && 14225 + (vsi->flags & I40E_VSI_FLAG_VEB_OWNER) == 0) 14226 + n++; 14227 + 14228 + /* If there is no VSI except the control one then release 14229 + * the VEB and put the control VSI onto VEB uplink. 14230 + */ 14231 + if (!n) 14232 + i40e_veb_release(veb); 14187 14233 } 14188 - for (i = 0; i < I40E_MAX_VEB; i++) { 14189 - if (!pf->veb[i]) 14190 - continue; 14191 - if (pf->veb[i]->uplink_seid == uplink_seid) 14192 - n++; /* count the VEBs */ 14193 - if (pf->veb[i]->seid == uplink_seid) 14194 - veb = pf->veb[i]; 14195 - } 14196 - if (n == 0 && veb && veb->uplink_seid != 0) 14197 - i40e_veb_release(veb); 14198 14234 14199 14235 return 0; 14200 14236 } ··· 14351 14389 struct i40e_vsi *vsi = NULL; 14352 14390 struct i40e_veb *veb = NULL; 14353 14391 u16 alloc_queue_pairs; 14354 - int ret, i; 14355 14392 int v_idx; 14393 + int ret; 14356 14394 14357 14395 /* The requested uplink_seid must be either 14358 14396 * - the PF's port seid ··· 14367 14405 * 14368 14406 * Find which uplink_seid we were given and create a new VEB if needed 14369 14407 */ 14370 - for (i = 0; i < I40E_MAX_VEB; i++) { 14371 - if (pf->veb[i] && pf->veb[i]->seid == uplink_seid) { 14372 - veb = pf->veb[i]; 14373 - break; 14374 - } 14375 - } 14376 - 14408 + veb = i40e_pf_get_veb_by_seid(pf, uplink_seid); 14377 14409 if (!veb && uplink_seid != pf->mac_seid) { 14378 - 14379 - for (i = 0; i < pf->num_alloc_vsi; i++) { 14380 - if (pf->vsi[i] && pf->vsi[i]->seid == uplink_seid) { 14381 - vsi = pf->vsi[i]; 14382 - break; 14383 - } 14384 - } 14410 + vsi = i40e_pf_get_vsi_by_seid(pf, uplink_seid); 14385 14411 if (!vsi) { 14386 14412 dev_info(&pf->pdev->dev, "no such uplink_seid %d\n", 14387 14413 uplink_seid); ··· 14398 14448 } 14399 14449 i40e_config_bridge_mode(veb); 14400 14450 } 14401 - for (i = 0; i < I40E_MAX_VEB && !veb; i++) { 14402 - if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid) 14403 - veb = pf->veb[i]; 14404 - } 14451 + veb = i40e_pf_get_veb_by_seid(pf, vsi->uplink_seid); 14405 14452 if (!veb) { 14406 14453 dev_info(&pf->pdev->dev, "couldn't add VEB\n"); 14407 14454 return NULL; ··· 14628 14681 struct i40e_pf *pf = branch->pf; 14629 14682 u16 branch_seid = branch->seid; 14630 14683 u16 veb_idx = branch->idx; 14684 + struct i40e_vsi *vsi; 14685 + struct i40e_veb *veb; 14631 14686 int i; 14632 14687 14633 14688 /* release any VEBs on this VEB - RECURSION */ 14634 - for (i = 0; i < I40E_MAX_VEB; i++) { 14635 - if (!pf->veb[i]) 14636 - continue; 14637 - if (pf->veb[i]->uplink_seid == branch->seid) 14638 - i40e_switch_branch_release(pf->veb[i]); 14639 - } 14689 + i40e_pf_for_each_veb(pf, i, veb) 14690 + if (veb->uplink_seid == branch->seid) 14691 + i40e_switch_branch_release(veb); 14640 14692 14641 14693 /* Release the VSIs on this VEB, but not the owner VSI. 14642 14694 * 14643 14695 * NOTE: Removing the last VSI on a VEB has the SIDE EFFECT of removing 14644 14696 * the VEB itself, so don't use (*branch) after this loop. 14645 14697 */ 14646 - for (i = 0; i < pf->num_alloc_vsi; i++) { 14647 - if (!pf->vsi[i]) 14648 - continue; 14649 - if (pf->vsi[i]->uplink_seid == branch_seid && 14650 - (pf->vsi[i]->flags & I40E_VSI_FLAG_VEB_OWNER) == 0) { 14651 - i40e_vsi_release(pf->vsi[i]); 14652 - } 14653 - } 14698 + i40e_pf_for_each_vsi(pf, i, vsi) 14699 + if (vsi->uplink_seid == branch_seid && 14700 + (vsi->flags & I40E_VSI_FLAG_VEB_OWNER) == 0) 14701 + i40e_vsi_release(vsi); 14654 14702 14655 14703 /* There's one corner case where the VEB might not have been 14656 14704 * removed, so double check it here and remove it if needed. ··· 14683 14741 **/ 14684 14742 void i40e_veb_release(struct i40e_veb *veb) 14685 14743 { 14686 - struct i40e_vsi *vsi = NULL; 14744 + struct i40e_vsi *vsi, *vsi_it; 14687 14745 struct i40e_pf *pf; 14688 14746 int i, n = 0; 14689 14747 14690 14748 pf = veb->pf; 14691 14749 14692 14750 /* find the remaining VSI and check for extras */ 14693 - for (i = 0; i < pf->num_alloc_vsi; i++) { 14694 - if (pf->vsi[i] && pf->vsi[i]->uplink_seid == veb->seid) { 14751 + i40e_pf_for_each_vsi(pf, i, vsi_it) 14752 + if (vsi_it->uplink_seid == veb->seid) { 14753 + if (vsi_it->flags & I40E_VSI_FLAG_VEB_OWNER) 14754 + vsi = vsi_it; 14695 14755 n++; 14696 - vsi = pf->vsi[i]; 14697 14756 } 14698 - } 14699 - if (n != 1) { 14757 + 14758 + /* Floating VEB has to be empty and regular one must have 14759 + * single owner VSI. 14760 + */ 14761 + if ((veb->uplink_seid && n != 1) || (!veb->uplink_seid && n != 0)) { 14700 14762 dev_info(&pf->pdev->dev, 14701 14763 "can't remove VEB %d with %d VSIs left\n", 14702 14764 veb->seid, n); 14703 14765 return; 14704 14766 } 14705 14767 14706 - /* move the remaining VSI to uplink veb */ 14707 - vsi->flags &= ~I40E_VSI_FLAG_VEB_OWNER; 14768 + /* For regular VEB move the owner VSI to uplink port */ 14708 14769 if (veb->uplink_seid) { 14770 + vsi->flags &= ~I40E_VSI_FLAG_VEB_OWNER; 14709 14771 vsi->uplink_seid = veb->uplink_seid; 14710 - if (veb->uplink_seid == pf->mac_seid) 14711 - vsi->veb_idx = I40E_NO_VEB; 14712 - else 14713 - vsi->veb_idx = veb->veb_idx; 14714 - } else { 14715 - /* floating VEB */ 14716 - vsi->uplink_seid = pf->vsi[pf->lan_vsi]->uplink_seid; 14717 - vsi->veb_idx = pf->vsi[pf->lan_vsi]->veb_idx; 14772 + vsi->veb_idx = I40E_NO_VEB; 14718 14773 } 14719 14774 14720 14775 i40e_aq_delete_element(&pf->hw, veb->seid, NULL); ··· 14729 14790 bool enable_stats = !!test_bit(I40E_FLAG_VEB_STATS_ENA, pf->flags); 14730 14791 int ret; 14731 14792 14732 - ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid, 14733 - veb->enabled_tc, false, 14793 + ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi ? vsi->seid : 0, 14794 + veb->enabled_tc, vsi ? false : true, 14734 14795 &veb->seid, enable_stats, NULL); 14735 14796 14736 14797 /* get a VEB from the hardware */ ··· 14762 14823 return -ENOENT; 14763 14824 } 14764 14825 14765 - vsi->uplink_seid = veb->seid; 14766 - vsi->veb_idx = veb->idx; 14767 - vsi->flags |= I40E_VSI_FLAG_VEB_OWNER; 14826 + if (vsi) { 14827 + vsi->uplink_seid = veb->seid; 14828 + vsi->veb_idx = veb->idx; 14829 + vsi->flags |= I40E_VSI_FLAG_VEB_OWNER; 14830 + } 14768 14831 14769 14832 return 0; 14770 14833 } ··· 14791 14850 u16 uplink_seid, u16 vsi_seid, 14792 14851 u8 enabled_tc) 14793 14852 { 14794 - struct i40e_veb *veb, *uplink_veb = NULL; 14795 - int vsi_idx, veb_idx; 14853 + struct i40e_vsi *vsi = NULL; 14854 + struct i40e_veb *veb; 14855 + int veb_idx; 14796 14856 int ret; 14797 14857 14798 14858 /* if one seid is 0, the other must be 0 to create a floating relay */ ··· 14806 14864 } 14807 14865 14808 14866 /* make sure there is such a vsi and uplink */ 14809 - for (vsi_idx = 0; vsi_idx < pf->num_alloc_vsi; vsi_idx++) 14810 - if (pf->vsi[vsi_idx] && pf->vsi[vsi_idx]->seid == vsi_seid) 14811 - break; 14812 - if (vsi_idx == pf->num_alloc_vsi && vsi_seid != 0) { 14813 - dev_info(&pf->pdev->dev, "vsi seid %d not found\n", 14814 - vsi_seid); 14815 - return NULL; 14816 - } 14817 - 14818 - if (uplink_seid && uplink_seid != pf->mac_seid) { 14819 - for (veb_idx = 0; veb_idx < I40E_MAX_VEB; veb_idx++) { 14820 - if (pf->veb[veb_idx] && 14821 - pf->veb[veb_idx]->seid == uplink_seid) { 14822 - uplink_veb = pf->veb[veb_idx]; 14823 - break; 14824 - } 14825 - } 14826 - if (!uplink_veb) { 14827 - dev_info(&pf->pdev->dev, 14828 - "uplink seid %d not found\n", uplink_seid); 14867 + if (vsi_seid) { 14868 + vsi = i40e_pf_get_vsi_by_seid(pf, vsi_seid); 14869 + if (!vsi) { 14870 + dev_err(&pf->pdev->dev, "vsi seid %d not found\n", 14871 + vsi_seid); 14829 14872 return NULL; 14830 14873 } 14831 14874 } ··· 14822 14895 veb = pf->veb[veb_idx]; 14823 14896 veb->flags = flags; 14824 14897 veb->uplink_seid = uplink_seid; 14825 - veb->veb_idx = (uplink_veb ? uplink_veb->idx : I40E_NO_VEB); 14826 14898 veb->enabled_tc = (enabled_tc ? enabled_tc : 0x1); 14827 14899 14828 14900 /* create the VEB in the switch */ 14829 - ret = i40e_add_veb(veb, pf->vsi[vsi_idx]); 14901 + ret = i40e_add_veb(veb, vsi); 14830 14902 if (ret) 14831 14903 goto err_veb; 14832 - if (vsi_idx == pf->lan_vsi) 14904 + 14905 + if (vsi && vsi->idx == pf->lan_vsi) 14833 14906 pf->lan_veb = veb->idx; 14834 14907 14835 14908 return veb; ··· 14857 14930 u16 uplink_seid = le16_to_cpu(ele->uplink_seid); 14858 14931 u8 element_type = ele->element_type; 14859 14932 u16 seid = le16_to_cpu(ele->seid); 14933 + struct i40e_veb *veb; 14860 14934 14861 14935 if (printconfig) 14862 14936 dev_info(&pf->pdev->dev, ··· 14876 14948 int v; 14877 14949 14878 14950 /* find existing or else empty VEB */ 14879 - for (v = 0; v < I40E_MAX_VEB; v++) { 14880 - if (pf->veb[v] && (pf->veb[v]->seid == seid)) { 14881 - pf->lan_veb = v; 14882 - break; 14883 - } 14884 - } 14885 - if (pf->lan_veb >= I40E_MAX_VEB) { 14951 + veb = i40e_pf_get_veb_by_seid(pf, seid); 14952 + if (veb) { 14953 + pf->lan_veb = veb->idx; 14954 + } else { 14886 14955 v = i40e_veb_mem_alloc(pf); 14887 14956 if (v < 0) 14888 14957 break; ··· 14892 14967 pf->veb[pf->lan_veb]->seid = seid; 14893 14968 pf->veb[pf->lan_veb]->uplink_seid = pf->mac_seid; 14894 14969 pf->veb[pf->lan_veb]->pf = pf; 14895 - pf->veb[pf->lan_veb]->veb_idx = I40E_NO_VEB; 14896 14970 break; 14897 14971 case I40E_SWITCH_ELEMENT_TYPE_VSI: 14898 14972 if (num_reported != 1) ··· 15554 15630 #ifdef CONFIG_I40E_DCB 15555 15631 enum i40e_get_fw_lldp_status_resp lldp_status; 15556 15632 #endif /* CONFIG_I40E_DCB */ 15633 + struct i40e_vsi *vsi; 15557 15634 struct i40e_pf *pf; 15558 15635 struct i40e_hw *hw; 15559 15636 u16 wol_nvm_bits; ··· 15565 15640 #endif /* CONFIG_I40E_DCB */ 15566 15641 int err; 15567 15642 u32 val; 15568 - u32 i; 15569 15643 15570 15644 err = pci_enable_device_mem(pdev); 15571 15645 if (err) ··· 15914 15990 INIT_LIST_HEAD(&pf->vsi[pf->lan_vsi]->ch_list); 15915 15991 15916 15992 /* if FDIR VSI was set up, start it now */ 15917 - for (i = 0; i < pf->num_alloc_vsi; i++) { 15918 - if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) { 15919 - i40e_vsi_open(pf->vsi[i]); 15920 - break; 15921 - } 15922 - } 15993 + vsi = i40e_find_vsi_by_type(pf, I40E_VSI_FDIR); 15994 + if (vsi) 15995 + i40e_vsi_open(vsi); 15923 15996 15924 15997 /* The driver only wants link up/down and module qualification 15925 15998 * reports from firmware. Note the negative logic. ··· 16162 16241 { 16163 16242 struct i40e_pf *pf = pci_get_drvdata(pdev); 16164 16243 struct i40e_hw *hw = &pf->hw; 16244 + struct i40e_vsi *vsi; 16245 + struct i40e_veb *veb; 16165 16246 int ret_code; 16166 16247 int i; 16167 16248 ··· 16221 16298 /* If there is a switch structure or any orphans, remove them. 16222 16299 * This will leave only the PF's VSI remaining. 16223 16300 */ 16224 - for (i = 0; i < I40E_MAX_VEB; i++) { 16225 - if (!pf->veb[i]) 16226 - continue; 16227 - 16228 - if (pf->veb[i]->uplink_seid == pf->mac_seid || 16229 - pf->veb[i]->uplink_seid == 0) 16230 - i40e_switch_branch_release(pf->veb[i]); 16231 - } 16301 + i40e_pf_for_each_veb(pf, i, veb) 16302 + if (veb->uplink_seid == pf->mac_seid || 16303 + veb->uplink_seid == 0) 16304 + i40e_switch_branch_release(veb); 16232 16305 16233 16306 /* Now we can shutdown the PF's VSIs, just before we kill 16234 16307 * adminq and hmc. 16235 16308 */ 16236 - for (i = pf->num_alloc_vsi; i--;) 16237 - if (pf->vsi[i]) { 16238 - i40e_vsi_close(pf->vsi[i]); 16239 - i40e_vsi_release(pf->vsi[i]); 16240 - pf->vsi[i] = NULL; 16241 - } 16309 + i40e_pf_for_each_vsi(pf, i, vsi) { 16310 + i40e_vsi_close(vsi); 16311 + i40e_vsi_release(vsi); 16312 + pf->vsi[i] = NULL; 16313 + } 16242 16314 16243 16315 i40e_cloud_filter_exit(pf); 16244 16316 ··· 16270 16352 /* Clear all dynamic memory lists of rings, q_vectors, and VSIs */ 16271 16353 rtnl_lock(); 16272 16354 i40e_clear_interrupt_scheme(pf); 16273 - for (i = 0; i < pf->num_alloc_vsi; i++) { 16274 - if (pf->vsi[i]) { 16275 - if (!test_bit(__I40E_RECOVERY_MODE, pf->state)) 16276 - i40e_vsi_clear_rings(pf->vsi[i]); 16277 - i40e_vsi_clear(pf->vsi[i]); 16278 - pf->vsi[i] = NULL; 16279 - } 16355 + i40e_pf_for_each_vsi(pf, i, vsi) { 16356 + if (!test_bit(__I40E_RECOVERY_MODE, pf->state)) 16357 + i40e_vsi_clear_rings(vsi); 16358 + 16359 + i40e_vsi_clear(vsi); 16360 + pf->vsi[i] = NULL; 16280 16361 } 16281 16362 rtnl_unlock(); 16282 16363 16283 - for (i = 0; i < I40E_MAX_VEB; i++) { 16284 - kfree(pf->veb[i]); 16364 + i40e_pf_for_each_veb(pf, i, veb) { 16365 + kfree(veb); 16285 16366 pf->veb[i] = NULL; 16286 16367 } 16287 16368