drivers/net/ethernet/microchip/lan966x/lan966x_lag.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_lag.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_lag.c- Extension
.c- Size
- 8867 bytes
- Lines
- 369
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/if_bridge.hlan966x_main.h
Detected Declarations
function lan966x_lag_set_aggr_pgidsfunction for_each_set_bitfunction lan966x_lag_set_port_idsfunction lan966x_lag_update_idsfunction lan966x_lag_port_joinfunction lan966x_lag_port_leavefunction lan966x_lag_port_check_hash_typesfunction lan966x_lag_port_prechangeupperfunction lan966x_lag_port_changelowerstatefunction lan966x_lag_netdev_prechangeupperfunction netdev_for_each_lower_devfunction lan966x_lag_netdev_changeupperfunction netdev_for_each_lower_devfunction lan966x_lag_first_portfunction lan966x_lag_get_mask
Annotated Snippet
for_each_set_bit(p, &bond_mask, lan966x->num_phys_ports) {
struct lan966x_port *port = lan966x->ports[p];
if (!port)
continue;
lan_wr(ANA_PGID_PGID_SET(bond_mask),
lan966x, ANA_PGID(p));
if (port->lag_tx_active)
aggr_idx[num_active_ports++] = p;
}
for (i = PGID_AGGR; i < PGID_SRC; ++i) {
u32 ac;
ac = lan_rd(lan966x, ANA_PGID(i));
ac &= ~bond_mask;
/* Don't do division by zero if there was no active
* port. Just make all aggregation codes zero.
*/
if (num_active_ports)
ac |= BIT(aggr_idx[i % num_active_ports]);
lan_wr(ANA_PGID_PGID_SET(ac),
lan966x, ANA_PGID(i));
}
/* Mark all ports in the same LAG as visited to avoid applying
* the same config again.
*/
for (p = lag; p < lan966x->num_phys_ports; p++) {
struct lan966x_port *port = lan966x->ports[p];
if (!port)
continue;
if (port->bond == bond)
visited |= BIT(p);
}
}
}
static void lan966x_lag_set_port_ids(struct lan966x *lan966x)
{
struct lan966x_port *port;
u32 bond_mask;
u32 lag_id;
int p;
for (p = 0; p < lan966x->num_phys_ports; ++p) {
port = lan966x->ports[p];
if (!port)
continue;
lag_id = port->chip_port;
bond_mask = lan966x_lag_get_mask(lan966x, port->bond);
if (bond_mask)
lag_id = __ffs(bond_mask);
lan_rmw(ANA_PORT_CFG_PORTID_VAL_SET(lag_id),
ANA_PORT_CFG_PORTID_VAL,
lan966x, ANA_PORT_CFG(port->chip_port));
}
}
static void lan966x_lag_update_ids(struct lan966x *lan966x)
{
lan966x_lag_set_port_ids(lan966x);
lan966x_update_fwd_mask(lan966x);
lan966x_lag_set_aggr_pgids(lan966x);
}
int lan966x_lag_port_join(struct lan966x_port *port,
struct net_device *brport_dev,
struct net_device *bond,
struct netlink_ext_ack *extack)
{
struct lan966x *lan966x = port->lan966x;
struct net_device *dev = port->dev;
u32 lag_id = -1;
u32 bond_mask;
int err;
bond_mask = lan966x_lag_get_mask(lan966x, bond);
if (bond_mask)
lag_id = __ffs(bond_mask);
port->bond = bond;
lan966x_lag_update_ids(lan966x);
Annotation
- Immediate include surface: `linux/if_bridge.h`, `lan966x_main.h`.
- Detected declarations: `function lan966x_lag_set_aggr_pgids`, `function for_each_set_bit`, `function lan966x_lag_set_port_ids`, `function lan966x_lag_update_ids`, `function lan966x_lag_port_join`, `function lan966x_lag_port_leave`, `function lan966x_lag_port_check_hash_types`, `function lan966x_lag_port_prechangeupper`, `function lan966x_lag_port_changelowerstate`, `function lan966x_lag_netdev_prechangeupper`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.