ieee80211_tx_pending分析

        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();



这个函数比较简单,主要发送所有缓存未处理的帧,如果遇到该队列由于某种原因被停止,则停止发送。继续下一个队列。

为什么要在尾部恢复队列的发送功能,知道的求解答。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值