29
29
30
30
#define OTX2_UNSUPP_LSE_DEPTH GENMASK(6, 4)
31
31
32
+ #define MCAST_INVALID_GRP (-1U)
33
+
32
34
struct otx2_tc_flow_stats {
33
35
u64 bytes ;
34
36
u64 pkts ;
@@ -47,6 +49,7 @@ struct otx2_tc_flow {
47
49
bool is_act_police ;
48
50
u32 prio ;
49
51
struct npc_install_flow_req req ;
52
+ u32 mcast_grp_idx ;
50
53
u64 rate ;
51
54
u32 burst ;
52
55
bool is_pps ;
@@ -355,22 +358,96 @@ static int otx2_tc_act_set_police(struct otx2_nic *nic,
355
358
return rc ;
356
359
}
357
360
361
+ static int otx2_tc_update_mcast (struct otx2_nic * nic ,
362
+ struct npc_install_flow_req * req ,
363
+ struct netlink_ext_ack * extack ,
364
+ struct otx2_tc_flow * node ,
365
+ struct nix_mcast_grp_update_req * ureq ,
366
+ u8 num_intf )
367
+ {
368
+ struct nix_mcast_grp_update_req * grp_update_req ;
369
+ struct nix_mcast_grp_create_req * creq ;
370
+ struct nix_mcast_grp_create_rsp * crsp ;
371
+ u32 grp_index ;
372
+ int rc ;
373
+
374
+ mutex_lock (& nic -> mbox .lock );
375
+ creq = otx2_mbox_alloc_msg_nix_mcast_grp_create (& nic -> mbox );
376
+ if (!creq ) {
377
+ rc = - ENOMEM ;
378
+ goto error ;
379
+ }
380
+
381
+ creq -> dir = NIX_MCAST_INGRESS ;
382
+ /* Send message to AF */
383
+ rc = otx2_sync_mbox_msg (& nic -> mbox );
384
+ if (rc ) {
385
+ NL_SET_ERR_MSG_MOD (extack , "Failed to create multicast group" );
386
+ goto error ;
387
+ }
388
+
389
+ crsp = (struct nix_mcast_grp_create_rsp * )otx2_mbox_get_rsp (& nic -> mbox .mbox ,
390
+ 0 ,
391
+ & creq -> hdr );
392
+ if (IS_ERR (crsp )) {
393
+ rc = PTR_ERR (crsp );
394
+ goto error ;
395
+ }
396
+
397
+ grp_index = crsp -> mcast_grp_idx ;
398
+ grp_update_req = otx2_mbox_alloc_msg_nix_mcast_grp_update (& nic -> mbox );
399
+ if (!grp_update_req ) {
400
+ NL_SET_ERR_MSG_MOD (extack , "Failed to update multicast group" );
401
+ rc = - ENOMEM ;
402
+ goto error ;
403
+ }
404
+
405
+ ureq -> op = NIX_MCAST_OP_ADD_ENTRY ;
406
+ ureq -> mcast_grp_idx = grp_index ;
407
+ ureq -> num_mce_entry = num_intf ;
408
+ ureq -> pcifunc [0 ] = nic -> pcifunc ;
409
+ ureq -> channel [0 ] = nic -> hw .tx_chan_base ;
410
+
411
+ ureq -> dest_type [0 ] = NIX_RX_RSS ;
412
+ ureq -> rq_rss_index [0 ] = 0 ;
413
+ memcpy (& ureq -> hdr , & grp_update_req -> hdr , sizeof (struct mbox_msghdr ));
414
+ memcpy (grp_update_req , ureq , sizeof (struct nix_mcast_grp_update_req ));
415
+
416
+ /* Send message to AF */
417
+ rc = otx2_sync_mbox_msg (& nic -> mbox );
418
+ if (rc ) {
419
+ NL_SET_ERR_MSG_MOD (extack , "Failed to update multicast group" );
420
+ goto error ;
421
+ }
422
+
423
+ mutex_unlock (& nic -> mbox .lock );
424
+ req -> op = NIX_RX_ACTIONOP_MCAST ;
425
+ req -> index = grp_index ;
426
+ node -> mcast_grp_idx = grp_index ;
427
+ return 0 ;
428
+
429
+ error :
430
+ mutex_unlock (& nic -> mbox .lock );
431
+ return rc ;
432
+ }
433
+
358
434
static int otx2_tc_parse_actions (struct otx2_nic * nic ,
359
435
struct flow_action * flow_action ,
360
436
struct npc_install_flow_req * req ,
361
437
struct flow_cls_offload * f ,
362
438
struct otx2_tc_flow * node )
363
439
{
440
+ struct nix_mcast_grp_update_req dummy_grp_update_req = { 0 };
364
441
struct netlink_ext_ack * extack = f -> common .extack ;
442
+ bool pps = false, mcast = false;
365
443
struct flow_action_entry * act ;
366
444
struct net_device * target ;
367
445
struct otx2_nic * priv ;
368
446
u32 burst , mark = 0 ;
369
447
u8 nr_police = 0 ;
370
- bool pps = false;
448
+ u8 num_intf = 1 ;
449
+ int err , i ;
371
450
u64 rate ;
372
- int err ;
373
- int i ;
374
451
375
452
if (!flow_action_has_entries (flow_action )) {
376
453
NL_SET_ERR_MSG_MOD (extack , "no tc actions specified" );
@@ -442,11 +519,30 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
442
519
req -> index = act -> rx_queue ;
443
520
break ;
444
521
522
+ case FLOW_ACTION_MIRRED_INGRESS :
523
+ target = act -> dev ;
524
+ priv = netdev_priv (target );
525
+ dummy_grp_update_req .pcifunc [num_intf ] = priv -> pcifunc ;
526
+ dummy_grp_update_req .channel [num_intf ] = priv -> hw .tx_chan_base ;
527
+ dummy_grp_update_req .dest_type [num_intf ] = NIX_RX_RSS ;
528
+ dummy_grp_update_req .rq_rss_index [num_intf ] = 0 ;
529
+ mcast = true;
530
+ num_intf ++ ;
531
+ break ;
532
+
445
533
default :
446
534
return - EOPNOTSUPP ;
447
535
}
448
536
}
449
537
538
+ if (mcast ) {
539
+ err = otx2_tc_update_mcast (nic , req , extack , node ,
540
+ & dummy_grp_update_req ,
541
+ num_intf );
542
+ if (err )
543
+ return err ;
544
+ }
545
+
450
546
if (nr_police > 1 ) {
451
547
NL_SET_ERR_MSG_MOD (extack ,
452
548
"rate limit police offload requires a single action" );
@@ -1066,6 +1162,7 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
1066
1162
struct flow_cls_offload * tc_flow_cmd )
1067
1163
{
1068
1164
struct otx2_flow_config * flow_cfg = nic -> flow_cfg ;
1165
+ struct nix_mcast_grp_destroy_req * grp_destroy_req ;
1069
1166
struct otx2_tc_flow * flow_node ;
1070
1167
int err ;
1071
1168
@@ -1099,6 +1196,15 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
1099
1196
1100
1197
mutex_unlock (& nic -> mbox .lock );
1101
1198
}
1199
+ /* Remove the multicast/mirror related nodes */
1200
+ if (flow_node -> mcast_grp_idx != MCAST_INVALID_GRP ) {
1201
+ mutex_lock (& nic -> mbox .lock );
1202
+ grp_destroy_req = otx2_mbox_alloc_msg_nix_mcast_grp_destroy (& nic -> mbox );
1203
+ grp_destroy_req -> mcast_grp_idx = flow_node -> mcast_grp_idx ;
1204
+ otx2_sync_mbox_msg (& nic -> mbox );
1205
+ mutex_unlock (& nic -> mbox .lock );
1206
+ }
1207
+
1102
1208
1103
1209
free_mcam_flow :
1104
1210
otx2_del_mcam_flow_entry (nic , flow_node -> entry , NULL );
@@ -1138,6 +1244,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
1138
1244
spin_lock_init (& new_node -> lock );
1139
1245
new_node -> cookie = tc_flow_cmd -> cookie ;
1140
1246
new_node -> prio = tc_flow_cmd -> common .prio ;
1247
+ new_node -> mcast_grp_idx = MCAST_INVALID_GRP ;
1141
1248
1142
1249
memset (& dummy , 0 , sizeof (struct npc_install_flow_req ));
1143
1250
0 commit comments