drivers/nfc/st-nci/ndlc.c
Source file repositories/reference/linux-study-clean/drivers/nfc/st-nci/ndlc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nfc/st-nci/ndlc.c- Extension
.c- Size
- 7506 bytes
- Lines
- 299
- Domain
- Driver Families
- Bucket
- drivers/nfc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/sched.hnet/nfc/nci_core.hst-nci.h
Detected Declarations
function ndlc_openfunction ndlc_closefunction ndlc_sendfunction llt_ndlc_send_queuefunction llt_ndlc_requeue_data_pendingfunction llt_ndlc_rcv_queuefunction llt_ndlc_sm_workfunction ndlc_recvfunction ndlc_t1_timeoutfunction ndlc_t2_timeoutfunction ndlc_probefunction ndlc_removeexport ndlc_openexport ndlc_closeexport ndlc_sendexport ndlc_recvexport ndlc_probeexport ndlc_remove
Annotated Snippet
if (r < 0) {
ndlc->hard_fault = r;
break;
}
time_sent = jiffies;
*(unsigned long *)skb->cb = time_sent;
skb_queue_tail(&ndlc->ack_pending_q, skb);
/* start timer t1 for ndlc aknowledge */
ndlc->t1_active = true;
mod_timer(&ndlc->t1_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T1));
/* start timer t2 for chip availability */
ndlc->t2_active = true;
mod_timer(&ndlc->t2_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T2));
}
}
static void llt_ndlc_requeue_data_pending(struct llt_ndlc *ndlc)
{
struct sk_buff *skb;
u8 pcb;
while ((skb = skb_dequeue_tail(&ndlc->ack_pending_q))) {
pcb = skb->data[0];
switch (pcb & PCB_TYPE_MASK) {
case PCB_TYPE_SUPERVISOR:
skb->data[0] = (pcb & ~PCB_SUPERVISOR_RETRANSMIT_MASK) |
PCB_SUPERVISOR_RETRANSMIT_YES;
break;
case PCB_TYPE_DATAFRAME:
skb->data[0] = (pcb & ~PCB_DATAFRAME_RETRANSMIT_MASK) |
PCB_DATAFRAME_RETRANSMIT_YES;
break;
default:
pr_err("UNKNOWN Packet Control Byte=%d\n", pcb);
kfree_skb(skb);
continue;
}
skb_queue_head(&ndlc->send_q, skb);
}
}
static void llt_ndlc_rcv_queue(struct llt_ndlc *ndlc)
{
struct sk_buff *skb;
u8 pcb;
unsigned long time_sent;
if (ndlc->rcv_q.qlen)
pr_debug("rcvQlen=%d\n", ndlc->rcv_q.qlen);
while ((skb = skb_dequeue(&ndlc->rcv_q)) != NULL) {
pcb = skb->data[0];
skb_pull(skb, 1);
if ((pcb & PCB_TYPE_MASK) == PCB_TYPE_SUPERVISOR) {
switch (pcb & PCB_SYNC_MASK) {
case PCB_SYNC_ACK:
skb = skb_dequeue(&ndlc->ack_pending_q);
kfree_skb(skb);
timer_delete_sync(&ndlc->t1_timer);
timer_delete_sync(&ndlc->t2_timer);
ndlc->t2_active = false;
ndlc->t1_active = false;
break;
case PCB_SYNC_NACK:
llt_ndlc_requeue_data_pending(ndlc);
llt_ndlc_send_queue(ndlc);
/* start timer t1 for ndlc aknowledge */
time_sent = jiffies;
ndlc->t1_active = true;
mod_timer(&ndlc->t1_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T1));
break;
case PCB_SYNC_WAIT:
time_sent = jiffies;
ndlc->t1_active = true;
mod_timer(&ndlc->t1_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T1_WAIT));
break;
default:
kfree_skb(skb);
break;
}
} else if ((pcb & PCB_TYPE_MASK) == PCB_TYPE_DATAFRAME) {
nci_recv_frame(ndlc->ndev, skb);
} else {
kfree_skb(skb);
Annotation
- Immediate include surface: `linux/sched.h`, `net/nfc/nci_core.h`, `st-nci.h`.
- Detected declarations: `function ndlc_open`, `function ndlc_close`, `function ndlc_send`, `function llt_ndlc_send_queue`, `function llt_ndlc_requeue_data_pending`, `function llt_ndlc_rcv_queue`, `function llt_ndlc_sm_work`, `function ndlc_recv`, `function ndlc_t1_timeout`, `function ndlc_t2_timeout`.
- Atlas domain: Driver Families / drivers/nfc.
- Implementation status: integration 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.