@@ -415,6 +415,36 @@ static int mv88e6xxx_region_atu_snapshot(struct devlink *dl,
415
415
return err ;
416
416
}
417
417
418
+ static int mv88e6xxx_region_port_snapshot (struct devlink_port * devlink_port ,
419
+ const struct devlink_port_region_ops * ops ,
420
+ struct netlink_ext_ack * extack ,
421
+ u8 * * data )
422
+ {
423
+ struct dsa_switch * ds = dsa_devlink_port_to_ds (devlink_port );
424
+ int port = dsa_devlink_port_to_port (devlink_port );
425
+ struct mv88e6xxx_chip * chip = ds -> priv ;
426
+ u16 * registers ;
427
+ int i , err ;
428
+
429
+ registers = kmalloc_array (32 , sizeof (u16 ), GFP_KERNEL );
430
+ if (!registers )
431
+ return - ENOMEM ;
432
+
433
+ mv88e6xxx_reg_lock (chip );
434
+ for (i = 0 ; i < 32 ; i ++ ) {
435
+ err = mv88e6xxx_port_read (chip , port , i , & registers [i ]);
436
+ if (err ) {
437
+ kfree (registers );
438
+ goto out ;
439
+ }
440
+ }
441
+ * data = (u8 * )registers ;
442
+ out :
443
+ mv88e6xxx_reg_unlock (chip );
444
+
445
+ return err ;
446
+ }
447
+
418
448
static struct mv88e6xxx_region_priv mv88e6xxx_region_global1_priv = {
419
449
.id = MV88E6XXX_REGION_GLOBAL1 ,
420
450
};
@@ -443,6 +473,12 @@ static struct devlink_region_ops mv88e6xxx_region_atu_ops = {
443
473
.destructor = kfree ,
444
474
};
445
475
476
+ static const struct devlink_port_region_ops mv88e6xxx_region_port_ops = {
477
+ .name = "port" ,
478
+ .snapshot = mv88e6xxx_region_port_snapshot ,
479
+ .destructor = kfree ,
480
+ };
481
+
446
482
struct mv88e6xxx_region {
447
483
struct devlink_region_ops * ops ;
448
484
u64 size ;
@@ -471,11 +507,59 @@ mv88e6xxx_teardown_devlink_regions_global(struct mv88e6xxx_chip *chip)
471
507
dsa_devlink_region_destroy (chip -> regions [i ]);
472
508
}
473
509
474
- void mv88e6xxx_teardown_devlink_regions (struct dsa_switch * ds )
510
+ static void
511
+ mv88e6xxx_teardown_devlink_regions_port (struct mv88e6xxx_chip * chip ,
512
+ int port )
475
513
{
476
- struct mv88e6xxx_chip * chip = ds -> priv ;
514
+ dsa_devlink_region_destroy (chip -> ports [port ].region );
515
+ }
477
516
478
- mv88e6xxx_teardown_devlink_regions_global (chip );
517
+ static int mv88e6xxx_setup_devlink_regions_port (struct dsa_switch * ds ,
518
+ struct mv88e6xxx_chip * chip ,
519
+ int port )
520
+ {
521
+ struct devlink_region * region ;
522
+
523
+ region = dsa_devlink_port_region_create (ds ,
524
+ port ,
525
+ & mv88e6xxx_region_port_ops , 1 ,
526
+ 32 * sizeof (u16 ));
527
+ if (IS_ERR (region ))
528
+ return PTR_ERR (region );
529
+
530
+ chip -> ports [port ].region = region ;
531
+
532
+ return 0 ;
533
+ }
534
+
535
+ static void
536
+ mv88e6xxx_teardown_devlink_regions_ports (struct mv88e6xxx_chip * chip )
537
+ {
538
+ int port ;
539
+
540
+ for (port = 0 ; port < mv88e6xxx_num_ports (chip ); port ++ )
541
+ mv88e6xxx_teardown_devlink_regions_port (chip , port );
542
+ }
543
+
544
+ static int mv88e6xxx_setup_devlink_regions_ports (struct dsa_switch * ds ,
545
+ struct mv88e6xxx_chip * chip )
546
+ {
547
+ int port ;
548
+ int err ;
549
+
550
+ for (port = 0 ; port < mv88e6xxx_num_ports (chip ); port ++ ) {
551
+ err = mv88e6xxx_setup_devlink_regions_port (ds , chip , port );
552
+ if (err )
553
+ goto out ;
554
+ }
555
+
556
+ return 0 ;
557
+
558
+ out :
559
+ while (port -- > 0 )
560
+ mv88e6xxx_teardown_devlink_regions_port (chip , port );
561
+
562
+ return err ;
479
563
}
480
564
481
565
static int mv88e6xxx_setup_devlink_regions_global (struct dsa_switch * ds ,
@@ -511,8 +595,25 @@ static int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds,
511
595
int mv88e6xxx_setup_devlink_regions (struct dsa_switch * ds )
512
596
{
513
597
struct mv88e6xxx_chip * chip = ds -> priv ;
598
+ int err ;
599
+
600
+ err = mv88e6xxx_setup_devlink_regions_global (ds , chip );
601
+ if (err )
602
+ return err ;
603
+
604
+ err = mv88e6xxx_setup_devlink_regions_ports (ds , chip );
605
+ if (err )
606
+ mv88e6xxx_teardown_devlink_regions_global (chip );
514
607
515
- return mv88e6xxx_setup_devlink_regions_global (ds , chip );
608
+ return err ;
609
+ }
610
+
611
+ void mv88e6xxx_teardown_devlink_regions (struct dsa_switch * ds )
612
+ {
613
+ struct mv88e6xxx_chip * chip = ds -> priv ;
614
+
615
+ mv88e6xxx_teardown_devlink_regions_ports (chip );
616
+ mv88e6xxx_teardown_devlink_regions_global (chip );
516
617
}
517
618
518
619
int mv88e6xxx_devlink_info_get (struct dsa_switch * ds ,
0 commit comments