drivers/net/dsa/lan9303-core.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/lan9303-core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/lan9303-core.c
Extension
.c
Size
43916 bytes
Lines
1516
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 del_port_learned_ctx {
	int port;
};

/* Clear learned (non-static) entry on given port */
static int alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0,
					u32 dat1, int portmap, void *ctx)
{
	struct del_port_learned_ctx *del_ctx = ctx;
	int port = del_ctx->port;

	if (((BIT(port) & portmap) == 0) || (dat1 & LAN9303_ALR_DAT1_STATIC))
		return 0;

	/* learned entries has only one port, we can just delete */
	dat1 &= ~LAN9303_ALR_DAT1_VALID; /* delete entry */
	lan9303_alr_make_entry_raw(chip, dat0, dat1);

	return 0;
}

struct port_fdb_dump_ctx {
	int port;
	void *data;
	dsa_fdb_dump_cb_t *cb;
};

static int alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0,
				     u32 dat1, int portmap, void *ctx)
{
	struct port_fdb_dump_ctx *dump_ctx = ctx;
	u8 mac[ETH_ALEN];
	bool is_static;

	if ((BIT(dump_ctx->port) & portmap) == 0)
		return 0;

	alr_reg_to_mac(dat0, dat1, mac);
	is_static = !!(dat1 & LAN9303_ALR_DAT1_STATIC);
	return dump_ctx->cb(mac, 0, is_static, dump_ctx->data);
}

/* Set a static ALR entry. Delete entry if port_map is zero */
static void lan9303_alr_set_entry(struct lan9303 *chip, const u8 *mac,
				  u8 port_map, bool stp_override)
{
	u32 dat0, dat1, alr_port;

	dev_dbg(chip->dev, "%s(%pM, %d)\n", __func__, mac, port_map);
	dat1 = LAN9303_ALR_DAT1_STATIC;
	if (port_map)
		dat1 |= LAN9303_ALR_DAT1_VALID;
	/* otherwise no ports: delete entry */
	if (stp_override)
		dat1 |= LAN9303_ALR_DAT1_AGE_OVERRID;

	alr_port = portmap_2_alrport[port_map & 7];
	dat1 &= ~LAN9303_ALR_DAT1_PORT_MASK;
	dat1 |= alr_port << LAN9303_ALR_DAT1_PORT_BITOFFS;

	dat0 = 0;
	dat0 |= (mac[0] << 0);
	dat0 |= (mac[1] << 8);
	dat0 |= (mac[2] << 16);
	dat0 |= (mac[3] << 24);

	dat1 |= (mac[4] << 0);
	dat1 |= (mac[5] << 8);

	lan9303_alr_make_entry_raw(chip, dat0, dat1);
}

/* Add port to static ALR entry, create new static entry if needed */
static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac, int port,
				bool stp_override)
{
	struct lan9303_alr_cache_entry *entr;

	mutex_lock(&chip->alr_mutex);
	entr = lan9303_alr_cache_find_mac(chip, mac);
	if (!entr) { /*New entry */
		entr = lan9303_alr_cache_find_free(chip);
		if (!entr) {
			mutex_unlock(&chip->alr_mutex);
			return -ENOSPC;
		}
		ether_addr_copy(entr->mac_addr, mac);
	}
	entr->port_map |= BIT(port);
	entr->stp_override = stp_override;

Annotation

Implementation Notes