drivers/net/dsa/mv88e6xxx/devlink.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/mv88e6xxx/devlink.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mv88e6xxx/devlink.c
Extension
.c
Size
19778 bytes
Lines
816
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mv88e6xxx_devlink_atu_entry {
	/* The FID is scattered over multiple registers. */
	u16 fid;
	u16 atu_op;
	u16 atu_data;
	u16 atu_01;
	u16 atu_23;
	u16 atu_45;
};

static int mv88e6xxx_region_atu_snapshot_fid(struct mv88e6xxx_chip *chip,
					     int fid,
					     struct mv88e6xxx_devlink_atu_entry *table,
					     int *count)
{
	u16 atu_op, atu_data, atu_01, atu_23, atu_45;
	struct mv88e6xxx_atu_entry addr;
	int err;

	addr.state = 0;
	eth_broadcast_addr(addr.mac);

	do {
		err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
		if (err)
			return err;

		if (!addr.state)
			break;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &atu_op);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_DATA, &atu_data);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC01, &atu_01);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC23, &atu_23);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC45, &atu_45);
		if (err)
			return err;

		table[*count].fid = fid;
		table[*count].atu_op = atu_op;
		table[*count].atu_data = atu_data;
		table[*count].atu_01 = atu_01;
		table[*count].atu_23 = atu_23;
		table[*count].atu_45 = atu_45;
		(*count)++;
	} while (!is_broadcast_ether_addr(addr.mac));

	return 0;
}

static int mv88e6xxx_region_atu_snapshot(struct devlink *dl,
					 const struct devlink_region_ops *ops,
					 struct netlink_ext_ack *extack,
					 u8 **data)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	struct mv88e6xxx_devlink_atu_entry *table;
	struct mv88e6xxx_chip *chip = ds->priv;
	int fid = -1, err = 0, count = 0;

	table = kzalloc_objs(struct mv88e6xxx_devlink_atu_entry,
			     mv88e6xxx_num_databases(chip));
	if (!table)
		return -ENOMEM;

	mv88e6xxx_reg_lock(chip);

	while (1) {
		fid = find_next_bit(chip->fid_bitmap, MV88E6XXX_N_FID, fid + 1);
		if (fid == MV88E6XXX_N_FID)
			break;

		err =  mv88e6xxx_region_atu_snapshot_fid(chip, fid, table,
							 &count);
		if (err) {
			kfree(table);
			goto out;
		}

Annotation

Implementation Notes