Skip to content

Commit b71a8d6

Browse files
lunndavem330
authored andcommitted
net: dsa: mv88e6xxx: Add per port devlink regions
Add a devlink region to return the per port registers. Signed-off-by: Andrew Lunn <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Reviewed-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7d1e2a1 commit b71a8d6

File tree

1 file changed

+105
-4
lines changed

1 file changed

+105
-4
lines changed

drivers/net/dsa/mv88e6xxx/devlink.c

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
418448
static 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+
446482
struct 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

481565
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,
511595
int 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

518619
int mv88e6xxx_devlink_info_get(struct dsa_switch *ds,

0 commit comments

Comments
 (0)