drivers/net/wwan/t7xx/t7xx_hif_cldma.c
Source file repositories/reference/linux-study-clean/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wwan/t7xx/t7xx_hif_cldma.c- Extension
.c- Size
- 38163 bytes
- Lines
- 1363
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/bits.hlinux/bitops.hlinux/delay.hlinux/device.hlinux/dmapool.hlinux/dma-mapping.hlinux/dma-direction.hlinux/gfp.hlinux/io.hlinux/io-64-nonatomic-lo-hi.hlinux/iopoll.hlinux/irqreturn.hlinux/kernel.hlinux/kthread.hlinux/list.hlinux/netdevice.hlinux/pci.hlinux/pm_runtime.hlinux/sched.hlinux/skbuff.hlinux/slab.hlinux/spinlock.hlinux/types.hlinux/wait.hlinux/workqueue.ht7xx_cldma.ht7xx_hif_cldma.ht7xx_mhccif.ht7xx_pci.ht7xx_pcie_mac.ht7xx_port_proxy.ht7xx_reg.h
Detected Declarations
function Copyrightfunction md_cd_queue_struct_initfunction t7xx_cldma_gpd_set_data_ptrfunction t7xx_cldma_gpd_set_next_ptrfunction t7xx_cldma_alloc_and_map_skbfunction t7xx_cldma_gpd_rx_from_qfunction t7xx_cldma_gpd_rx_collectfunction t7xx_cldma_rx_donefunction t7xx_cldma_gpd_tx_collectfunction t7xx_cldma_txq_empty_hndlfunction t7xx_cldma_tx_donefunction t7xx_cldma_ring_freefunction list_for_each_entry_safefunction t7xx_cldma_rx_ring_initfunction t7xx_cldma_tx_ring_initfunction t7xx_cldma_q_resetfunction t7xx_cldma_rxq_initfunction t7xx_cldma_txq_initfunction t7xx_cldma_enable_irqfunction t7xx_cldma_disable_irqfunction t7xx_cldma_irq_work_cbfunction for_each_set_bitfunction t7xx_cldma_qs_are_activefunction t7xx_cldma_stopfunction t7xx_cldma_late_releasefunction t7xx_cldma_resetfunction t7xx_cldma_startfunction t7xx_cldma_clear_txqfunction t7xx_cldma_clear_rxqfunction list_for_each_entryfunction t7xx_cldma_clear_all_qsfunction t7xx_cldma_stop_all_qsfunction t7xx_cldma_gpd_handle_tx_requestfunction t7xx_cldma_hw_start_sendfunction t7xx_cldma_set_recv_skbfunction t7xx_cldma_send_skbfunction t7xx_cldma_adjust_configfunction t7xx_cldma_late_initfunction t7xx_hw_info_initfunction t7xx_cldma_default_recv_skbfunction t7xx_cldma_allocfunction t7xx_cldma_resume_earlyfunction t7xx_cldma_resumefunction t7xx_cldma_suspend_latefunction t7xx_cldma_suspendfunction t7xx_cldma_pm_initfunction t7xx_cldma_pm_uninitfunction t7xx_cldma_hif_hw_init
Annotated Snippet
if ((gpd->flags & GPD_FLAGS_HWO) || !req->skb) {
dma_addr_t gpd_addr;
if (!pci_device_is_present(to_pci_dev(md_ctrl->dev))) {
dev_err(md_ctrl->dev, "PCIe Link disconnected\n");
return -ENODEV;
}
gpd_addr = ioread64_lo_hi(hw_info->ap_pdn_base +
REG_CLDMA_DL_CURRENT_ADDRL_0 +
queue->index * sizeof(u64));
if (req->gpd_addr == gpd_addr || hwo_polling_count++ >= 100)
return 0;
udelay(1);
continue;
}
hwo_polling_count = 0;
skb = req->skb;
if (req->mapped_buff) {
dma_unmap_single(md_ctrl->dev, req->mapped_buff,
queue->tr_ring->pkt_size, DMA_FROM_DEVICE);
req->mapped_buff = 0;
}
skb->len = 0;
skb_reset_tail_pointer(skb);
skb_put(skb, le16_to_cpu(gpd->data_buff_len));
ret = queue->recv_skb(queue, skb);
/* Break processing, will try again later */
if (ret < 0)
return ret;
req->skb = NULL;
t7xx_cldma_gpd_set_data_ptr(gpd, 0);
spin_lock_irqsave(&queue->ring_lock, flags);
queue->tr_done = list_next_entry_circular(req, &queue->tr_ring->gpd_ring, entry);
spin_unlock_irqrestore(&queue->ring_lock, flags);
req = queue->rx_refill;
ret = t7xx_cldma_alloc_and_map_skb(md_ctrl, req, queue->tr_ring->pkt_size, GFP_KERNEL);
if (ret)
return ret;
gpd = req->gpd;
t7xx_cldma_gpd_set_data_ptr(gpd, req->mapped_buff);
gpd->data_buff_len = 0;
gpd->flags = GPD_FLAGS_IOC | GPD_FLAGS_HWO;
spin_lock_irqsave(&queue->ring_lock, flags);
queue->rx_refill = list_next_entry_circular(req, &queue->tr_ring->gpd_ring, entry);
spin_unlock_irqrestore(&queue->ring_lock, flags);
rx_not_done = ++count < budget || !need_resched();
} while (rx_not_done);
*over_budget = true;
return 0;
}
static int t7xx_cldma_gpd_rx_collect(struct cldma_queue *queue, int budget)
{
struct cldma_ctrl *md_ctrl = queue->md_ctrl;
struct t7xx_cldma_hw *hw_info;
unsigned int pending_rx_int;
bool over_budget = false;
unsigned long flags;
int ret;
hw_info = &md_ctrl->hw_info;
do {
ret = t7xx_cldma_gpd_rx_from_q(queue, budget, &over_budget);
if (ret == -ENODATA)
return 0;
else if (ret)
return ret;
pending_rx_int = 0;
spin_lock_irqsave(&md_ctrl->cldma_lock, flags);
if (md_ctrl->rxq_active & BIT(queue->index)) {
if (!t7xx_cldma_hw_queue_status(hw_info, queue->index, MTK_RX))
t7xx_cldma_hw_resume_queue(hw_info, queue->index, MTK_RX);
pending_rx_int = t7xx_cldma_hw_int_status(hw_info, BIT(queue->index),
Annotation
- Immediate include surface: `linux/bits.h`, `linux/bitops.h`, `linux/delay.h`, `linux/device.h`, `linux/dmapool.h`, `linux/dma-mapping.h`, `linux/dma-direction.h`, `linux/gfp.h`.
- Detected declarations: `function Copyright`, `function md_cd_queue_struct_init`, `function t7xx_cldma_gpd_set_data_ptr`, `function t7xx_cldma_gpd_set_next_ptr`, `function t7xx_cldma_alloc_and_map_skb`, `function t7xx_cldma_gpd_rx_from_q`, `function t7xx_cldma_gpd_rx_collect`, `function t7xx_cldma_rx_done`, `function t7xx_cldma_gpd_tx_collect`, `function t7xx_cldma_txq_empty_hndl`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.