drivers/net/wireless/ti/wlcore/tx.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/ti/wlcore/tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/ti/wlcore/tx.c- Extension
.c- Size
- 34910 bytes
- Lines
- 1317
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/etherdevice.hlinux/pm_runtime.hlinux/spinlock.hwlcore.hdebug.hio.hps.htx.hevent.hhw_ops.h../wl12xx/reg.h
Detected Declarations
function Copyrightfunction wl1271_alloc_tx_idfunction wl1271_free_tx_idfunction wl1271_tx_ap_update_inconnection_stafunction wl1271_tx_regulate_linkfunction wl12xx_is_dummy_packetfunction wl12xx_tx_get_hlid_apfunction wl12xx_tx_get_hlidfunction wlcore_calc_packet_alignmentfunction wl1271_tx_allocatefunction wl1271_tx_fill_hdrfunction wl1271_prepare_tx_framefunction wl1271_tx_enabled_rates_getfunction wl1271_handle_tx_low_watermarkfunction wl12xx_for_each_wlviffunction wlcore_select_acfunction wl12xx_for_each_wlvif_continuefunction wl12xx_for_each_wlviffunction test_and_clear_bitfunction wl1271_skb_queue_headfunction wl1271_tx_is_data_presentfunction wl12xx_rearm_rx_streamingfunction for_each_set_bitfunction wlcore_tx_work_lockedfunction wl1271_tx_workfunction wl1271_tx_get_rate_flagsfunction wl1271_tx_complete_packetfunction wlcore_tx_completefunction wl1271_tx_reset_link_queuesfunction wl12xx_tx_reset_wlviffunction wl12xx_tx_resetfunction wl1271_tx_flushfunction wl1271_tx_min_rate_getfunction wlcore_stop_queue_lockedfunction wlcore_stop_queuefunction wlcore_wake_queuefunction wlcore_stop_queuesfunction wlcore_wake_queuesfunction wlcore_is_queue_stopped_by_reasonfunction wlcore_is_queue_stopped_by_reason_lockedfunction wlcore_is_queue_stopped_lockedexport wl1271_free_tx_idexport wl12xx_is_dummy_packetexport wlcore_calc_packet_alignmentexport wlcore_tx_completeexport wl1271_tx_flushexport wl1271_tx_min_rate_get
Annotated Snippet
pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) {
wl1271_free_tx_id(wl, id);
return -ENOMEM;
}
desc = skb_push(skb, total_len - skb->len);
wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
spare_blocks);
desc->id = id;
wl->tx_blocks_available -= total_blocks;
wl->tx_allocated_blocks += total_blocks;
/*
* If the FW was empty before, arm the Tx watchdog. Also do
* this on the first Tx after resume, as we always cancel the
* watchdog on suspend.
*/
if (wl->tx_allocated_blocks == total_blocks ||
test_and_clear_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags))
wl12xx_rearm_tx_watchdog_locked(wl);
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
wl->tx_allocated_pkts[ac]++;
if (test_bit(hlid, wl->links_map))
wl->links[hlid].allocated_pkts++;
ret = 0;
wl1271_debug(DEBUG_TX,
"tx_allocate: size: %d, blocks: %d, id: %d",
total_len, total_blocks, id);
} else {
wl1271_free_tx_id(wl, id);
}
return ret;
}
static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct sk_buff *skb, u32 extra,
struct ieee80211_tx_info *control, u8 hlid)
{
struct wl1271_tx_hw_descr *desc;
int ac, rate_idx;
s64 hosttime;
u16 tx_attr = 0;
__le16 frame_control;
struct ieee80211_hdr *hdr;
u8 *frame_start;
bool is_dummy;
desc = (struct wl1271_tx_hw_descr *) skb->data;
frame_start = (u8 *)(desc + 1);
hdr = (struct ieee80211_hdr *)(frame_start + extra);
frame_control = hdr->frame_control;
/* relocate space for security header */
if (extra) {
int hdrlen = ieee80211_hdrlen(frame_control);
memmove(frame_start, hdr, hdrlen);
skb_set_network_header(skb, skb_network_offset(skb) + extra);
}
/* configure packet life time */
hosttime = (ktime_get_boottime_ns() >> 10);
desc->start_time = cpu_to_le32(hosttime - wl->time_offset);
is_dummy = wl12xx_is_dummy_packet(wl, skb);
if (is_dummy || !wlvif || wlvif->bss_type != BSS_TYPE_AP_BSS)
desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
else
desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
/* queue */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
desc->tid = skb->priority;
if (is_dummy) {
/*
* FW expects the dummy packet to have an invalid session id -
* any session id that is different than the one set in the join
*/
tx_attr = (SESSION_COUNTER_INVALID <<
TX_HW_ATTR_OFST_SESSION_COUNTER) &
TX_HW_ATTR_SESSION_COUNTER;
tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/etherdevice.h`, `linux/pm_runtime.h`, `linux/spinlock.h`, `wlcore.h`, `debug.h`, `io.h`.
- Detected declarations: `function Copyright`, `function wl1271_alloc_tx_id`, `function wl1271_free_tx_id`, `function wl1271_tx_ap_update_inconnection_sta`, `function wl1271_tx_regulate_link`, `function wl12xx_is_dummy_packet`, `function wl12xx_tx_get_hlid_ap`, `function wl12xx_tx_get_hlid`, `function wlcore_calc_packet_alignment`, `function wl1271_tx_allocate`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration 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.