drivers/net/wireless/silabs/wfx/queue.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/silabs/wfx/queue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/silabs/wfx/queue.c- Extension
.c- Size
- 8842 bytes
- Lines
- 323
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/sched.hnet/mac80211.hqueue.hwfx.hsta.hdata_tx.htraces.h
Detected Declarations
function Copyrightfunction wfx_tx_unlockfunction wfx_tx_flushfunction wfx_tx_lock_flushfunction wfx_tx_queues_initfunction wfx_tx_queue_emptyfunction wfx_tx_queues_check_emptyfunction __wfx_tx_queue_dropfunction wfx_tx_queue_dropfunction wfx_tx_queues_putfunction wfx_pending_dropfunction wfx_pending_dump_old_framesfunction wfx_pending_get_pkt_us_delayfunction wfx_tx_queues_has_cabfunction wfx_tx_queue_get_weight
Annotated Snippet
if (wvif) {
queue = &wvif->tx_queue[skb_get_queue_mapping(skb)];
WARN_ON(skb_get_queue_mapping(skb) > 3);
WARN_ON(!atomic_read(&queue->pending_frames));
atomic_dec(&queue->pending_frames);
}
skb_queue_head(dropped, skb);
}
}
struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id)
{
struct wfx_queue *queue;
struct wfx_hif_req_tx *req;
struct wfx_vif *wvif;
struct wfx_hif_msg *hif;
struct sk_buff *skb;
spin_lock_bh(&wdev->tx_pending.lock);
skb_queue_walk(&wdev->tx_pending, skb) {
hif = (struct wfx_hif_msg *)skb->data;
req = (struct wfx_hif_req_tx *)hif->body;
if (req->packet_id != packet_id)
continue;
spin_unlock_bh(&wdev->tx_pending.lock);
wvif = wfx_skb_wvif(wdev, skb);
if (wvif) {
queue = &wvif->tx_queue[skb_get_queue_mapping(skb)];
WARN_ON(skb_get_queue_mapping(skb) > 3);
WARN_ON(!atomic_read(&queue->pending_frames));
atomic_dec(&queue->pending_frames);
}
skb_unlink(skb, &wdev->tx_pending);
return skb;
}
spin_unlock_bh(&wdev->tx_pending.lock);
WARN(1, "cannot find packet in pending queue");
return NULL;
}
void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms)
{
ktime_t now = ktime_get();
struct wfx_tx_priv *tx_priv;
struct wfx_hif_req_tx *req;
struct sk_buff *skb;
bool first = true;
spin_lock_bh(&wdev->tx_pending.lock);
skb_queue_walk(&wdev->tx_pending, skb) {
tx_priv = wfx_skb_tx_priv(skb);
req = wfx_skb_txreq(skb);
if (ktime_after(now, ktime_add_ms(tx_priv->xmit_timestamp, limit_ms))) {
if (first) {
dev_info(wdev->dev, "frames stuck in firmware since %dms or more:\n",
limit_ms);
first = false;
}
dev_info(wdev->dev, " id %08x sent %lldms ago\n",
req->packet_id, ktime_ms_delta(now, tx_priv->xmit_timestamp));
}
}
spin_unlock_bh(&wdev->tx_pending.lock);
}
unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev, struct sk_buff *skb)
{
ktime_t now = ktime_get();
struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
return ktime_us_delta(now, tx_priv->xmit_timestamp);
}
bool wfx_tx_queues_has_cab(struct wfx_vif *wvif)
{
struct ieee80211_vif *vif = wvif_to_vif(wvif);
int i;
if (vif->type != NL80211_IFTYPE_AP)
return false;
for (i = 0; i < IEEE80211_NUM_ACS; ++i)
/* Note: since only AP can have mcast frames in queue and only one vif can be AP,
* all queued frames has same interface id
*/
if (!skb_queue_empty_lockless(&wvif->tx_queue[i].cab))
return true;
return false;
}
static int wfx_tx_queue_get_weight(struct wfx_queue *queue)
Annotation
- Immediate include surface: `linux/sched.h`, `net/mac80211.h`, `queue.h`, `wfx.h`, `sta.h`, `data_tx.h`, `traces.h`.
- Detected declarations: `function Copyright`, `function wfx_tx_unlock`, `function wfx_tx_flush`, `function wfx_tx_lock_flush`, `function wfx_tx_queues_init`, `function wfx_tx_queue_empty`, `function wfx_tx_queues_check_empty`, `function __wfx_tx_queue_drop`, `function wfx_tx_queue_drop`, `function wfx_tx_queues_put`.
- 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.