drivers/net/mhi_net.c
Source file repositories/reference/linux-study-clean/drivers/net/mhi_net.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/mhi_net.c- Extension
.c- Size
- 11140 bytes
- Lines
- 414
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/if_arp.hlinux/mhi.hlinux/mod_devicetable.hlinux/module.hlinux/netdevice.hlinux/skbuff.hlinux/u64_stats_sync.h
Detected Declarations
struct mhi_net_statsstruct mhi_net_devstruct mhi_device_infofunction mhi_ndo_openfunction mhi_ndo_stopfunction mhi_ndo_xmitfunction mhi_ndo_get_stats64function mhi_net_setupfunction mhi_net_dl_callbackfunction mhi_net_ul_callbackfunction mhi_net_rx_refill_workfunction mhi_net_newlinkfunction mhi_net_dellinkfunction mhi_net_probefunction mhi_net_remove
Annotated Snippet
static const struct net_device_ops mhi_netdev_ops = {
.ndo_open = mhi_ndo_open,
.ndo_stop = mhi_ndo_stop,
.ndo_start_xmit = mhi_ndo_xmit,
.ndo_get_stats64 = mhi_ndo_get_stats64,
};
static void mhi_net_setup(struct net_device *ndev)
{
ndev->header_ops = NULL; /* No header */
ndev->type = ARPHRD_RAWIP;
ndev->hard_header_len = 0;
ndev->addr_len = 0;
ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
ndev->netdev_ops = &mhi_netdev_ops;
ndev->mtu = MHI_NET_DEFAULT_MTU;
ndev->min_mtu = MHI_NET_MIN_MTU;
ndev->max_mtu = MHI_NET_MAX_MTU;
ndev->tx_queue_len = 1000;
}
static struct sk_buff *mhi_net_skb_agg(struct mhi_net_dev *mhi_netdev,
struct sk_buff *skb)
{
struct sk_buff *head = mhi_netdev->skbagg_head;
struct sk_buff *tail = mhi_netdev->skbagg_tail;
/* This is non-paged skb chaining using frag_list */
if (!head) {
mhi_netdev->skbagg_head = skb;
return skb;
}
if (!skb_shinfo(head)->frag_list)
skb_shinfo(head)->frag_list = skb;
else
tail->next = skb;
head->len += skb->len;
head->data_len += skb->len;
head->truesize += skb->truesize;
mhi_netdev->skbagg_tail = skb;
return mhi_netdev->skbagg_head;
}
static void mhi_net_dl_callback(struct mhi_device *mhi_dev,
struct mhi_result *mhi_res)
{
struct mhi_net_dev *mhi_netdev = dev_get_drvdata(&mhi_dev->dev);
struct sk_buff *skb = mhi_res->buf_addr;
int free_desc_count;
free_desc_count = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
if (unlikely(mhi_res->transaction_status)) {
switch (mhi_res->transaction_status) {
case -EOVERFLOW:
/* Packet can not fit in one MHI buffer and has been
* split over multiple MHI transfers, do re-aggregation.
* That usually means the device side MTU is larger than
* the host side MTU/MRU. Since this is not optimal,
* print a warning (once).
*/
netdev_warn_once(mhi_netdev->ndev,
"Fragmented packets received, fix MTU?\n");
skb_put(skb, mhi_res->bytes_xferd);
mhi_net_skb_agg(mhi_netdev, skb);
break;
case -ENOTCONN:
/* MHI layer stopping/resetting the DL channel */
dev_kfree_skb_any(skb);
return;
default:
/* Unknown error, simply drop */
dev_kfree_skb_any(skb);
u64_stats_update_begin(&mhi_netdev->stats.rx_syncp);
u64_stats_inc(&mhi_netdev->stats.rx_errors);
u64_stats_update_end(&mhi_netdev->stats.rx_syncp);
}
} else {
skb_put(skb, mhi_res->bytes_xferd);
if (mhi_netdev->skbagg_head) {
/* Aggregate the final fragment */
skb = mhi_net_skb_agg(mhi_netdev, skb);
mhi_netdev->skbagg_head = NULL;
}
Annotation
- Immediate include surface: `linux/if_arp.h`, `linux/mhi.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/netdevice.h`, `linux/skbuff.h`, `linux/u64_stats_sync.h`.
- Detected declarations: `struct mhi_net_stats`, `struct mhi_net_dev`, `struct mhi_device_info`, `function mhi_ndo_open`, `function mhi_ndo_stop`, `function mhi_ndo_xmit`, `function mhi_ndo_get_stats64`, `function mhi_net_setup`, `function mhi_net_dl_callback`, `function mhi_net_ul_callback`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern 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.