drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
Extension
.c
Size
16948 bytes
Lines
666
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

if (port && lan966x->bridge_fwd_mask & BIT(i)) {
			mask = lan966x->bridge_fwd_mask & ~BIT(i);

			if (port->bond)
				mask &= ~lan966x_lag_get_mask(lan966x,
							      port->bond);
		}

		mask |= BIT(CPU_PORT);

		lan_wr(ANA_PGID_PGID_SET(mask),
		       lan966x, ANA_PGID(PGID_SRC + i));
	}
}

void lan966x_port_stp_state_set(struct lan966x_port *port, u8 state)
{
	struct lan966x *lan966x = port->lan966x;
	bool learn_ena = false;

	if ((state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING) &&
	    port->learn_ena)
		learn_ena = true;

	if (state == BR_STATE_FORWARDING)
		lan966x->bridge_fwd_mask |= BIT(port->chip_port);
	else
		lan966x->bridge_fwd_mask &= ~BIT(port->chip_port);

	lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(learn_ena),
		ANA_PORT_CFG_LEARN_ENA,
		lan966x, ANA_PORT_CFG(port->chip_port));

	lan966x_update_fwd_mask(lan966x);
}

void lan966x_port_ageing_set(struct lan966x_port *port,
			     unsigned long ageing_clock_t)
{
	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
	u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;

	lan966x_mac_set_ageing(port->lan966x, ageing_time);
}

static void lan966x_port_mc_set(struct lan966x_port *port, bool mcast_ena)
{
	struct lan966x *lan966x = port->lan966x;

	port->mcast_ena = mcast_ena;
	if (mcast_ena)
		lan966x_mdb_restore_entries(lan966x);
	else
		lan966x_mdb_clear_entries(lan966x);

	lan_rmw(ANA_CPU_FWD_CFG_IGMP_REDIR_ENA_SET(mcast_ena) |
		ANA_CPU_FWD_CFG_MLD_REDIR_ENA_SET(mcast_ena) |
		ANA_CPU_FWD_CFG_IPMC_CTRL_COPY_ENA_SET(mcast_ena),
		ANA_CPU_FWD_CFG_IGMP_REDIR_ENA |
		ANA_CPU_FWD_CFG_MLD_REDIR_ENA |
		ANA_CPU_FWD_CFG_IPMC_CTRL_COPY_ENA,
		lan966x, ANA_CPU_FWD_CFG(port->chip_port));

	lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV4);
	lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV6);
}

static int lan966x_port_attr_set(struct net_device *dev, const void *ctx,
				 const struct switchdev_attr *attr,
				 struct netlink_ext_ack *extack)
{
	struct lan966x_port *port = netdev_priv(dev);
	int err = 0;

	if (ctx && ctx != port)
		return 0;

	switch (attr->id) {
	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
		lan966x_port_bridge_flags(port, attr->u.brport_flags);
		break;
	case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
		err = lan966x_port_pre_bridge_flags(port, attr->u.brport_flags);
		break;
	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
		lan966x_port_stp_state_set(port, attr->u.stp_state);
		break;
	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
		lan966x_port_ageing_set(port, attr->u.ageing_time);
		break;

Annotation

Implementation Notes