struct ieee80211_local *local = (struct ieee80211_local *)data;
struct ieee80211_sub_if_data *sdata;
unsigned long flags;
int i;
bool txok;
rcu_read_lock();
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
for (i = 0; i < local->hw.queues; i++) {
/*
* If queue is stopped by something other than due to pending
* frames, or we have no pending frames, proceed to next queue.
*/
if (local->queue_stop_reasons[i] ||
skb_queue_empty(&local->pending[i]))
continue;
while (!skb_queue_empty(&local->pending[i])) {
struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) {
kfree_skb(skb);
continue;
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock,
flags);
txok = ieee80211_tx_pending_skb(local, skb);
spin_lock_irqsave(&local->queue_stop_reason_lock,
flags);
if (!txok)
break;
}
if (skb_queue_empty(&local->pending[i]))
list_for_each_entry_rcu(sdata, &local->interfaces, list)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
netif_wake_subqueue(sdata->dev, i);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
netif_start_subqueue(sdata->dev, i);
#else
if (ieee80211_all_queues_started(hw))
netif_wake_queue(sdata->dev);
#endif
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
rcu_read_unlock();
这个函数比较简单,主要发送所有缓存未处理的帧,如果遇到该队列由于某种原因被停止,则停止发送。继续下一个队列。
为什么要在尾部恢复队列的发送功能,知道的求解答。