drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c- Extension
.c- Size
- 39771 bytes
- Lines
- 1435
- 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
net/tso.hlinux/tcp.hiwl-debug.hiwl-csr.hiwl-io.hinternal.hfw/api/tx.hfw/api/commands.hfw/api/datapath.hiwl-scd.h
Detected Declarations
function Copyrightfunction dma_unmap_pagefunction get_workaround_pagefunction iwl_txq_gen2_build_amsdufunction iwl_txq_gen2_tx_add_fragsfunction skb_walk_fragsfunction iwl_txq_spacefunction iwl_pcie_gen2_update_byte_tblfunction iwl_txq_gen2_get_num_tbsfunction iwl_txq_gen2_set_tbfunction iwl_txq_gen2_tfd_unmapfunction iwl_txq_gen2_free_tfdfunction iwl_txq_inc_wr_ptrfunction iwl_txq_gen2_txfunction iwl_txq_gen2_unmapfunction iwl_txq_gen2_free_memoryfunction iwl_txq_gen2_freefunction iwl_txq_dyn_alloc_dmafunction iwl_pcie_txq_alloc_responsefunction iwl_txq_dyn_allocfunction iwl_txq_dyn_freefunction iwl_txq_gen2_tx_freefunction iwl_txq_gen2_initfunction iwl_pcie_gen2_enqueue_hcmdfunction iwl_get_cmd_string
Annotated Snippet
while (data_left) {
int ret;
tb_len = min_t(unsigned int, tso.size, data_left);
tb_phys = iwl_pcie_get_sgt_tb_phys(sgt, data_offset,
tb_len);
/* Not a real mapping error, use direct comparison */
if (unlikely(tb_phys == DMA_MAPPING_ERROR))
goto out_err;
ret = iwl_txq_gen2_set_tb_with_wa(trans, skb, tfd,
tb_phys, tso.data,
tb_len, NULL, false);
if (ret)
goto out_err;
data_left -= tb_len;
data_offset += tb_len;
tso_build_data(skb, &tso, tb_len);
}
}
dma_sync_single_for_device(trans->dev, start_hdr_phys, hdr_room,
DMA_TO_DEVICE);
/* re -add the WiFi header */
skb_push(skb, hdr_len);
return 0;
out_err:
#endif
return -EINVAL;
}
static struct
iwl_tfh_tfd *iwl_txq_gen2_build_tx_amsdu(struct iwl_trans *trans,
struct iwl_txq *txq,
struct iwl_device_tx_cmd *dev_cmd,
struct sk_buff *skb,
struct iwl_cmd_meta *out_meta,
int hdr_len,
int tx_cmd_len)
{
int idx = iwl_txq_get_cmd_index(txq, txq->write_ptr);
struct iwl_tfh_tfd *tfd = iwl_txq_get_tfd(trans, txq, idx);
dma_addr_t tb_phys;
int len;
void *tb1_addr;
tb_phys = iwl_txq_get_first_tb_dma(txq, idx);
/*
* No need for _with_wa, the first TB allocation is aligned up
* to a 64-byte boundary and thus can't be at the end or cross
* a page boundary (much less a 2^32 boundary).
*/
iwl_txq_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);
/*
* The second TB (tb1) points to the remainder of the TX command
* and the 802.11 header - dword aligned size
* (This calculation modifies the TX command, so do it before the
* setup of the first TB)
*/
len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len -
IWL_FIRST_TB_SIZE;
/* do not align A-MSDU to dword as the subframe header aligns it */
/* map the data for TB1 */
tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE;
tb_phys = dma_map_single(trans->dev, tb1_addr, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
goto out_err;
/*
* No need for _with_wa(), we ensure (via alignment) that the data
* here can never cross or end at a page boundary.
*/
iwl_txq_gen2_set_tb(trans, tfd, tb_phys, len);
if (iwl_txq_gen2_build_amsdu(trans, skb, tfd, out_meta,
len + IWL_FIRST_TB_SIZE, hdr_len, dev_cmd))
goto out_err;
/* building the A-MSDU might have changed this data, memcpy it now */
memcpy(&txq->first_tb_bufs[idx], dev_cmd, IWL_FIRST_TB_SIZE);
return tfd;
out_err:
Annotation
- Immediate include surface: `net/tso.h`, `linux/tcp.h`, `iwl-debug.h`, `iwl-csr.h`, `iwl-io.h`, `internal.h`, `fw/api/tx.h`, `fw/api/commands.h`.
- Detected declarations: `function Copyright`, `function dma_unmap_page`, `function get_workaround_page`, `function iwl_txq_gen2_build_amsdu`, `function iwl_txq_gen2_tx_add_frags`, `function skb_walk_frags`, `function iwl_txq_space`, `function iwl_pcie_gen2_update_byte_tbl`, `function iwl_txq_gen2_get_num_tbs`, `function iwl_txq_gen2_set_tb`.
- 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.