@@ -1106,39 +1106,81 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
11061106 return - EIO ;
11071107}
11081108
1109- static inline int i40e_getnum_vf_vsi_vlan_filters (struct i40e_vsi * vsi );
1109+ /**
1110+ * i40e_getnum_vf_vsi_vlan_filters
1111+ * @vsi: pointer to the vsi
1112+ *
1113+ * called to get the number of VLANs offloaded on this VF
1114+ **/
1115+ static int i40e_getnum_vf_vsi_vlan_filters (struct i40e_vsi * vsi )
1116+ {
1117+ struct i40e_mac_filter * f ;
1118+ int num_vlans = 0 , bkt ;
1119+
1120+ hash_for_each (vsi -> mac_filter_hash , bkt , f , hlist ) {
1121+ if (f -> vlan >= 0 && f -> vlan <= I40E_MAX_VLANID )
1122+ num_vlans ++ ;
1123+ }
1124+
1125+ return num_vlans ;
1126+ }
11101127
11111128/**
1112- * i40e_config_vf_promiscuous_mode
1113- * @vf : pointer to the VF info
1114- * @vsi_id: VSI id
1115- * @allmulti: set MAC L2 layer multicast promiscuous enable/disable
1116- * @alluni: set MAC L2 layer unicast promiscuous enable/disable
1129+ * i40e_get_vlan_list_sync
1130+ * @vsi : pointer to the VSI
1131+ * @num_vlans: number of VLANs in mac_filter_hash, returned to caller
1132+ * @vlan_list: list of VLANs present in mac_filter_hash, returned to caller.
1133+ * This array is allocated here, but has to be freed in caller.
11171134 *
1118- * Called from the VF to configure the promiscuous mode of
1119- * VF vsis and from the VF reset path to reset promiscuous mode.
1135+ * Called to get number of VLANs and VLAN list present in mac_filter_hash.
11201136 **/
1121- static i40e_status i40e_config_vf_promiscuous_mode (struct i40e_vf * vf ,
1122- u16 vsi_id ,
1123- bool allmulti ,
1124- bool alluni )
1137+ static void i40e_get_vlan_list_sync (struct i40e_vsi * vsi , int * num_vlans ,
1138+ s16 * * vlan_list )
11251139{
1126- struct i40e_pf * pf = vf -> pf ;
1127- struct i40e_hw * hw = & pf -> hw ;
11281140 struct i40e_mac_filter * f ;
1129- i40e_status aq_ret = 0 ;
1130- struct i40e_vsi * vsi ;
1141+ int i = 0 ;
11311142 int bkt ;
11321143
1133- vsi = i40e_find_vsi_from_id (pf , vsi_id );
1134- if (!i40e_vc_isvalid_vsi_id (vf , vsi_id ) || !vsi )
1135- return I40E_ERR_PARAM ;
1144+ spin_lock_bh (& vsi -> mac_filter_hash_lock );
1145+ * num_vlans = i40e_getnum_vf_vsi_vlan_filters (vsi );
1146+ * vlan_list = kcalloc (* num_vlans , sizeof (* * vlan_list ), GFP_ATOMIC );
1147+ if (!(* vlan_list ))
1148+ goto err ;
11361149
1137- if (vf -> port_vlan_id ) {
1138- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan (hw , vsi -> seid ,
1139- allmulti ,
1140- vf -> port_vlan_id ,
1141- NULL );
1150+ hash_for_each (vsi -> mac_filter_hash , bkt , f , hlist ) {
1151+ if (f -> vlan < 0 || f -> vlan > I40E_MAX_VLANID )
1152+ continue ;
1153+ (* vlan_list )[i ++ ] = f -> vlan ;
1154+ }
1155+ err :
1156+ spin_unlock_bh (& vsi -> mac_filter_hash_lock );
1157+ }
1158+
1159+ /**
1160+ * i40e_set_vsi_promisc
1161+ * @vf: pointer to the VF struct
1162+ * @seid: VSI number
1163+ * @multi_enable: set MAC L2 layer multicast promiscuous enable/disable
1164+ * for a given VLAN
1165+ * @unicast_enable: set MAC L2 layer unicast promiscuous enable/disable
1166+ * for a given VLAN
1167+ * @vl: List of VLANs - apply filter for given VLANs
1168+ * @num_vlans: Number of elements in @vl
1169+ **/
1170+ static i40e_status
1171+ i40e_set_vsi_promisc (struct i40e_vf * vf , u16 seid , bool multi_enable ,
1172+ bool unicast_enable , s16 * vl , int num_vlans )
1173+ {
1174+ struct i40e_pf * pf = vf -> pf ;
1175+ struct i40e_hw * hw = & pf -> hw ;
1176+ i40e_status aq_ret ;
1177+ int i ;
1178+
1179+ /* No VLAN to set promisc on, set on VSI */
1180+ if (!num_vlans || !vl ) {
1181+ aq_ret = i40e_aq_set_vsi_multicast_promiscuous (hw , seid ,
1182+ multi_enable ,
1183+ NULL );
11421184 if (aq_ret ) {
11431185 int aq_err = pf -> hw .aq .asq_last_status ;
11441186
@@ -1147,13 +1189,14 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
11471189 vf -> vf_id ,
11481190 i40e_stat_str (& pf -> hw , aq_ret ),
11491191 i40e_aq_str (& pf -> hw , aq_err ));
1192+
11501193 return aq_ret ;
11511194 }
11521195
1153- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan (hw , vsi -> seid ,
1154- alluni ,
1155- vf -> port_vlan_id ,
1156- NULL );
1196+ aq_ret = i40e_aq_set_vsi_unicast_promiscuous (hw , seid ,
1197+ unicast_enable ,
1198+ NULL , true);
1199+
11571200 if (aq_ret ) {
11581201 int aq_err = pf -> hw .aq .asq_last_status ;
11591202
@@ -1163,68 +1206,84 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
11631206 i40e_stat_str (& pf -> hw , aq_ret ),
11641207 i40e_aq_str (& pf -> hw , aq_err ));
11651208 }
1209+
11661210 return aq_ret ;
1167- } else if (i40e_getnum_vf_vsi_vlan_filters (vsi )) {
1168- hash_for_each (vsi -> mac_filter_hash , bkt , f , hlist ) {
1169- if (f -> vlan < 0 || f -> vlan > I40E_MAX_VLANID )
1170- continue ;
1171- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan (hw ,
1172- vsi -> seid ,
1173- allmulti ,
1174- f -> vlan ,
1175- NULL );
1176- if (aq_ret ) {
1177- int aq_err = pf -> hw .aq .asq_last_status ;
1211+ }
11781212
1179- dev_err (& pf -> pdev -> dev ,
1180- "Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n" ,
1181- f -> vlan ,
1182- i40e_stat_str (& pf -> hw , aq_ret ),
1183- i40e_aq_str (& pf -> hw , aq_err ));
1184- }
1213+ for (i = 0 ; i < num_vlans ; i ++ ) {
1214+ aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan (hw , seid ,
1215+ multi_enable ,
1216+ vl [i ], NULL );
1217+ if (aq_ret ) {
1218+ int aq_err = pf -> hw .aq .asq_last_status ;
1219+
1220+ dev_err (& pf -> pdev -> dev ,
1221+ "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" ,
1222+ vf -> vf_id ,
1223+ i40e_stat_str (& pf -> hw , aq_ret ),
1224+ i40e_aq_str (& pf -> hw , aq_err ));
1225+ }
11851226
1186- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan (hw ,
1187- vsi -> seid ,
1188- alluni ,
1189- f -> vlan ,
1190- NULL );
1191- if (aq_ret ) {
1192- int aq_err = pf -> hw .aq .asq_last_status ;
1227+ aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan (hw , seid ,
1228+ unicast_enable ,
1229+ vl [i ], NULL );
1230+ if (aq_ret ) {
1231+ int aq_err = pf -> hw .aq .asq_last_status ;
11931232
1194- dev_err (& pf -> pdev -> dev ,
1195- "Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n" ,
1196- f -> vlan ,
1197- i40e_stat_str (& pf -> hw , aq_ret ),
1198- i40e_aq_str (& pf -> hw , aq_err ));
1199- }
1233+ dev_err (& pf -> pdev -> dev ,
1234+ "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" ,
1235+ vf -> vf_id ,
1236+ i40e_stat_str (& pf -> hw , aq_ret ),
1237+ i40e_aq_str (& pf -> hw , aq_err ));
12001238 }
1201- return aq_ret ;
12021239 }
1203- aq_ret = i40e_aq_set_vsi_multicast_promiscuous (hw , vsi -> seid , allmulti ,
1204- NULL );
1205- if (aq_ret ) {
1206- int aq_err = pf -> hw .aq .asq_last_status ;
1240+ return aq_ret ;
1241+ }
12071242
1208- dev_err (& pf -> pdev -> dev ,
1209- "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" ,
1210- vf -> vf_id ,
1211- i40e_stat_str (& pf -> hw , aq_ret ),
1212- i40e_aq_str (& pf -> hw , aq_err ));
1243+ /**
1244+ * i40e_config_vf_promiscuous_mode
1245+ * @vf: pointer to the VF info
1246+ * @vsi_id: VSI id
1247+ * @allmulti: set MAC L2 layer multicast promiscuous enable/disable
1248+ * @alluni: set MAC L2 layer unicast promiscuous enable/disable
1249+ *
1250+ * Called from the VF to configure the promiscuous mode of
1251+ * VF vsis and from the VF reset path to reset promiscuous mode.
1252+ **/
1253+ static i40e_status i40e_config_vf_promiscuous_mode (struct i40e_vf * vf ,
1254+ u16 vsi_id ,
1255+ bool allmulti ,
1256+ bool alluni )
1257+ {
1258+ i40e_status aq_ret = I40E_SUCCESS ;
1259+ struct i40e_pf * pf = vf -> pf ;
1260+ struct i40e_vsi * vsi ;
1261+ int num_vlans ;
1262+ s16 * vl ;
1263+
1264+ vsi = i40e_find_vsi_from_id (pf , vsi_id );
1265+ if (!i40e_vc_isvalid_vsi_id (vf , vsi_id ) || !vsi )
1266+ return I40E_ERR_PARAM ;
1267+
1268+ if (vf -> port_vlan_id ) {
1269+ aq_ret = i40e_set_vsi_promisc (vf , vsi -> seid , allmulti ,
1270+ alluni , & vf -> port_vlan_id , 1 );
12131271 return aq_ret ;
1214- }
1272+ } else if (i40e_getnum_vf_vsi_vlan_filters (vsi )) {
1273+ i40e_get_vlan_list_sync (vsi , & num_vlans , & vl );
12151274
1216- aq_ret = i40e_aq_set_vsi_unicast_promiscuous (hw , vsi -> seid , alluni ,
1217- NULL , true);
1218- if (aq_ret ) {
1219- int aq_err = pf -> hw .aq .asq_last_status ;
1275+ if (!vl )
1276+ return I40E_ERR_NO_MEMORY ;
12201277
1221- dev_err (& pf -> pdev -> dev ,
1222- "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" ,
1223- vf -> vf_id ,
1224- i40e_stat_str (& pf -> hw , aq_ret ),
1225- i40e_aq_str (& pf -> hw , aq_err ));
1278+ aq_ret = i40e_set_vsi_promisc (vf , vsi -> seid , allmulti , alluni ,
1279+ vl , num_vlans );
1280+ kfree (vl );
1281+ return aq_ret ;
12261282 }
12271283
1284+ /* no VLANs to set on, set on VSI */
1285+ aq_ret = i40e_set_vsi_promisc (vf , vsi -> seid , allmulti , alluni ,
1286+ NULL , 0 );
12281287 return aq_ret ;
12291288}
12301289
@@ -1972,25 +2031,6 @@ static void i40e_vc_reset_vf_msg(struct i40e_vf *vf)
19722031 i40e_reset_vf (vf , false);
19732032}
19742033
1975- /**
1976- * i40e_getnum_vf_vsi_vlan_filters
1977- * @vsi: pointer to the vsi
1978- *
1979- * called to get the number of VLANs offloaded on this VF
1980- **/
1981- static inline int i40e_getnum_vf_vsi_vlan_filters (struct i40e_vsi * vsi )
1982- {
1983- struct i40e_mac_filter * f ;
1984- int num_vlans = 0 , bkt ;
1985-
1986- hash_for_each (vsi -> mac_filter_hash , bkt , f , hlist ) {
1987- if (f -> vlan >= 0 && f -> vlan <= I40E_MAX_VLANID )
1988- num_vlans ++ ;
1989- }
1990-
1991- return num_vlans ;
1992- }
1993-
19942034/**
19952035 * i40e_vc_config_promiscuous_mode_msg
19962036 * @vf: pointer to the VF info
0 commit comments