drivers/net/can/dev/rx-offload.c
Source file repositories/reference/linux-study-clean/drivers/net/can/dev/rx-offload.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/dev/rx-offload.c- Extension
.c- Size
- 10615 bytes
- Lines
- 428
- Domain
- Driver Families
- Bucket
- drivers/net
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/can/dev.hlinux/can/rx-offload.h
Detected Declarations
struct can_rx_offload_cbfunction can_rx_offload_get_cbfunction can_rx_offload_lefunction can_rx_offload_incfunction can_rx_offload_napi_pollfunction __skb_queue_add_sortfunction skb_queue_reverse_walkfunction can_rx_offload_comparefunction can_rx_offload_offload_onefunction can_rx_offload_irq_offload_timestampfunction can_rx_offload_incfunction can_rx_offload_irq_offload_fifofunction can_rx_offload_queue_timestampfunction can_rx_offload_get_echo_skb_queue_timestampfunction can_rx_offload_queue_tailfunction can_rx_offload_get_echo_skb_queue_tailfunction can_rx_offload_irq_finishfunction can_rx_offload_threaded_irq_finishfunction can_rx_offload_init_queuefunction can_rx_offload_add_timestampfunction can_rx_offload_add_fifofunction can_rx_offload_add_manualfunction can_rx_offload_enablefunction can_rx_offload_delexport can_rx_offload_irq_offload_timestampexport can_rx_offload_irq_offload_fifoexport can_rx_offload_queue_timestampexport can_rx_offload_get_echo_skb_queue_timestampexport can_rx_offload_queue_tailexport can_rx_offload_get_echo_skb_queue_tailexport can_rx_offload_irq_finishexport can_rx_offload_threaded_irq_finishexport can_rx_offload_add_timestampexport can_rx_offload_add_fifoexport can_rx_offload_add_manualexport can_rx_offload_enableexport can_rx_offload_del
Annotated Snippet
struct can_rx_offload_cb {
u32 timestamp;
};
static inline struct can_rx_offload_cb *
can_rx_offload_get_cb(struct sk_buff *skb)
{
BUILD_BUG_ON(sizeof(struct can_rx_offload_cb) > sizeof(skb->cb));
return (struct can_rx_offload_cb *)skb->cb;
}
static inline bool
can_rx_offload_le(struct can_rx_offload *offload,
unsigned int a, unsigned int b)
{
if (offload->inc)
return a <= b;
else
return a >= b;
}
static inline unsigned int
can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val)
{
if (offload->inc)
return (*val)++;
else
return (*val)--;
}
static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
{
struct can_rx_offload *offload = container_of(napi,
struct can_rx_offload,
napi);
struct net_device *dev = offload->dev;
struct net_device_stats *stats = &dev->stats;
struct sk_buff *skb;
int work_done = 0;
while ((work_done < quota) &&
(skb = skb_dequeue(&offload->skb_queue))) {
struct can_frame *cf = (struct can_frame *)skb->data;
work_done++;
if (!(cf->can_id & CAN_ERR_FLAG)) {
stats->rx_packets++;
if (!(cf->can_id & CAN_RTR_FLAG))
stats->rx_bytes += cf->len;
}
netif_receive_skb(skb);
}
if (work_done < quota) {
napi_complete_done(napi, work_done);
/* Check if there was another interrupt */
if (!skb_queue_empty(&offload->skb_queue))
napi_schedule(&offload->napi);
}
return work_done;
}
static inline void
__skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new,
int (*compare)(struct sk_buff *a, struct sk_buff *b))
{
struct sk_buff *pos, *insert = NULL;
skb_queue_reverse_walk(head, pos) {
const struct can_rx_offload_cb *cb_pos, *cb_new;
cb_pos = can_rx_offload_get_cb(pos);
cb_new = can_rx_offload_get_cb(new);
netdev_dbg(new->dev,
"%s: pos=0x%08x, new=0x%08x, diff=%10d, queue_len=%d\n",
__func__,
cb_pos->timestamp, cb_new->timestamp,
cb_new->timestamp - cb_pos->timestamp,
skb_queue_len(head));
if (compare(pos, new) < 0)
continue;
insert = pos;
break;
}
if (!insert)
Annotation
- Immediate include surface: `linux/can/dev.h`, `linux/can/rx-offload.h`.
- Detected declarations: `struct can_rx_offload_cb`, `function can_rx_offload_get_cb`, `function can_rx_offload_le`, `function can_rx_offload_inc`, `function can_rx_offload_napi_poll`, `function __skb_queue_add_sort`, `function skb_queue_reverse_walk`, `function can_rx_offload_compare`, `function can_rx_offload_offload_one`, `function can_rx_offload_irq_offload_timestamp`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration 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.