drivers/net/wwan/mhi_wwan_ctrl.c
Source file repositories/reference/linux-study-clean/drivers/net/wwan/mhi_wwan_ctrl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wwan/mhi_wwan_ctrl.c- Extension
.c- Size
- 7847 bytes
- Lines
- 287
- 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.
- 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/kernel.hlinux/mhi.hlinux/mod_devicetable.hlinux/module.hlinux/wwan.h
Detected Declarations
struct mhi_wwan_devenum mhi_wwan_flagsfunction mhi_wwan_rx_budget_incfunction mhi_wwan_rx_budget_decfunction __mhi_skb_destructorfunction mhi_wwan_ctrl_refill_workfunction mhi_wwan_ctrl_startfunction mhi_wwan_ctrl_stopfunction mhi_wwan_ctrl_txfunction mhi_ul_xfer_cbfunction mhi_dl_xfer_cbfunction mhi_wwan_ctrl_probefunction mhi_wwan_ctrl_remove
Annotated Snippet
struct mhi_wwan_dev {
/* Lower level is a mhi dev, upper level is a wwan port */
struct mhi_device *mhi_dev;
struct wwan_port *wwan_port;
/* State and capabilities */
unsigned long flags;
size_t mtu;
/* Protect against concurrent TX and TX-completion (bh) */
spinlock_t tx_lock;
/* Protect RX budget and rx_refill scheduling */
spinlock_t rx_lock;
struct work_struct rx_refill;
/* RX budget is initially set to the size of the MHI RX queue and is
* used to limit the number of allocated and queued packets. It is
* decremented on data queueing and incremented on data release.
*/
unsigned int rx_budget;
};
/* Increment RX budget and schedule RX refill if necessary */
static void mhi_wwan_rx_budget_inc(struct mhi_wwan_dev *mhiwwan)
{
spin_lock_bh(&mhiwwan->rx_lock);
mhiwwan->rx_budget++;
if (test_bit(MHI_WWAN_RX_REFILL, &mhiwwan->flags))
schedule_work(&mhiwwan->rx_refill);
spin_unlock_bh(&mhiwwan->rx_lock);
}
/* Decrement RX budget if non-zero and return true on success */
static bool mhi_wwan_rx_budget_dec(struct mhi_wwan_dev *mhiwwan)
{
bool ret = false;
spin_lock_bh(&mhiwwan->rx_lock);
if (mhiwwan->rx_budget) {
mhiwwan->rx_budget--;
if (test_bit(MHI_WWAN_RX_REFILL, &mhiwwan->flags))
ret = true;
}
spin_unlock_bh(&mhiwwan->rx_lock);
return ret;
}
static void __mhi_skb_destructor(struct sk_buff *skb)
{
/* RX buffer has been consumed, increase the allowed budget */
mhi_wwan_rx_budget_inc(skb_shinfo(skb)->destructor_arg);
}
static void mhi_wwan_ctrl_refill_work(struct work_struct *work)
{
struct mhi_wwan_dev *mhiwwan = container_of(work, struct mhi_wwan_dev, rx_refill);
struct mhi_device *mhi_dev = mhiwwan->mhi_dev;
while (mhi_wwan_rx_budget_dec(mhiwwan)) {
struct sk_buff *skb;
skb = alloc_skb(mhiwwan->mtu, GFP_KERNEL);
if (!skb) {
mhi_wwan_rx_budget_inc(mhiwwan);
break;
}
/* To prevent unlimited buffer allocation if nothing consumes
* the RX buffers (passed to WWAN core), track their lifespan
* to not allocate more than allowed budget.
*/
skb->destructor = __mhi_skb_destructor;
skb_shinfo(skb)->destructor_arg = mhiwwan;
if (mhi_queue_skb(mhi_dev, DMA_FROM_DEVICE, skb, mhiwwan->mtu, MHI_EOT)) {
dev_err(&mhi_dev->dev, "Failed to queue buffer\n");
kfree_skb(skb);
break;
}
}
}
static int mhi_wwan_ctrl_start(struct wwan_port *port)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/mhi.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/wwan.h`.
- Detected declarations: `struct mhi_wwan_dev`, `enum mhi_wwan_flags`, `function mhi_wwan_rx_budget_inc`, `function mhi_wwan_rx_budget_dec`, `function __mhi_skb_destructor`, `function mhi_wwan_ctrl_refill_work`, `function mhi_wwan_ctrl_start`, `function mhi_wwan_ctrl_stop`, `function mhi_wwan_ctrl_tx`, `function mhi_ul_xfer_cb`.
- 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.
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.