drivers/net/wwan/mhi_wwan_mbim.c
Source file repositories/reference/linux-study-clean/drivers/net/wwan/mhi_wwan_mbim.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wwan/mhi_wwan_mbim.c- Extension
.c- Size
- 18194 bytes
- Lines
- 671
- 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.
- 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
linux/ethtool.hlinux/if_arp.hlinux/if_vlan.hlinux/ip.hlinux/mhi.hlinux/mii.hlinux/mod_devicetable.hlinux/module.hlinux/netdevice.hlinux/skbuff.hlinux/u64_stats_sync.hlinux/usb.hlinux/usb/cdc.hlinux/usb/usbnet.hlinux/usb/cdc_ncm.hlinux/wwan.h
Detected Declarations
struct mhi_mbim_linkstruct mhi_mbim_contextstruct mbim_tx_hdrfunction hlist_for_each_entry_rcufunction mhi_mbim_get_link_mux_idfunction mhi_mbim_ndo_xmitfunction mbim_rx_verify_nth16function mbim_rx_verify_ndp16function mhi_mbim_rxfunction mhi_net_rx_refill_workfunction mhi_mbim_dl_callbackfunction mhi_mbim_ndo_get_stats64function mhi_mbim_ul_callbackfunction mhi_mbim_ndo_openfunction mhi_mbim_ndo_stopfunction mhi_mbim_newlinkfunction mhi_mbim_dellinkfunction mhi_mbim_setupfunction mhi_mbim_probefunction mhi_mbim_remove
Annotated Snippet
static const struct net_device_ops mhi_mbim_ndo = {
.ndo_open = mhi_mbim_ndo_open,
.ndo_stop = mhi_mbim_ndo_stop,
.ndo_start_xmit = mhi_mbim_ndo_xmit,
.ndo_get_stats64 = mhi_mbim_ndo_get_stats64,
};
static int mhi_mbim_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
struct netlink_ext_ack *extack)
{
struct mhi_mbim_link *link = wwan_netdev_drvpriv(ndev);
struct mhi_mbim_context *mbim = ctxt;
link->mbim = mbim;
link->session = mhi_mbim_get_link_mux_id(link->mbim->mdev->mhi_cntrl) + if_id;
link->ndev = ndev;
u64_stats_init(&link->rx_syncp);
u64_stats_init(&link->tx_syncp);
rcu_read_lock();
if (mhi_mbim_get_link_rcu(mbim, if_id)) {
rcu_read_unlock();
return -EEXIST;
}
rcu_read_unlock();
/* Already protected by RTNL lock */
hlist_add_head_rcu(&link->hlnode, &mbim->link_list[LINK_HASH(if_id)]);
return register_netdevice(ndev);
}
static void mhi_mbim_dellink(void *ctxt, struct net_device *ndev,
struct list_head *head)
{
struct mhi_mbim_link *link = wwan_netdev_drvpriv(ndev);
hlist_del_init_rcu(&link->hlnode);
synchronize_rcu();
unregister_netdevice_queue(ndev, head);
}
static void mhi_mbim_setup(struct net_device *ndev)
{
ndev->header_ops = NULL; /* No header */
ndev->type = ARPHRD_RAWIP;
ndev->needed_headroom = sizeof(struct mbim_tx_hdr);
ndev->hard_header_len = 0;
ndev->addr_len = 0;
ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
ndev->netdev_ops = &mhi_mbim_ndo;
ndev->mtu = MHI_MBIM_DEFAULT_MTU;
ndev->min_mtu = ETH_MIN_MTU;
ndev->max_mtu = MHI_MAX_BUF_SZ - ndev->needed_headroom;
ndev->tx_queue_len = 1000;
ndev->needs_free_netdev = true;
}
static const struct wwan_ops mhi_mbim_wwan_ops = {
.priv_size = sizeof(struct mhi_mbim_link),
.setup = mhi_mbim_setup,
.newlink = mhi_mbim_newlink,
.dellink = mhi_mbim_dellink,
};
static int mhi_mbim_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
{
struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
struct mhi_mbim_context *mbim;
int err;
mbim = devm_kzalloc(&mhi_dev->dev, sizeof(*mbim), GFP_KERNEL);
if (!mbim)
return -ENOMEM;
spin_lock_init(&mbim->tx_lock);
dev_set_drvdata(&mhi_dev->dev, mbim);
mbim->mdev = mhi_dev;
mbim->mru = mhi_dev->mhi_cntrl->mru ? mhi_dev->mhi_cntrl->mru : MHI_DEFAULT_MRU;
INIT_DELAYED_WORK(&mbim->rx_refill, mhi_net_rx_refill_work);
/* Start MHI channels */
err = mhi_prepare_for_transfer(mhi_dev);
if (err)
return err;
/* Number of transfer descriptors determines size of the queue */
mbim->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
Annotation
- Immediate include surface: `linux/ethtool.h`, `linux/if_arp.h`, `linux/if_vlan.h`, `linux/ip.h`, `linux/mhi.h`, `linux/mii.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `struct mhi_mbim_link`, `struct mhi_mbim_context`, `struct mbim_tx_hdr`, `function hlist_for_each_entry_rcu`, `function mhi_mbim_get_link_mux_id`, `function mhi_mbim_ndo_xmit`, `function mbim_rx_verify_nth16`, `function mbim_rx_verify_ndp16`, `function mhi_mbim_rx`, `function mhi_net_rx_refill_work`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern 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.