@@ -19,8 +19,11 @@ static const u8 lacp_train_pkt[LACP_TRAIN_PKT_LEN] = { 0, 0, 0, 0, 0, 0,
19
19
static const u8 ice_dflt_vsi_rcp [ICE_RECIPE_LEN ] = {
20
20
0x05 , 0 , 0 , 0 , 0x20 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
21
21
0x85 , 0 , 0x01 , 0 , 0 , 0 , 0xff , 0xff , 0x08 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
22
- 0 , 0 , 0 , 0 , 0 , 0 , 0x30 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
23
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
22
+ 0 , 0 , 0 , 0 , 0 , 0 , 0x30 };
23
+ static const u8 ice_lport_rcp [ICE_RECIPE_LEN ] = {
24
+ 0x05 , 0 , 0 , 0 , 0x20 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
25
+ 0x85 , 0 , 0x16 , 0 , 0 , 0 , 0xff , 0xff , 0x07 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
26
+ 0 , 0 , 0 , 0 , 0 , 0 , 0x30 };
24
27
25
28
/**
26
29
* ice_lag_set_primary - set PF LAG state as Primary
@@ -173,18 +176,22 @@ static struct ice_lag *ice_lag_find_primary(struct ice_lag *lag)
173
176
}
174
177
175
178
/**
176
- * ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
179
+ * ice_lag_cfg_fltr - Add/Remove rule for LAG
177
180
* @lag: lag struct for local interface
181
+ * @act: rule action
182
+ * @recipe_id: recipe id for the new rule
183
+ * @rule_idx: pointer to rule index
178
184
* @add: boolean on whether we are adding filters
179
185
*/
180
186
static int
181
- ice_lag_cfg_dflt_fltr (struct ice_lag * lag , bool add )
187
+ ice_lag_cfg_fltr (struct ice_lag * lag , u32 act , u16 recipe_id , u16 * rule_idx ,
188
+ bool add )
182
189
{
183
190
struct ice_sw_rule_lkup_rx_tx * s_rule ;
184
191
u16 s_rule_sz , vsi_num ;
185
192
struct ice_hw * hw ;
186
- u32 act , opc ;
187
193
u8 * eth_hdr ;
194
+ u32 opc ;
188
195
int err ;
189
196
190
197
hw = & lag -> pf -> hw ;
@@ -193,27 +200,25 @@ ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
193
200
s_rule_sz = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE (s_rule );
194
201
s_rule = kzalloc (s_rule_sz , GFP_KERNEL );
195
202
if (!s_rule ) {
196
- dev_err (ice_pf_to_dev (lag -> pf ), "error allocating rule for LAG default VSI \n" );
203
+ dev_err (ice_pf_to_dev (lag -> pf ), "error allocating rule for LAG\n" );
197
204
return - ENOMEM ;
198
205
}
199
206
200
207
if (add ) {
201
208
eth_hdr = s_rule -> hdr_data ;
202
209
ice_fill_eth_hdr (eth_hdr );
203
210
204
- act = (vsi_num << ICE_SINGLE_ACT_VSI_ID_S ) &
211
+ act | = (vsi_num << ICE_SINGLE_ACT_VSI_ID_S ) &
205
212
ICE_SINGLE_ACT_VSI_ID_M ;
206
- act |= ICE_SINGLE_ACT_VSI_FORWARDING |
207
- ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE ;
208
213
209
214
s_rule -> hdr .type = cpu_to_le16 (ICE_AQC_SW_RULES_T_LKUP_RX );
210
- s_rule -> recipe_id = cpu_to_le16 (lag -> pf_recipe );
215
+ s_rule -> recipe_id = cpu_to_le16 (recipe_id );
211
216
s_rule -> src = cpu_to_le16 (hw -> port_info -> lport );
212
217
s_rule -> act = cpu_to_le32 (act );
213
218
s_rule -> hdr_len = cpu_to_le16 (DUMMY_ETH_HDR_LEN );
214
219
opc = ice_aqc_opc_add_sw_rules ;
215
220
} else {
216
- s_rule -> index = cpu_to_le16 (lag -> pf_rule_id );
221
+ s_rule -> index = cpu_to_le16 (* rule_idx );
217
222
opc = ice_aqc_opc_remove_sw_rules ;
218
223
}
219
224
@@ -222,15 +227,46 @@ ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
222
227
goto dflt_fltr_free ;
223
228
224
229
if (add )
225
- lag -> pf_rule_id = le16_to_cpu (s_rule -> index );
230
+ * rule_idx = le16_to_cpu (s_rule -> index );
226
231
else
227
- lag -> pf_rule_id = 0 ;
232
+ * rule_idx = 0 ;
228
233
229
234
dflt_fltr_free :
230
235
kfree (s_rule );
231
236
return err ;
232
237
}
233
238
239
+ /**
240
+ * ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
241
+ * @lag: lag struct for local interface
242
+ * @add: boolean on whether to add filter
243
+ */
244
+ static int
245
+ ice_lag_cfg_dflt_fltr (struct ice_lag * lag , bool add )
246
+ {
247
+ u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
248
+ ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE ;
249
+
250
+ return ice_lag_cfg_fltr (lag , act , lag -> pf_recipe ,
251
+ & lag -> pf_rule_id , add );
252
+ }
253
+
254
+ /**
255
+ * ice_lag_cfg_drop_fltr - Add/Remove lport drop rule
256
+ * @lag: lag struct for local interface
257
+ * @add: boolean on whether to add filter
258
+ */
259
+ static int
260
+ ice_lag_cfg_drop_fltr (struct ice_lag * lag , bool add )
261
+ {
262
+ u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
263
+ ICE_SINGLE_ACT_VALID_BIT |
264
+ ICE_SINGLE_ACT_DROP ;
265
+
266
+ return ice_lag_cfg_fltr (lag , act , lag -> lport_recipe ,
267
+ & lag -> lport_rule_idx , add );
268
+ }
269
+
234
270
/**
235
271
* ice_lag_cfg_pf_fltrs - set filters up for new active port
236
272
* @lag: local interfaces lag struct
@@ -257,13 +293,18 @@ ice_lag_cfg_pf_fltrs(struct ice_lag *lag, void *ptr)
257
293
if (bonding_info -> slave .state && lag -> pf_rule_id ) {
258
294
if (ice_lag_cfg_dflt_fltr (lag , false))
259
295
dev_err (dev , "Error removing old default VSI filter\n" );
296
+ if (ice_lag_cfg_drop_fltr (lag , true))
297
+ dev_err (dev , "Error adding new drop filter\n" );
260
298
return ;
261
299
}
262
300
263
301
/* interface becoming active - add new default VSI rule */
264
- if (!bonding_info -> slave .state && !lag -> pf_rule_id )
302
+ if (!bonding_info -> slave .state && !lag -> pf_rule_id ) {
265
303
if (ice_lag_cfg_dflt_fltr (lag , true))
266
304
dev_err (dev , "Error adding new default VSI filter\n" );
305
+ if (lag -> lport_rule_idx && ice_lag_cfg_drop_fltr (lag , false))
306
+ dev_err (dev , "Error removing old drop filter\n" );
307
+ }
267
308
}
268
309
269
310
/**
@@ -1179,6 +1220,7 @@ static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
1179
1220
swid = primary_lag -> pf -> hw .port_info -> sw_id ;
1180
1221
ice_lag_set_swid (swid , lag , true);
1181
1222
ice_lag_add_prune_list (primary_lag , lag -> pf );
1223
+ ice_lag_cfg_drop_fltr (lag , true);
1182
1224
}
1183
1225
/* add filter for primary control packets */
1184
1226
ice_lag_cfg_cp_fltr (lag , true);
@@ -1929,11 +1971,16 @@ int ice_init_lag(struct ice_pf *pf)
1929
1971
goto lag_error ;
1930
1972
}
1931
1973
1932
- err = ice_create_lag_recipe (& pf -> hw , & lag -> pf_recipe , ice_dflt_vsi_rcp ,
1933
- 1 );
1974
+ err = ice_create_lag_recipe (& pf -> hw , & lag -> pf_recipe ,
1975
+ ice_dflt_vsi_rcp , 1 );
1934
1976
if (err )
1935
1977
goto lag_error ;
1936
1978
1979
+ err = ice_create_lag_recipe (& pf -> hw , & lag -> lport_recipe ,
1980
+ ice_lport_rcp , 3 );
1981
+ if (err )
1982
+ goto free_rcp_res ;
1983
+
1937
1984
/* associate recipes to profiles */
1938
1985
for (n = 0 ; n < ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER ; n ++ ) {
1939
1986
err = ice_aq_get_recipe_to_profile (& pf -> hw , n ,
@@ -1942,7 +1989,8 @@ int ice_init_lag(struct ice_pf *pf)
1942
1989
continue ;
1943
1990
1944
1991
if (recipe_bits & BIT (ICE_SW_LKUP_DFLT )) {
1945
- recipe_bits |= BIT (lag -> pf_recipe );
1992
+ recipe_bits |= BIT (lag -> pf_recipe ) |
1993
+ BIT (lag -> lport_recipe );
1946
1994
ice_aq_map_recipe_to_profile (& pf -> hw , n ,
1947
1995
(u8 * )& recipe_bits , NULL );
1948
1996
}
@@ -1953,6 +2001,9 @@ int ice_init_lag(struct ice_pf *pf)
1953
2001
dev_dbg (dev , "INIT LAG complete\n" );
1954
2002
return 0 ;
1955
2003
2004
+ free_rcp_res :
2005
+ ice_free_hw_res (& pf -> hw , ICE_AQC_RES_TYPE_RECIPE , 1 ,
2006
+ & pf -> lag -> pf_recipe );
1956
2007
lag_error :
1957
2008
kfree (lag );
1958
2009
pf -> lag = NULL ;
@@ -1982,6 +2033,8 @@ void ice_deinit_lag(struct ice_pf *pf)
1982
2033
1983
2034
ice_free_hw_res (& pf -> hw , ICE_AQC_RES_TYPE_RECIPE , 1 ,
1984
2035
& pf -> lag -> pf_recipe );
2036
+ ice_free_hw_res (& pf -> hw , ICE_AQC_RES_TYPE_RECIPE , 1 ,
2037
+ & pf -> lag -> lport_recipe );
1985
2038
1986
2039
kfree (lag );
1987
2040
0 commit comments