@@ -231,8 +231,26 @@ static void cxgb4_matchall_mirror_free(struct net_device *dev)
231
231
tc_port_matchall -> ingress .viid_mirror = 0 ;
232
232
}
233
233
234
- static int cxgb4_matchall_alloc_filter (struct net_device * dev ,
235
- struct tc_cls_matchall_offload * cls )
234
+ static int cxgb4_matchall_del_filter (struct net_device * dev , u8 filter_type )
235
+ {
236
+ struct cxgb4_tc_port_matchall * tc_port_matchall ;
237
+ struct port_info * pi = netdev2pinfo (dev );
238
+ struct adapter * adap = netdev2adap (dev );
239
+ int ret ;
240
+
241
+ tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
242
+ ret = cxgb4_del_filter (dev , tc_port_matchall -> ingress .tid [filter_type ],
243
+ & tc_port_matchall -> ingress .fs [filter_type ]);
244
+ if (ret )
245
+ return ret ;
246
+
247
+ tc_port_matchall -> ingress .tid [filter_type ] = 0 ;
248
+ return 0 ;
249
+ }
250
+
251
+ static int cxgb4_matchall_add_filter (struct net_device * dev ,
252
+ struct tc_cls_matchall_offload * cls ,
253
+ u8 filter_type )
236
254
{
237
255
struct netlink_ext_ack * extack = cls -> common .extack ;
238
256
struct cxgb4_tc_port_matchall * tc_port_matchall ;
@@ -244,28 +262,24 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev,
244
262
/* Get a free filter entry TID, where we can insert this new
245
263
* rule. Only insert rule if its prio doesn't conflict with
246
264
* existing rules.
247
- *
248
- * 1 slot is enough to create a wildcard matchall VIID rule.
249
265
*/
250
- fidx = cxgb4_get_free_ftid (dev , PF_INET , false, cls -> common .prio );
266
+ fidx = cxgb4_get_free_ftid (dev , filter_type ? PF_INET6 : PF_INET ,
267
+ false, cls -> common .prio );
251
268
if (fidx < 0 ) {
252
269
NL_SET_ERR_MSG_MOD (extack ,
253
270
"No free LETCAM index available" );
254
271
return - ENOMEM ;
255
272
}
256
273
257
- ret = cxgb4_matchall_mirror_alloc (dev , cls );
258
- if (ret )
259
- return ret ;
260
-
261
274
tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
262
- fs = & tc_port_matchall -> ingress .fs ;
275
+ fs = & tc_port_matchall -> ingress .fs [ filter_type ] ;
263
276
memset (fs , 0 , sizeof (* fs ));
264
277
265
278
if (fidx < adap -> tids .nhpftids )
266
279
fs -> prio = 1 ;
267
280
fs -> tc_prio = cls -> common .prio ;
268
281
fs -> tc_cookie = cls -> cookie ;
282
+ fs -> type = filter_type ;
269
283
fs -> hitcnts = 1 ;
270
284
271
285
fs -> val .pfvf_vld = 1 ;
@@ -276,13 +290,39 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev,
276
290
277
291
ret = cxgb4_set_filter (dev , fidx , fs );
278
292
if (ret )
279
- goto out_free ;
293
+ return ret ;
294
+
295
+ tc_port_matchall -> ingress .tid [filter_type ] = fidx ;
296
+ return 0 ;
297
+ }
298
+
299
+ static int cxgb4_matchall_alloc_filter (struct net_device * dev ,
300
+ struct tc_cls_matchall_offload * cls )
301
+ {
302
+ struct cxgb4_tc_port_matchall * tc_port_matchall ;
303
+ struct port_info * pi = netdev2pinfo (dev );
304
+ struct adapter * adap = netdev2adap (dev );
305
+ int ret , i ;
306
+
307
+ tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
308
+
309
+ ret = cxgb4_matchall_mirror_alloc (dev , cls );
310
+ if (ret )
311
+ return ret ;
312
+
313
+ for (i = 0 ; i < CXGB4_FILTER_TYPE_MAX ; i ++ ) {
314
+ ret = cxgb4_matchall_add_filter (dev , cls , i );
315
+ if (ret )
316
+ goto out_free ;
317
+ }
280
318
281
- tc_port_matchall -> ingress .tid = fidx ;
282
319
tc_port_matchall -> ingress .state = CXGB4_MATCHALL_STATE_ENABLED ;
283
320
return 0 ;
284
321
285
322
out_free :
323
+ while (i -- > 0 )
324
+ cxgb4_matchall_del_filter (dev , i );
325
+
286
326
cxgb4_matchall_mirror_free (dev );
287
327
return ret ;
288
328
}
@@ -293,20 +333,21 @@ static int cxgb4_matchall_free_filter(struct net_device *dev)
293
333
struct port_info * pi = netdev2pinfo (dev );
294
334
struct adapter * adap = netdev2adap (dev );
295
335
int ret ;
336
+ u8 i ;
296
337
297
338
tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
298
339
299
- ret = cxgb4_del_filter (dev , tc_port_matchall -> ingress .tid ,
300
- & tc_port_matchall -> ingress .fs );
301
- if (ret )
302
- return ret ;
340
+ for (i = 0 ; i < CXGB4_FILTER_TYPE_MAX ; i ++ ) {
341
+ ret = cxgb4_matchall_del_filter (dev , i );
342
+ if (ret )
343
+ return ret ;
344
+ }
303
345
304
346
cxgb4_matchall_mirror_free (dev );
305
347
306
348
tc_port_matchall -> ingress .packets = 0 ;
307
349
tc_port_matchall -> ingress .bytes = 0 ;
308
350
tc_port_matchall -> ingress .last_used = 0 ;
309
- tc_port_matchall -> ingress .tid = 0 ;
310
351
tc_port_matchall -> ingress .state = CXGB4_MATCHALL_STATE_DISABLED ;
311
352
return 0 ;
312
353
}
@@ -362,8 +403,12 @@ int cxgb4_tc_matchall_destroy(struct net_device *dev,
362
403
363
404
tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
364
405
if (ingress ) {
406
+ /* All the filter types of this matchall rule save the
407
+ * same cookie. So, checking for the first one is
408
+ * enough.
409
+ */
365
410
if (cls_matchall -> cookie !=
366
- tc_port_matchall -> ingress .fs .tc_cookie )
411
+ tc_port_matchall -> ingress .fs [ 0 ] .tc_cookie )
367
412
return - ENOENT ;
368
413
369
414
return cxgb4_matchall_free_filter (dev );
@@ -379,21 +424,29 @@ int cxgb4_tc_matchall_destroy(struct net_device *dev,
379
424
int cxgb4_tc_matchall_stats (struct net_device * dev ,
380
425
struct tc_cls_matchall_offload * cls_matchall )
381
426
{
427
+ u64 tmp_packets , tmp_bytes , packets = 0 , bytes = 0 ;
382
428
struct cxgb4_tc_port_matchall * tc_port_matchall ;
429
+ struct cxgb4_matchall_ingress_entry * ingress ;
383
430
struct port_info * pi = netdev2pinfo (dev );
384
431
struct adapter * adap = netdev2adap (dev );
385
- u64 packets , bytes ;
386
432
int ret ;
433
+ u8 i ;
387
434
388
435
tc_port_matchall = & adap -> tc_matchall -> port_matchall [pi -> port_id ];
389
436
if (tc_port_matchall -> ingress .state == CXGB4_MATCHALL_STATE_DISABLED )
390
437
return - ENOENT ;
391
438
392
- ret = cxgb4_get_filter_counters (dev , tc_port_matchall -> ingress .tid ,
393
- & packets , & bytes ,
394
- tc_port_matchall -> ingress .fs .hash );
395
- if (ret )
396
- return ret ;
439
+ ingress = & tc_port_matchall -> ingress ;
440
+ for (i = 0 ; i < CXGB4_FILTER_TYPE_MAX ; i ++ ) {
441
+ ret = cxgb4_get_filter_counters (dev , ingress -> tid [i ],
442
+ & tmp_packets , & tmp_bytes ,
443
+ ingress -> fs [i ].hash );
444
+ if (ret )
445
+ return ret ;
446
+
447
+ packets += tmp_packets ;
448
+ bytes += tmp_bytes ;
449
+ }
397
450
398
451
if (tc_port_matchall -> ingress .packets != packets ) {
399
452
flow_stats_update (& cls_matchall -> stats ,
0 commit comments