drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c- Extension
.c- Size
- 28807 bytes
- Lines
- 1134
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/ptp_classify.hlinux/units.hlan966x_main.hvcap_api.hvcap_api_client.h
Detected Declarations
function lan966x_ptp_get_nominal_valuefunction lan966x_ptp_add_trapfunction lan966x_ptp_del_trapfunction lan966x_ptp_add_l2_keyfunction lan966x_ptp_add_ip_event_keyfunction lan966x_ptp_add_ip_general_keyfunction lan966x_ptp_add_l2_rulefunction lan966x_ptp_add_ipv4_rulesfunction lan966x_ptp_add_ipv6_rulesfunction lan966x_ptp_del_l2_rulefunction lan966x_ptp_del_ipv4_rulesfunction lan966x_ptp_del_ipv6_rulesfunction lan966x_ptp_add_trapsfunction lan966x_ptp_del_trapsfunction lan966x_ptp_setup_trapsfunction lan966x_ptp_hwtstamp_setfunction lan966x_ptp_hwtstamp_getfunction lan966x_ptp_classifyfunction lan966x_ptp_txtstamp_old_releasefunction lan966x_ptp_txtstamp_requestfunction lan966x_ptp_txtstamp_releasefunction lan966x_get_hwtimestampfunction lan966x_ptp_irq_handlerfunction skb_queue_walk_safefunction lan966x_ptp_ext_irq_handlerfunction lan966x_ptp_adjfinefunction lan966x_ptp_settime64function lan966x_ptp_gettime64function lan966x_ptp_adjtimefunction lan966x_ptp_verifyfunction lan966x_ptp_peroutfunction lan966x_ptp_exttsfunction lan966x_ptp_enablefunction lan966x_ptp_phc_initfunction lan966x_ptp_initfunction lan966x_ptp_deinitfunction lan966x_ptp_rxtstampfunction lan966x_ptp_get_period_ps
Annotated Snippet
skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
if (LAN966X_SKB_CB(skb)->ts_id != id)
continue;
__skb_unlink(skb, &port->tx_skbs);
skb_match = skb;
break;
}
spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
/* Next ts */
lan_rmw(PTP_TWOSTEP_CTRL_NXT_SET(1),
PTP_TWOSTEP_CTRL_NXT,
lan966x, PTP_TWOSTEP_CTRL);
if (WARN_ON(!skb_match))
continue;
spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags);
lan966x->ptp_skbs--;
spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags);
/* Get the h/w timestamp */
lan966x_get_hwtimestamp(lan966x, &ts, delay);
/* Set the timestamp into the skb */
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
skb_tstamp_tx(skb_match, &shhwtstamps);
dev_kfree_skb_any(skb_match);
}
return IRQ_HANDLED;
}
irqreturn_t lan966x_ptp_ext_irq_handler(int irq, void *args)
{
struct lan966x *lan966x = args;
struct lan966x_phc *phc;
unsigned long flags;
u64 time = 0;
time64_t s;
int pin, i;
s64 ns;
if (!(lan_rd(lan966x, PTP_PIN_INTR)))
return IRQ_NONE;
/* Go through all domains and see which pin generated the interrupt */
for (i = 0; i < LAN966X_PHC_COUNT; ++i) {
struct ptp_clock_event ptp_event = {0};
phc = &lan966x->phc[i];
pin = ptp_find_pin_unlocked(phc->clock, PTP_PF_EXTTS, 0);
if (pin == -1)
continue;
if (!(lan_rd(lan966x, PTP_PIN_INTR) & BIT(pin)))
continue;
spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
/* Enable to get the new interrupt.
* By writing 1 it clears the bit
*/
lan_wr(BIT(pin), lan966x, PTP_PIN_INTR);
/* Get current time */
s = lan_rd(lan966x, PTP_TOD_SEC_MSB(pin));
s <<= 32;
s |= lan_rd(lan966x, PTP_TOD_SEC_LSB(pin));
ns = lan_rd(lan966x, PTP_TOD_NSEC(pin));
ns &= PTP_TOD_NSEC_TOD_NSEC;
spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
if ((ns & 0xFFFFFFF0) == 0x3FFFFFF0) {
s--;
ns &= 0xf;
ns += 999999984;
}
time = ktime_set(s, ns);
ptp_event.index = pin;
ptp_event.timestamp = time;
ptp_event.type = PTP_CLOCK_EXTTS;
ptp_clock_event(phc->clock, &ptp_event);
}
return IRQ_HANDLED;
Annotation
- Immediate include surface: `linux/ptp_classify.h`, `linux/units.h`, `lan966x_main.h`, `vcap_api.h`, `vcap_api_client.h`.
- Detected declarations: `function lan966x_ptp_get_nominal_value`, `function lan966x_ptp_add_trap`, `function lan966x_ptp_del_trap`, `function lan966x_ptp_add_l2_key`, `function lan966x_ptp_add_ip_event_key`, `function lan966x_ptp_add_ip_general_key`, `function lan966x_ptp_add_l2_rule`, `function lan966x_ptp_add_ipv4_rules`, `function lan966x_ptp_add_ipv6_rules`, `function lan966x_ptp_del_l2_rule`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.