38
38
#define MLX5E_100MB (100000)
39
39
#define MLX5E_1GB (1000000)
40
40
41
+ #define MLX5E_CEE_STATE_UP 1
42
+ #define MLX5E_CEE_STATE_DOWN 0
43
+
41
44
static int mlx5e_dcbnl_ieee_getets (struct net_device * netdev ,
42
45
struct ieee_ets * ets )
43
46
{
@@ -222,13 +225,15 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
222
225
223
226
static u8 mlx5e_dcbnl_getdcbx (struct net_device * dev )
224
227
{
225
- return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE ;
228
+ return DCB_CAP_DCBX_HOST |
229
+ DCB_CAP_DCBX_VER_IEEE |
230
+ DCB_CAP_DCBX_VER_CEE ;
226
231
}
227
232
228
233
static u8 mlx5e_dcbnl_setdcbx (struct net_device * dev , u8 mode )
229
234
{
230
235
if ((mode & DCB_CAP_DCBX_LLD_MANAGED ) ||
231
- (mode & DCB_CAP_DCBX_VER_CEE ) ||
236
+ ! (mode & DCB_CAP_DCBX_VER_CEE ) ||
232
237
!(mode & DCB_CAP_DCBX_VER_IEEE ) ||
233
238
!(mode & DCB_CAP_DCBX_HOST ))
234
239
return 1 ;
@@ -304,6 +309,281 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
304
309
return mlx5_modify_port_ets_rate_limit (mdev , max_bw_value , max_bw_unit );
305
310
}
306
311
312
+ static u8 mlx5e_dcbnl_setall (struct net_device * netdev )
313
+ {
314
+ struct mlx5e_priv * priv = netdev_priv (netdev );
315
+ struct mlx5e_cee_config * cee_cfg = & priv -> dcbx .cee_cfg ;
316
+ struct mlx5_core_dev * mdev = priv -> mdev ;
317
+ struct ieee_ets ets ;
318
+ struct ieee_pfc pfc ;
319
+ int err ;
320
+ int i ;
321
+
322
+ memset (& ets , 0 , sizeof (ets ));
323
+ memset (& pfc , 0 , sizeof (pfc ));
324
+
325
+ ets .ets_cap = IEEE_8021QAZ_MAX_TCS ;
326
+ for (i = 0 ; i < CEE_DCBX_MAX_PGS ; i ++ ) {
327
+ ets .tc_tx_bw [i ] = cee_cfg -> pg_bw_pct [i ];
328
+ ets .tc_rx_bw [i ] = cee_cfg -> pg_bw_pct [i ];
329
+ ets .tc_tsa [i ] = IEEE_8021QAZ_TSA_ETS ;
330
+ ets .prio_tc [i ] = cee_cfg -> prio_to_pg_map [i ];
331
+ }
332
+
333
+ err = mlx5e_dbcnl_validate_ets (netdev , & ets );
334
+ if (err ) {
335
+ netdev_err (netdev ,
336
+ "%s, Failed to validate ETS: %d\n" , __func__ , err );
337
+ goto out ;
338
+ }
339
+
340
+ err = mlx5e_dcbnl_ieee_setets_core (priv , & ets );
341
+ if (err ) {
342
+ netdev_err (netdev ,
343
+ "%s, Failed to set ETS: %d\n" , __func__ , err );
344
+ goto out ;
345
+ }
346
+
347
+ /* Set PFC */
348
+ pfc .pfc_cap = mlx5_max_tc (mdev ) + 1 ;
349
+ if (!cee_cfg -> pfc_enable )
350
+ pfc .pfc_en = 0 ;
351
+ else
352
+ for (i = 0 ; i < CEE_DCBX_MAX_PRIO ; i ++ )
353
+ pfc .pfc_en |= cee_cfg -> pfc_setting [i ] << i ;
354
+
355
+ err = mlx5e_dcbnl_ieee_setpfc (netdev , & pfc );
356
+ if (err ) {
357
+ netdev_err (netdev ,
358
+ "%s, Failed to set PFC: %d\n" , __func__ , err );
359
+ goto out ;
360
+ }
361
+ out :
362
+ return err ? MLX5_DCB_NO_CHG : MLX5_DCB_CHG_RESET ;
363
+ }
364
+
365
+ static u8 mlx5e_dcbnl_getstate (struct net_device * netdev )
366
+ {
367
+ return MLX5E_CEE_STATE_UP ;
368
+ }
369
+
370
+ static void mlx5e_dcbnl_getpermhwaddr (struct net_device * netdev ,
371
+ u8 * perm_addr )
372
+ {
373
+ struct mlx5e_priv * priv = netdev_priv (netdev );
374
+
375
+ if (!perm_addr )
376
+ return ;
377
+
378
+ mlx5_query_nic_vport_mac_address (priv -> mdev , 0 , perm_addr );
379
+ }
380
+
381
+ static void mlx5e_dcbnl_setpgtccfgtx (struct net_device * netdev ,
382
+ int priority , u8 prio_type ,
383
+ u8 pgid , u8 bw_pct , u8 up_map )
384
+ {
385
+ struct mlx5e_priv * priv = netdev_priv (netdev );
386
+ struct mlx5e_cee_config * cee_cfg = & priv -> dcbx .cee_cfg ;
387
+
388
+ if (priority >= CEE_DCBX_MAX_PRIO ) {
389
+ netdev_err (netdev ,
390
+ "%s, priority is out of range\n" , __func__ );
391
+ return ;
392
+ }
393
+
394
+ if (pgid >= CEE_DCBX_MAX_PGS ) {
395
+ netdev_err (netdev ,
396
+ "%s, priority group is out of range\n" , __func__ );
397
+ return ;
398
+ }
399
+
400
+ cee_cfg -> prio_to_pg_map [priority ] = pgid ;
401
+ }
402
+
403
+ static void mlx5e_dcbnl_setpgbwgcfgtx (struct net_device * netdev ,
404
+ int pgid , u8 bw_pct )
405
+ {
406
+ struct mlx5e_priv * priv = netdev_priv (netdev );
407
+ struct mlx5e_cee_config * cee_cfg = & priv -> dcbx .cee_cfg ;
408
+
409
+ if (pgid >= CEE_DCBX_MAX_PGS ) {
410
+ netdev_err (netdev ,
411
+ "%s, priority group is out of range\n" , __func__ );
412
+ return ;
413
+ }
414
+
415
+ cee_cfg -> pg_bw_pct [pgid ] = bw_pct ;
416
+ }
417
+
418
+ static void mlx5e_dcbnl_getpgtccfgtx (struct net_device * netdev ,
419
+ int priority , u8 * prio_type ,
420
+ u8 * pgid , u8 * bw_pct , u8 * up_map )
421
+ {
422
+ struct mlx5e_priv * priv = netdev_priv (netdev );
423
+ struct mlx5_core_dev * mdev = priv -> mdev ;
424
+
425
+ if (priority >= CEE_DCBX_MAX_PRIO ) {
426
+ netdev_err (netdev ,
427
+ "%s, priority is out of range\n" , __func__ );
428
+ return ;
429
+ }
430
+
431
+ * prio_type = 0 ;
432
+ * bw_pct = 0 ;
433
+ * up_map = 0 ;
434
+
435
+ if (mlx5_query_port_prio_tc (mdev , priority , pgid ))
436
+ * pgid = 0 ;
437
+ }
438
+
439
+ static void mlx5e_dcbnl_getpgbwgcfgtx (struct net_device * netdev ,
440
+ int pgid , u8 * bw_pct )
441
+ {
442
+ struct mlx5e_priv * priv = netdev_priv (netdev );
443
+ struct mlx5_core_dev * mdev = priv -> mdev ;
444
+
445
+ if (pgid >= CEE_DCBX_MAX_PGS ) {
446
+ netdev_err (netdev ,
447
+ "%s, priority group is out of range\n" , __func__ );
448
+ return ;
449
+ }
450
+
451
+ if (mlx5_query_port_tc_bw_alloc (mdev , pgid , bw_pct ))
452
+ * bw_pct = 0 ;
453
+ }
454
+
455
+ static void mlx5e_dcbnl_setpfccfg (struct net_device * netdev ,
456
+ int priority , u8 setting )
457
+ {
458
+ struct mlx5e_priv * priv = netdev_priv (netdev );
459
+ struct mlx5e_cee_config * cee_cfg = & priv -> dcbx .cee_cfg ;
460
+
461
+ if (priority >= CEE_DCBX_MAX_PRIO ) {
462
+ netdev_err (netdev ,
463
+ "%s, priority is out of range\n" , __func__ );
464
+ return ;
465
+ }
466
+
467
+ if (setting > 1 )
468
+ return ;
469
+
470
+ cee_cfg -> pfc_setting [priority ] = setting ;
471
+ }
472
+
473
+ static int
474
+ mlx5e_dcbnl_get_priority_pfc (struct net_device * netdev ,
475
+ int priority , u8 * setting )
476
+ {
477
+ struct ieee_pfc pfc ;
478
+ int err ;
479
+
480
+ err = mlx5e_dcbnl_ieee_getpfc (netdev , & pfc );
481
+
482
+ if (err )
483
+ * setting = 0 ;
484
+ else
485
+ * setting = (pfc .pfc_en >> priority ) & 0x01 ;
486
+
487
+ return err ;
488
+ }
489
+
490
+ static void mlx5e_dcbnl_getpfccfg (struct net_device * netdev ,
491
+ int priority , u8 * setting )
492
+ {
493
+ if (priority >= CEE_DCBX_MAX_PRIO ) {
494
+ netdev_err (netdev ,
495
+ "%s, priority is out of range\n" , __func__ );
496
+ return ;
497
+ }
498
+
499
+ if (!setting )
500
+ return ;
501
+
502
+ mlx5e_dcbnl_get_priority_pfc (netdev , priority , setting );
503
+ }
504
+
505
+ static u8 mlx5e_dcbnl_getcap (struct net_device * netdev ,
506
+ int capid , u8 * cap )
507
+ {
508
+ struct mlx5e_priv * priv = netdev_priv (netdev );
509
+ struct mlx5_core_dev * mdev = priv -> mdev ;
510
+ u8 rval = 0 ;
511
+
512
+ switch (capid ) {
513
+ case DCB_CAP_ATTR_PG :
514
+ * cap = true;
515
+ break ;
516
+ case DCB_CAP_ATTR_PFC :
517
+ * cap = true;
518
+ break ;
519
+ case DCB_CAP_ATTR_UP2TC :
520
+ * cap = false;
521
+ break ;
522
+ case DCB_CAP_ATTR_PG_TCS :
523
+ * cap = 1 << mlx5_max_tc (mdev );
524
+ break ;
525
+ case DCB_CAP_ATTR_PFC_TCS :
526
+ * cap = 1 << mlx5_max_tc (mdev );
527
+ break ;
528
+ case DCB_CAP_ATTR_GSP :
529
+ * cap = false;
530
+ break ;
531
+ case DCB_CAP_ATTR_BCN :
532
+ * cap = false;
533
+ break ;
534
+ case DCB_CAP_ATTR_DCBX :
535
+ * cap = (DCB_CAP_DCBX_LLD_MANAGED |
536
+ DCB_CAP_DCBX_VER_CEE |
537
+ DCB_CAP_DCBX_STATIC );
538
+ break ;
539
+ default :
540
+ * cap = 0 ;
541
+ rval = 1 ;
542
+ break ;
543
+ }
544
+
545
+ return rval ;
546
+ }
547
+
548
+ static int mlx5e_dcbnl_getnumtcs (struct net_device * netdev ,
549
+ int tcs_id , u8 * num )
550
+ {
551
+ struct mlx5e_priv * priv = netdev_priv (netdev );
552
+ struct mlx5_core_dev * mdev = priv -> mdev ;
553
+
554
+ switch (tcs_id ) {
555
+ case DCB_NUMTCS_ATTR_PG :
556
+ case DCB_NUMTCS_ATTR_PFC :
557
+ * num = mlx5_max_tc (mdev ) + 1 ;
558
+ break ;
559
+ default :
560
+ return - EINVAL ;
561
+ }
562
+
563
+ return 0 ;
564
+ }
565
+
566
+ static u8 mlx5e_dcbnl_getpfcstate (struct net_device * netdev )
567
+ {
568
+ struct ieee_pfc pfc ;
569
+
570
+ if (mlx5e_dcbnl_ieee_getpfc (netdev , & pfc ))
571
+ return MLX5E_CEE_STATE_DOWN ;
572
+
573
+ return pfc .pfc_en ? MLX5E_CEE_STATE_UP : MLX5E_CEE_STATE_DOWN ;
574
+ }
575
+
576
+ static void mlx5e_dcbnl_setpfcstate (struct net_device * netdev , u8 state )
577
+ {
578
+ struct mlx5e_priv * priv = netdev_priv (netdev );
579
+ struct mlx5e_cee_config * cee_cfg = & priv -> dcbx .cee_cfg ;
580
+
581
+ if ((state != MLX5E_CEE_STATE_UP ) && (state != MLX5E_CEE_STATE_DOWN ))
582
+ return ;
583
+
584
+ cee_cfg -> pfc_enable = state ;
585
+ }
586
+
307
587
const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
308
588
.ieee_getets = mlx5e_dcbnl_ieee_getets ,
309
589
.ieee_setets = mlx5e_dcbnl_ieee_setets ,
@@ -313,4 +593,21 @@ const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
313
593
.ieee_setpfc = mlx5e_dcbnl_ieee_setpfc ,
314
594
.getdcbx = mlx5e_dcbnl_getdcbx ,
315
595
.setdcbx = mlx5e_dcbnl_setdcbx ,
596
+
597
+ /* CEE interfaces */
598
+ .setall = mlx5e_dcbnl_setall ,
599
+ .getstate = mlx5e_dcbnl_getstate ,
600
+ .getpermhwaddr = mlx5e_dcbnl_getpermhwaddr ,
601
+
602
+ .setpgtccfgtx = mlx5e_dcbnl_setpgtccfgtx ,
603
+ .setpgbwgcfgtx = mlx5e_dcbnl_setpgbwgcfgtx ,
604
+ .getpgtccfgtx = mlx5e_dcbnl_getpgtccfgtx ,
605
+ .getpgbwgcfgtx = mlx5e_dcbnl_getpgbwgcfgtx ,
606
+
607
+ .setpfccfg = mlx5e_dcbnl_setpfccfg ,
608
+ .getpfccfg = mlx5e_dcbnl_getpfccfg ,
609
+ .getcap = mlx5e_dcbnl_getcap ,
610
+ .getnumtcs = mlx5e_dcbnl_getnumtcs ,
611
+ .getpfcstate = mlx5e_dcbnl_getpfcstate ,
612
+ .setpfcstate = mlx5e_dcbnl_setpfcstate ,
316
613
};
0 commit comments