@@ -415,6 +415,36 @@ static int mv88e6xxx_region_atu_snapshot(struct devlink *dl,
415415 return err ;
416416}
417417
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+
418448static struct mv88e6xxx_region_priv mv88e6xxx_region_global1_priv = {
419449 .id = MV88E6XXX_REGION_GLOBAL1 ,
420450};
@@ -443,6 +473,12 @@ static struct devlink_region_ops mv88e6xxx_region_atu_ops = {
443473 .destructor = kfree ,
444474};
445475
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+
446482struct mv88e6xxx_region {
447483 struct devlink_region_ops * ops ;
448484 u64 size ;
@@ -471,11 +507,59 @@ mv88e6xxx_teardown_devlink_regions_global(struct mv88e6xxx_chip *chip)
471507 dsa_devlink_region_destroy (chip -> regions [i ]);
472508}
473509
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 )
475513{
476- struct mv88e6xxx_chip * chip = ds -> priv ;
514+ dsa_devlink_region_destroy (chip -> ports [port ].region );
515+ }
477516
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 ;
479563}
480564
481565static 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,
511595int mv88e6xxx_setup_devlink_regions (struct dsa_switch * ds )
512596{
513597 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 );
514607
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 );
516617}
517618
518619int mv88e6xxx_devlink_info_get (struct dsa_switch * ds ,
0 commit comments