drivers/net/dsa/mv88e6xxx/chip.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mv88e6xxx/chip.c
Extension
.c
Size
220431 bytes
Lines
7537
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_port_broadcast_sync_ctx {
	int port;
	bool flood;
};

static int
mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip,
				   const struct mv88e6xxx_vtu_entry *vlan,
				   void *_ctx)
{
	struct mv88e6xxx_port_broadcast_sync_ctx *ctx = _ctx;
	u8 broadcast[ETH_ALEN];
	u8 state;

	if (ctx->flood)
		state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
	else
		state = MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED;

	eth_broadcast_addr(broadcast);

	return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast,
					    vlan->vid, state);
}

static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port,
					 bool flood)
{
	struct mv88e6xxx_port_broadcast_sync_ctx ctx = {
		.port = port,
		.flood = flood,
	};
	struct mv88e6xxx_vtu_entry vid0 = {
		.vid = 0,
	};
	int err;

	/* Update the port's private database... */
	err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx);
	if (err)
		return err;

	/* ...and the database for all VLANs. */
	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan,
				  &ctx);
}

static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
				    u16 vid, u8 member, bool warn)
{
	const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
	struct mv88e6xxx_vtu_entry vlan;
	int i, err;

	err = mv88e6xxx_vtu_get(chip, vid, &vlan);
	if (err)
		return err;

	if (!vlan.valid) {
		memset(&vlan, 0, sizeof(vlan));

		if (vid == MV88E6XXX_VID_STANDALONE)
			vlan.policy = true;

		err = mv88e6xxx_atu_new(chip, &vlan.fid);
		if (err)
			return err;

		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
			if (i == port)
				vlan.member[i] = member;
			else
				vlan.member[i] = non_member;

		vlan.vid = vid;
		vlan.valid = true;

		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
		if (err)
			return err;

		err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
		if (err)
			return err;
	} else if (vlan.member[port] != member) {
		vlan.member[port] = member;

		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
		if (err)
			return err;

Annotation

Implementation Notes