drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c- Extension
.c- Size
- 16518 bytes
- Lines
- 624
- 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.
- 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/module.hlinux/device.hsparx5_main_regs.hsparx5_main.h
Detected Declarations
function sparx5_target_bandwidthfunction sparx5_clk_to_bandwidthfunction sparx5_cal_speed_to_valuefunction sparx5_bandwidth_to_calendarfunction sparx5_get_port_cal_speedfunction sparx5_get_internal_portfunction sparx5_get_internal_portfunction sparx5_get_internal_portfunction sparx5_config_auto_calendarfunction sparx5_dsm_exb_gcdfunction sparx5_dsm_cal_lenfunction sparx5_dsm_cp_calfunction sparx5_dsm_calendar_calcfunction sparx5_dsm_calendar_checkfunction sparx5_dsm_calendar_updatefunction sparx5_config_dsm_calendarfunction sparx5_calendar_init
Annotated Snippet
sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_1)) {
/* Equals 1.25G */
return SPX5_CAL_SPEED_2G5;
} else if (portno ==
sparx5_get_internal_port(sparx5, SPX5_PORT_VD0)) {
/* IPMC only idle BW */
return SPX5_CAL_SPEED_NONE;
} else if (portno ==
sparx5_get_internal_port(sparx5, SPX5_PORT_VD1)) {
/* OAM only idle BW */
return SPX5_CAL_SPEED_NONE;
} else if (portno ==
sparx5_get_internal_port(sparx5, SPX5_PORT_VD2)) {
/* IPinIP gets only idle BW */
return SPX5_CAL_SPEED_NONE;
}
/* not in port map */
return SPX5_CAL_SPEED_NONE;
}
/* Front ports - may be used */
port = sparx5->ports[portno];
if (!port)
return SPX5_CAL_SPEED_NONE;
return sparx5_bandwidth_to_calendar(port->conf.bandwidth);
}
/* Auto configure the QSYS calendar based on port configuration */
static int sparx5_config_auto_calendar(struct sparx5 *sparx5)
{
const struct sparx5_consts *consts = sparx5->data->consts;
u32 cal[7], value, idx, portno;
u32 max_core_bw;
u32 total_bw = 0, used_port_bw = 0;
int err = 0;
enum sparx5_cal_bw spd;
memset(cal, 0, sizeof(cal));
max_core_bw = sparx5_clk_to_bandwidth(sparx5->coreclock);
if (max_core_bw == 0) {
dev_err(sparx5->dev, "Core clock not supported");
return -EINVAL;
}
/* Setup the calendar with the bandwidth to each port */
for (portno = 0; portno < consts->n_ports_all; portno++) {
u64 reg, offset, this_bw;
spd = sparx5_get_port_cal_speed(sparx5, portno);
if (spd == SPX5_CAL_SPEED_NONE)
continue;
this_bw = sparx5_cal_speed_to_value(spd);
if (portno < consts->n_ports)
used_port_bw += this_bw;
else
/* Internal ports are granted half the value */
this_bw = this_bw / 2;
total_bw += this_bw;
reg = portno;
offset = do_div(reg, SPX5_PORTS_PER_CALREG);
cal[reg] |= spd << (offset * SPX5_CALBITS_PER_PORT);
}
if (used_port_bw > sparx5_target_bandwidth(sparx5)) {
dev_err(sparx5->dev,
"Port BW %u above target BW %u\n",
used_port_bw, sparx5_target_bandwidth(sparx5));
return -EINVAL;
}
if (total_bw > max_core_bw) {
dev_err(sparx5->dev,
"Total BW %u above switch core BW %u\n",
total_bw, max_core_bw);
return -EINVAL;
}
/* Halt the calendar while changing it */
if (is_sparx5(sparx5))
spx5_rmw(QSYS_CAL_CTRL_CAL_MODE_SET(10),
QSYS_CAL_CTRL_CAL_MODE,
sparx5, QSYS_CAL_CTRL);
/* Assign port bandwidth to auto calendar */
for (idx = 0; idx < consts->n_auto_cals; idx++)
spx5_wr(cal[idx], sparx5, QSYS_CAL_AUTO(idx));
/* Increase grant rate of all ports to account for
* core clock ppm deviations
Annotation
- Immediate include surface: `linux/module.h`, `linux/device.h`, `sparx5_main_regs.h`, `sparx5_main.h`.
- Detected declarations: `function sparx5_target_bandwidth`, `function sparx5_clk_to_bandwidth`, `function sparx5_cal_speed_to_value`, `function sparx5_bandwidth_to_calendar`, `function sparx5_get_port_cal_speed`, `function sparx5_get_internal_port`, `function sparx5_get_internal_port`, `function sparx5_get_internal_port`, `function sparx5_config_auto_calendar`, `function sparx5_dsm_exb_gcd`.
- 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.