drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c- Extension
.c- Size
- 75345 bytes
- Lines
- 2687
- 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/etherdevice.hlinux/ieee80211.hlinux/dmapool.hlinux/slab.hlinux/sched.hlinux/tcp.hnet/ip6_checksum.hnet/tso.hfw/api/commands.hfw/api/datapath.hfw/api/debug.hiwl-fh.hiwl-debug.hiwl-csr.hiwl-prph.hiwl-io.hiwl-scd.hiwl-op-mode.hinternal.hfw/api/tx.hfw/dbg.hpcie/utils.h
Detected Declarations
function Copyrightfunction iwl_pcie_free_dma_ptrfunction iwl_pcie_txq_inc_wr_ptrfunction test_bitfunction iwl_pcie_txq_check_wrptrsfunction iwl_pcie_gen1_tfd_set_tbfunction iwl_txq_gen1_tfd_get_num_tbsfunction iwl_pcie_txq_build_tfdfunction iwl_pcie_clear_cmd_in_flightfunction iwl_pcie_free_and_unmap_tso_pagefunction iwl_pcie_free_tso_pagesfunction iwl_txq_gen1_tfd_tb_get_addrfunction iwl_txq_set_tfd_invalid_gen1function iwl_txq_gen1_tfd_unmapfunction itselffunction iwl_pcie_txq_unmapfunction iwl_pcie_txq_freefunction iwl_pcie_tx_startfunction iwl_trans_pcie_tx_resetfunction iwl_pcie_tx_stop_fhfunction iwl_pcie_tx_stopfunction iwl_pcie_tx_freefunction iwl_txq_log_scd_errorfunction iwl_txq_stuck_timerfunction iwl_pcie_txq_allocfunction iwl_pcie_tx_allocfunction iwl_queue_initfunction iwl_txq_initfunction iwl_pcie_tx_initfunction iwl_pcie_set_cmd_in_flightfunction iwl_txq_progressfunction iwl_txq_usedfunction spacefunction iwl_pcie_txq_set_ratid_mapfunction IDfunction iwl_trans_pcie_txq_set_shared_modefunction iwl_trans_pcie_txq_disablefunction iwl_trans_pcie_block_txq_ptrsfunction iwl_pcie_enqueue_hcmdfunction iwl_get_cmd_stringfunction iwl_pcie_hcmd_completefunction iwl_fill_data_tbsfunction iwl_pcie_get_sgt_tb_physfunction iwl_fill_data_tbs_amsdufunction iwl_fill_data_tbs_amsdufunction iwl_txq_gen1_update_byte_cnt_tblfunction iwl_trans_pcie_txfunction skb_walk_frags
Annotated Snippet
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
/*
* wake up nic if it's powered down ...
* uCode will wake up, and interrupt us again, so next
* time we'll skip this part.
*/
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
txq_id, reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
txq->need_update = true;
return;
}
}
/*
* if not in power-save mode, uCode will never sleep when we're
* trying to tx (during RFKILL, we're not trying to tx).
*/
IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->write_ptr);
if (!txq->block)
iwl_write32(trans, HBUS_TARG_WRPTR,
txq->write_ptr | (txq_id << 8));
}
void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int i;
for (i = 0; i < trans->mac_cfg->base->num_of_queues; i++) {
struct iwl_txq *txq = trans_pcie->txqs.txq[i];
if (!test_bit(i, trans_pcie->txqs.queue_used))
continue;
spin_lock_bh(&txq->lock);
if (txq->need_update) {
iwl_pcie_txq_inc_wr_ptr(trans, txq);
txq->need_update = false;
}
spin_unlock_bh(&txq->lock);
}
}
static inline void iwl_pcie_gen1_tfd_set_tb(struct iwl_tfd *tfd,
u8 idx, dma_addr_t addr, u16 len)
{
struct iwl_tfd_tb *tb = &tfd->tbs[idx];
u16 hi_n_len = len << 4;
put_unaligned_le32(addr, &tb->lo);
hi_n_len |= iwl_get_dma_hi_addr(addr);
tb->hi_n_len = cpu_to_le16(hi_n_len);
tfd->num_tbs = idx + 1;
}
static inline u8 iwl_txq_gen1_tfd_get_num_tbs(struct iwl_tfd *tfd)
{
return tfd->num_tbs & 0x1f;
}
static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
dma_addr_t addr, u16 len, bool reset)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
void *tfd;
u32 num_tbs;
tfd = (u8 *)txq->tfds + trans_pcie->txqs.tfd.size * txq->write_ptr;
if (reset)
memset(tfd, 0, trans_pcie->txqs.tfd.size);
num_tbs = iwl_txq_gen1_tfd_get_num_tbs(tfd);
/* Each TFD can point to a maximum max_tbs Tx buffers */
if (num_tbs >= trans_pcie->txqs.tfd.max_tbs) {
IWL_ERR(trans, "Error can not send more than %d chunks\n",
trans_pcie->txqs.tfd.max_tbs);
return -EINVAL;
}
if (WARN(addr & ~IWL_TX_DMA_MASK,
"Unaligned address = %llx\n", (unsigned long long)addr))
Annotation
- Immediate include surface: `linux/etherdevice.h`, `linux/ieee80211.h`, `linux/dmapool.h`, `linux/slab.h`, `linux/sched.h`, `linux/tcp.h`, `net/ip6_checksum.h`, `net/tso.h`.
- Detected declarations: `function Copyright`, `function iwl_pcie_free_dma_ptr`, `function iwl_pcie_txq_inc_wr_ptr`, `function test_bit`, `function iwl_pcie_txq_check_wrptrs`, `function iwl_pcie_gen1_tfd_set_tb`, `function iwl_txq_gen1_tfd_get_num_tbs`, `function iwl_pcie_txq_build_tfd`, `function iwl_pcie_clear_cmd_in_flight`, `function iwl_pcie_free_and_unmap_tso_page`.
- 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.