drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c- Extension
.c- Size
- 20264 bytes
- Lines
- 789
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/if_bridge.hnet/switchdev.hsparx5_main_regs.hsparx5_main.h
Detected Declarations
struct sparx5_switchdev_event_workfunction sparx5_port_attr_pre_bridge_flagsfunction sparx5_port_update_mcast_ip_floodfunction sparx5_port_attr_bridge_flagsfunction sparx5_attr_stp_state_setfunction sparx5_port_attr_ageing_setfunction sparx5_port_attr_mrouter_setfunction sparx5_port_attr_setfunction sparx5_port_bridge_joinfunction sparx5_port_bridge_leavefunction sparx5_port_changeupperfunction sparx5_port_add_addrfunction sparx5_netdevice_port_eventfunction sparx5_netdevice_eventfunction sparx5_switchdev_bridge_fdb_event_workfunction sparx5_schedule_workfunction sparx5_switchdev_eventfunction sparx5_handle_port_vlan_addfunction sparx5_alloc_mdb_entryfunction sparx5_free_mdb_entryfunction sparx5_cpu_copy_enafunction sparx5_handle_port_mdb_addfunction sparx5_handle_port_mdb_delfunction sparx5_handle_port_obj_addfunction sparx5_handle_port_vlan_delfunction sparx5_handle_port_obj_delfunction sparx5_switchdev_blocking_eventfunction sparx5_register_notifier_blocksfunction sparx5_unregister_notifier_blocks
Annotated Snippet
struct sparx5_switchdev_event_work {
struct work_struct work;
struct switchdev_notifier_fdb_info fdb_info;
struct net_device *dev;
struct sparx5 *sparx5;
unsigned long event;
};
static int sparx5_port_attr_pre_bridge_flags(struct sparx5_port *port,
struct switchdev_brport_flags flags)
{
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD))
return -EINVAL;
return 0;
}
static void sparx5_port_update_mcast_ip_flood(struct sparx5_port *port, bool flood_flag)
{
bool should_flood = flood_flag || port->is_mrouter;
struct sparx5 *sparx5 = port->sparx5;
int pgid;
for (pgid = sparx5_get_pgid(sparx5, PGID_IPV4_MC_DATA);
pgid <= sparx5_get_pgid(sparx5, PGID_IPV6_MC_CTRL); pgid++)
sparx5_pgid_update_mask(port, pgid, should_flood);
}
static void sparx5_port_attr_bridge_flags(struct sparx5_port *port,
struct switchdev_brport_flags flags)
{
struct sparx5 *sparx5 = port->sparx5;
if (flags.mask & BR_MCAST_FLOOD) {
sparx5_pgid_update_mask(port,
sparx5_get_pgid(sparx5, PGID_MC_FLOOD),
!!(flags.val & BR_MCAST_FLOOD));
sparx5_port_update_mcast_ip_flood(port, !!(flags.val & BR_MCAST_FLOOD));
}
if (flags.mask & BR_FLOOD)
sparx5_pgid_update_mask(port,
sparx5_get_pgid(sparx5, PGID_UC_FLOOD),
!!(flags.val & BR_FLOOD));
if (flags.mask & BR_BCAST_FLOOD)
sparx5_pgid_update_mask(port,
sparx5_get_pgid(sparx5, PGID_BCAST),
!!(flags.val & BR_BCAST_FLOOD));
}
static void sparx5_attr_stp_state_set(struct sparx5_port *port,
u8 state)
{
struct sparx5 *sparx5 = port->sparx5;
if (!test_bit(port->portno, sparx5->bridge_mask)) {
netdev_err(port->ndev,
"Controlling non-bridged port %d?\n", port->portno);
return;
}
switch (state) {
case BR_STATE_FORWARDING:
set_bit(port->portno, sparx5->bridge_fwd_mask);
fallthrough;
case BR_STATE_LEARNING:
set_bit(port->portno, sparx5->bridge_lrn_mask);
break;
default:
/* All other states treated as blocking */
clear_bit(port->portno, sparx5->bridge_fwd_mask);
clear_bit(port->portno, sparx5->bridge_lrn_mask);
break;
}
/* apply the bridge_fwd_mask to all the ports */
sparx5_update_fwd(sparx5);
}
static void sparx5_port_attr_ageing_set(struct sparx5_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);
sparx5_set_ageing(port->sparx5, ageing_time);
}
static void sparx5_port_attr_mrouter_set(struct sparx5_port *port,
Annotation
- Immediate include surface: `linux/if_bridge.h`, `net/switchdev.h`, `sparx5_main_regs.h`, `sparx5_main.h`.
- Detected declarations: `struct sparx5_switchdev_event_work`, `function sparx5_port_attr_pre_bridge_flags`, `function sparx5_port_update_mcast_ip_flood`, `function sparx5_port_attr_bridge_flags`, `function sparx5_attr_stp_state_set`, `function sparx5_port_attr_ageing_set`, `function sparx5_port_attr_mrouter_set`, `function sparx5_port_attr_set`, `function sparx5_port_bridge_join`, `function sparx5_port_bridge_leave`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.