drivers/net/dsa/sja1105/sja1105_tas.c
Source file repositories/reference/linux-study-clean/drivers/net/dsa/sja1105/sja1105_tas.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/dsa/sja1105/sja1105_tas.c- Extension
.c- Size
- 29418 bytes
- Lines
- 899
- 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
sja1105.h
Detected Declarations
function sja1105_tas_set_runtime_paramsfunction sja1105_delta_to_nsfunction Subschedulefunction list_for_each_entryfunction futurefunction sja1105_gating_check_conflictsfunction sja1105_setup_tc_tapriofunction sja1105_tas_check_runningfunction sja1105_tas_adjust_driftfunction sja1105_tas_set_base_timefunction sja1105_tas_startfunction sja1105_tas_stopfunction periodfunction sja1105_tas_clockstepfunction sja1105_tas_adjfreqfunction sja1105_tas_setupfunction sja1105_tas_teardown
Annotated Snippet
if (earliest_base_time > offload->base_time) {
earliest_base_time = offload->base_time;
its_cycle_time = offload->cycle_time;
}
}
if (!list_empty(&gating_cfg->entries)) {
tas_data->enabled = true;
if (max_cycle_time < gating_cfg->cycle_time)
max_cycle_time = gating_cfg->cycle_time;
if (latest_base_time < gating_cfg->base_time)
latest_base_time = gating_cfg->base_time;
if (earliest_base_time > gating_cfg->base_time) {
earliest_base_time = gating_cfg->base_time;
its_cycle_time = gating_cfg->cycle_time;
}
}
if (!tas_data->enabled)
return 0;
/* Roll the earliest base time over until it is in a comparable
* time base with the latest, then compare their deltas.
* We want to enforce that all ports' base times are within
* SJA1105_TAS_MAX_DELTA 200ns cycles of one another.
*/
earliest_base_time = future_base_time(earliest_base_time,
its_cycle_time,
latest_base_time);
while (earliest_base_time > latest_base_time)
earliest_base_time -= its_cycle_time;
if (latest_base_time - earliest_base_time >
sja1105_delta_to_ns(SJA1105_TAS_MAX_DELTA)) {
dev_err(ds->dev,
"Base times too far apart: min %llu max %llu\n",
earliest_base_time, latest_base_time);
return -ERANGE;
}
tas_data->earliest_base_time = earliest_base_time;
tas_data->max_cycle_time = max_cycle_time;
dev_dbg(ds->dev, "earliest base time %lld ns\n", earliest_base_time);
dev_dbg(ds->dev, "latest base time %lld ns\n", latest_base_time);
dev_dbg(ds->dev, "longest cycle time %lld ns\n", max_cycle_time);
return 0;
}
/* Lo and behold: the egress scheduler from hell.
*
* At the hardware level, the Time-Aware Shaper holds a global linear arrray of
* all schedule entries for all ports. These are the Gate Control List (GCL)
* entries, let's call them "timeslots" for short. This linear array of
* timeslots is held in BLK_IDX_SCHEDULE.
*
* Then there are a maximum of 8 "execution threads" inside the switch, which
* iterate cyclically through the "schedule". Each "cycle" has an entry point
* and an exit point, both being timeslot indices in the schedule table. The
* hardware calls each cycle a "subschedule".
*
* Subschedule (cycle) i starts when
* ptpclkval >= ptpschtm + BLK_IDX_SCHEDULE_ENTRY_POINTS[i].delta.
*
* The hardware scheduler iterates BLK_IDX_SCHEDULE with a k ranging from
* k = BLK_IDX_SCHEDULE_ENTRY_POINTS[i].address to
* k = BLK_IDX_SCHEDULE_PARAMS.subscheind[i]
*
* For each schedule entry (timeslot) k, the engine executes the gate control
* list entry for the duration of BLK_IDX_SCHEDULE[k].delta.
*
* +---------+
* | | BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS
* +---------+
* |
* +-----------------+
* | .actsubsch
* BLK_IDX_SCHEDULE_ENTRY_POINTS v
* +-------+-------+
* |cycle 0|cycle 1|
* +-------+-------+
* | | | |
* +----------------+ | | +-------------------------------------+
* | .subschindx | | .subschindx |
* | | +---------------+ |
* | .address | .address | |
* | | | |
* | | | |
* | BLK_IDX_SCHEDULE v v |
Annotation
- Immediate include surface: `sja1105.h`.
- Detected declarations: `function sja1105_tas_set_runtime_params`, `function sja1105_delta_to_ns`, `function Subschedule`, `function list_for_each_entry`, `function future`, `function sja1105_gating_check_conflicts`, `function sja1105_setup_tc_taprio`, `function sja1105_tas_check_running`, `function sja1105_tas_adjust_drift`, `function sja1105_tas_set_base_time`.
- 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.