Return-path: Received: from ug-out-1314.google.com ([66.249.92.170]:6823 "EHLO ug-out-1314.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753944AbYEAIQs (ORCPT ); Thu, 1 May 2008 04:16:48 -0400 Received: by ug-out-1314.google.com with SMTP id z38so1655134ugc.16 for ; Thu, 01 May 2008 01:16:46 -0700 (PDT) To: Johannes Berg Subject: Re: [RFC/RFT 4/4] mac80211: use multi-queue master netdevice Date: Thu, 1 May 2008 10:21:04 +0200 Cc: linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Ron Rindjunsky , Tomas Winkler , Peter P Waskiewicz Jr References: <20080430124055.091382000@sipsolutions.net> <1209566743.18659.30.camel@johannes.berg> <1209567609.18659.33.camel@johannes.berg> In-Reply-To: <1209567609.18659.33.camel@johannes.berg> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-15" Message-Id: <200805011021.04435.IvDoorn@gmail.com> (sfid-20080501_101645_691879_2F0E1CF8) From: Ivo van Doorn Sender: linux-wireless-owner@vger.kernel.org List-ID: On Wednesday 30 April 2008, Johannes Berg wrote: > Turns out there was something missing (last hunk of this updated > version) from the rt2x00 part of the patch that I accidentally didn't > quilt edit, here's an updated version if anybody wants to test on rt2x00 > hw. I've tested the following patch series: mac80211: clean up get_tx_stats callback mac80211: remove queue info from ieee80211_tx_status mac80211: QoS related cleanups mac80211: use rate index in TX control GSO: generalize for mac80211 mac80211: use GSO for fragmentation mac80211: use multi-queue master netdevice My rt61 card (4 TX queues) seems to work correctly, it uses queue 3 as default queue, and a few packets seem to go over queue 1. Ivo > johannes > > Subject: mac80211: use multi-queue master netdevice > > This patch updates mac80211 and drivers to be multi-queue aware and > use that instead of the internal queue mapping. > > Signed-off-by: Johannes Berg > --- > This is just ground-work. We'll be able to play with Qos much more now. > > drivers/net/wireless/ath5k/base.c | 2 - > drivers/net/wireless/b43/dma.c | 7 ++- > drivers/net/wireless/b43/pio.c | 8 ++-- > drivers/net/wireless/b43legacy/dma.c | 2 - > drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 +- > drivers/net/wireless/iwlwifi/iwl4965-base.c | 4 +- > drivers/net/wireless/p54/p54common.c | 10 ++--- > drivers/net/wireless/rt2x00/rt2x00mac.c | 10 ++--- > drivers/net/wireless/rt2x00/rt2x00pci.c | 2 - > drivers/net/wireless/rt2x00/rt2x00queue.h | 13 ------ > drivers/net/wireless/rt2x00/rt2x00usb.c | 2 - > drivers/net/wireless/rtl8180_dev.c | 4 +- > include/net/mac80211.h | 12 ++++-- > net/mac80211/Kconfig | 14 ++++++- > net/mac80211/Makefile | 2 - > net/mac80211/ieee80211_i.h | 7 --- > net/mac80211/main.c | 21 ++++++---- > net/mac80211/tx.c | 9 ---- > net/mac80211/util.c | 54 +++++++++++++++++++--------- > net/mac80211/wme.c | 13 ++---- > net/mac80211/wme.h | 2 - > 21 files changed, 108 insertions(+), 94 deletions(-) > > --- everything.orig/drivers/net/wireless/ath5k/base.c 2008-04-30 16:55:36.000000000 +0200 > +++ everything/drivers/net/wireless/ath5k/base.c 2008-04-30 16:55:37.000000000 +0200 > @@ -2677,7 +2677,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct > if (list_empty(&sc->txbuf)) { > ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); > spin_unlock_irqrestore(&sc->txbuflock, flags); > - ieee80211_stop_queue(hw, ctl->queue); > + ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); > return -1; > } > bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); > --- everything.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-04-30 16:55:36.000000000 +0200 > +++ everything/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-04-30 16:55:37.000000000 +0200 > @@ -2562,7 +2562,7 @@ static int iwl3945_tx_skb(struct iwl3945 > struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; > struct iwl3945_tfd_frame *tfd; > u32 *control_flags; > - int txq_id = ctl->queue; > + int txq_id = skb_get_queue_mapping(skb); > struct iwl3945_tx_queue *txq = NULL; > struct iwl3945_queue *q = NULL; > dma_addr_t phys_addr; > @@ -2776,7 +2776,7 @@ static int iwl3945_tx_skb(struct iwl3945 > spin_unlock_irqrestore(&priv->lock, flags); > } > > - ieee80211_stop_queue(priv->hw, ctl->queue); > + ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb)); > } > > return 0; > --- everything.orig/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-04-30 16:55:36.000000000 +0200 > +++ everything/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-04-30 16:55:37.000000000 +0200 > @@ -2126,7 +2126,7 @@ static int iwl4965_tx_skb(struct iwl_pri > struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; > struct iwl4965_tfd_frame *tfd; > u32 *control_flags; > - int txq_id = ctl->queue; > + int txq_id = skb_get_queue_mapping(skb); > struct iwl4965_tx_queue *txq = NULL; > struct iwl4965_queue *q = NULL; > dma_addr_t phys_addr; > @@ -2350,7 +2350,7 @@ static int iwl4965_tx_skb(struct iwl_pri > spin_unlock_irqrestore(&priv->lock, flags); > } > > - ieee80211_stop_queue(priv->hw, ctl->queue); > + ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb)); > } > > return 0; > --- everything.orig/drivers/net/wireless/p54/p54common.c 2008-04-30 16:55:36.000000000 +0200 > +++ everything/drivers/net/wireless/p54/p54common.c 2008-04-30 16:55:37.000000000 +0200 > @@ -417,7 +417,7 @@ static void p54_rx_frame_sent(struct iee > memcpy(&status.control, range->control, > sizeof(status.control)); > kfree(range->control); > - priv->tx_stats[status.control.queue].len--; > + priv->tx_stats[skb_get_queue_mapping(skb)].len--; > entry_hdr = (struct p54_control_hdr *) entry->data; > entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; > if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) > @@ -562,13 +562,13 @@ static int p54_tx(struct ieee80211_hw *d > size_t padding, len; > u8 rate; > > - current_queue = &priv->tx_stats[control->queue]; > + current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)]; > if (unlikely(current_queue->len > current_queue->limit)) > return NETDEV_TX_BUSY; > current_queue->len++; > current_queue->count++; > if (current_queue->len == current_queue->limit) > - ieee80211_stop_queue(dev, control->queue); > + ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); > > padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; > len = skb->len; > @@ -605,7 +605,7 @@ static int p54_tx(struct ieee80211_hw *d > memset(txhdr->rateset, rate, 8); > txhdr->wep_key_present = 0; > txhdr->wep_key_len = 0; > - txhdr->frame_type = cpu_to_le32(control->queue + 4); > + txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4); > txhdr->magic4 = 0; > txhdr->antenna = (control->antenna_sel_tx == 0) ? > 2 : control->antenna_sel_tx - 1; > @@ -944,7 +944,7 @@ static int p54_conf_tx(struct ieee80211_ > vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *) > ((void *)priv->cached_vdcf + priv->tx_hdr_len))->data); > > - if ((params) && !((queue < 0) || (queue > 4))) { > + if (params && queue < dev->queues) { > P54_SET_QUEUE(vdcf->queue[queue], params->aifs, > params->cw_min, params->cw_max, params->txop); > } else > --- everything.orig/drivers/net/wireless/rtl8180_dev.c 2008-04-30 16:55:36.000000000 +0200 > +++ everything/drivers/net/wireless/rtl8180_dev.c 2008-04-30 16:55:37.000000000 +0200 > @@ -251,7 +251,7 @@ static int rtl8180_tx(struct ieee80211_h > u16 plcp_len = 0; > __le16 rts_duration = 0; > > - prio = control->queue; > + prio = skb_get_queue_mapping(skb); > ring = &priv->tx_ring[prio]; > > mapping = pci_map_single(priv->pdev, skb->data, > @@ -306,7 +306,7 @@ static int rtl8180_tx(struct ieee80211_h > entry->flags = cpu_to_le32(tx_flags); > __skb_queue_tail(&ring->queue, skb); > if (ring->entries - skb_queue_len(&ring->queue) < 2) > - ieee80211_stop_queue(dev, control->queue); > + ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); > spin_unlock_irqrestore(&priv->lock, flags); > > rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); > --- everything.orig/include/net/mac80211.h 2008-04-30 16:55:37.000000000 +0200 > +++ everything/include/net/mac80211.h 2008-04-30 16:55:37.000000000 +0200 > @@ -282,9 +282,6 @@ struct ieee80211_tx_control { > * This could be used when set_retry_limit > * is not implemented by the driver */ > > - u16 queue; /* hardware queue to use for this frame; > - * 0 = highest, hw->queues-1 = lowest */ > - > struct ieee80211_vif *vif; > > /* Key used for hardware encryption > @@ -1575,6 +1572,15 @@ void ieee80211_wake_queue(struct ieee802 > void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue); > > /** > + * ieee80211_start_queue - start specific queue > + * @hw: pointer as obtained from ieee80211_alloc_hw(). > + * @queue: queue number (counted from zero). > + * > + * Drivers should use this function instead of netif_start_queue. > + */ > +void ieee80211_start_queue(struct ieee80211_hw *hw, int queue); > + > +/** > * ieee80211_start_queues - start all queues > * @hw: pointer to as obtained from ieee80211_alloc_hw(). > * > --- everything.orig/net/mac80211/Kconfig 2008-04-30 16:53:47.000000000 +0200 > +++ everything/net/mac80211/Kconfig 2008-04-30 16:55:37.000000000 +0200 > @@ -7,11 +7,23 @@ config MAC80211 > select CRC32 > select WIRELESS_EXT > select CFG80211 > - select NET_SCH_FIFO > ---help--- > This option enables the hardware independent IEEE 802.11 > networking stack. > > +config MAC80211_QOS > + def_bool y > + depends on MAC80211 > + depends on NET_SCHED > + depends on NETDEVICES_MULTIQUEUE > + > +comment "QoS/HT support disabled" > + depends on !MAC80211_QOS > +comment "QoS/HT support needs CONFIG_NET_SCHED" > + depends on MAC80211 && !NET_SCHED > +comment "QoS/HT support needs CONFIG_NETDEVICES_MULTIQUEUE" > + depends on MAC80211 && !NETDEVICES_MULTIQUEUE > + > menu "Rate control algorithm selection" > depends on MAC80211 != n > > --- everything.orig/net/mac80211/Makefile 2008-04-30 16:55:30.000000000 +0200 > +++ everything/net/mac80211/Makefile 2008-04-30 16:55:37.000000000 +0200 > @@ -29,7 +29,7 @@ mac80211-y := \ > event.o > > mac80211-$(CONFIG_MAC80211_LEDS) += led.o > -mac80211-$(CONFIG_NET_SCHED) += wme.o > +mac80211-$(CONFIG_MAC80211_QOS) += wme.o > mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ > debugfs.o \ > debugfs_sta.o \ > --- everything.orig/net/mac80211/ieee80211_i.h 2008-04-30 16:55:37.000000000 +0200 > +++ everything/net/mac80211/ieee80211_i.h 2008-04-30 16:55:37.000000000 +0200 > @@ -213,7 +213,6 @@ struct ieee80211_rx_data { > struct ieee80211_tx_packet_data { > u32 flags; > int ifindex; > - u16 queue; > unsigned long jiffies; > }; > > @@ -605,8 +604,6 @@ struct ieee80211_local { > struct sta_info *sta_hash[STA_HASH_SIZE]; > struct timer_list sta_cleanup; > > - unsigned long state[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; > - > /* number of interfaces with corresponding IFF_ flags */ > atomic_t iff_allmultis, iff_promiscs; > > @@ -836,10 +833,6 @@ static inline struct ieee80211_hw *local > return &local->hw; > } > > -enum ieee80211_link_state_t { > - IEEE80211_LINK_STATE_XOFF = 0, > -}; > - > struct sta_attribute { > struct attribute attr; > ssize_t (*show)(const struct sta_info *, char *buf); > --- everything.orig/net/mac80211/main.c 2008-04-30 16:55:37.000000000 +0200 > +++ everything/net/mac80211/main.c 2008-04-30 16:55:37.000000000 +0200 > @@ -1313,7 +1313,6 @@ static void ieee80211_remove_tx_extra(st > pkt_data->flags |= IEEE80211_TXPD_REQUEUE; > if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) > pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; > - pkt_data->queue = control->queue; > > hdrlen = ieee80211_get_hdrlen_from_skb(skb); > > @@ -1713,9 +1712,20 @@ int ieee80211_register_hw(struct ieee802 > if (result < 0) > return result; > > +#ifdef CONFIG_MAC80211_QOS > + if (hw->queues > IEEE80211_MAX_QUEUES) > + hw->queues = IEEE80211_MAX_QUEUES; > + if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) > + hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; > +#else > + hw->queues = 1; > + hw->ampdu_queues = 0; > +#endif > + > /* for now, mdev needs sub_if_data :/ */ > - mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), > - "wmaster%d", ether_setup); > + mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data), > + "wmaster%d", ether_setup, > + hw->queues + hw->ampdu_queues); > if (!mdev) > goto fail_mdev_alloc; > > @@ -1807,11 +1817,6 @@ int ieee80211_register_hw(struct ieee802 > goto fail_wep; > } > > - if (hw->queues > IEEE80211_MAX_QUEUES) > - hw->queues = IEEE80211_MAX_QUEUES; > - if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) > - hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; > - > ieee80211_install_qdisc(local->mdev); > > /* add one default STA interface */ > --- everything.orig/net/mac80211/tx.c 2008-04-30 16:55:37.000000000 +0200 > +++ everything/net/mac80211/tx.c 2008-04-30 16:55:37.000000000 +0200 > @@ -210,12 +210,6 @@ static u16 ieee80211_duration(struct iee > return dur; > } > > -static inline int __ieee80211_queue_stopped(const struct ieee80211_local *local, > - int queue) > -{ > - return test_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); > -} > - > static int inline is_ieee80211_device(struct net_device *dev, > struct net_device *master) > { > @@ -1066,7 +1060,7 @@ static int ___ieee80211_tx(struct ieee80 > print_control(control, skb); > > if (unlikely(netif_queue_stopped(local->mdev) || > - __ieee80211_queue_stopped(local, control->queue))) > + netif_subqueue_stopped(local->mdev, skb))) > return NETDEV_TX_BUSY; > > ieee80211_dump_frame(wiphy_name(local->hw.wiphy), > @@ -1354,7 +1348,6 @@ int ieee80211_master_start_xmit(struct s > control.flags |= IEEE80211_TXCTL_EAPOL_FRAME; > if (pkt_data->flags & IEEE80211_TXPD_AMPDU) > control.flags |= IEEE80211_TXCTL_AMPDU; > - control.queue = pkt_data->queue; > > memset(skb->cb, 0, sizeof(skb->cb)); > ret = ieee80211_tx(odev, skb, &control); > --- everything.orig/net/mac80211/util.c 2008-04-30 16:55:37.000000000 +0200 > +++ everything/net/mac80211/util.c 2008-04-30 16:55:37.000000000 +0200 > @@ -323,18 +323,28 @@ __le16 ieee80211_ctstoself_duration(stru > } > EXPORT_SYMBOL(ieee80211_ctstoself_duration); > > +void ieee80211_start_queue(struct ieee80211_hw *hw, int queue) > +{ > + struct ieee80211_local *local = hw_to_local(hw); > +#ifdef CONFIG_MAC80211_QOS > + netif_start_subqueue(local->mdev, queue); > +#else > + WARN_ON(queue != 0); > + netif_start_queue(local->mdev); > +#endif > +} > +EXPORT_SYMBOL(ieee80211_start_queue); > + > void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) > { > struct ieee80211_local *local = hw_to_local(hw); > > - if (test_and_clear_bit(IEEE80211_LINK_STATE_XOFF, > - &local->state[queue])) { > - if (!ieee80211_qdisc_installed(local->mdev)) { > - if (queue == 0) > - netif_wake_queue(local->mdev); > - } else > - __netif_schedule(local->mdev); > - } > +#ifdef CONFIG_MAC80211_QOS > + netif_wake_subqueue(local->mdev, queue); > +#else > + WARN_ON(queue != 0); > + netif_wake_queue(local->mdev); > +#endif > } > EXPORT_SYMBOL(ieee80211_wake_queue); > > @@ -342,39 +352,51 @@ void ieee80211_stop_queue(struct ieee802 > { > struct ieee80211_local *local = hw_to_local(hw); > > - if (!ieee80211_qdisc_installed(local->mdev) && queue == 0) > - netif_stop_queue(local->mdev); > - set_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); > +#ifdef CONFIG_MAC80211_QOS > + netif_stop_subqueue(local->mdev, queue); > +#else > + WARN_ON(queue != 0); > + netif_stop_queue(local->mdev); > +#endif > } > EXPORT_SYMBOL(ieee80211_stop_queue); > > void ieee80211_start_queues(struct ieee80211_hw *hw) > { > - struct ieee80211_local *local = hw_to_local(hw); > +#ifdef CONFIG_MAC80211_QOS > int i; > > - for (i = 0; i < local->hw.queues; i++) > - clear_bit(IEEE80211_LINK_STATE_XOFF, &local->state[i]); > - if (!ieee80211_qdisc_installed(local->mdev)) > - netif_start_queue(local->mdev); > + for (i = 0; i < hw->queues; i++) > + ieee80211_start_queue(hw, i); > +#else > + netif_start_queue(local->mdev); > +#endif > } > EXPORT_SYMBOL(ieee80211_start_queues); > > void ieee80211_stop_queues(struct ieee80211_hw *hw) > { > +#ifdef CONFIG_MAC80211_QOS > int i; > > for (i = 0; i < hw->queues; i++) > ieee80211_stop_queue(hw, i); > +#else > + netif_stop_queue(local->mdev); > +#endif > } > EXPORT_SYMBOL(ieee80211_stop_queues); > > void ieee80211_wake_queues(struct ieee80211_hw *hw) > { > +#ifdef CONFIG_MAC80211_QOS > int i; > > for (i = 0; i < hw->queues; i++) > ieee80211_wake_queue(hw, i); > +#else > + netif_wake_queue(local->mdev); > +#endif > } > EXPORT_SYMBOL(ieee80211_wake_queues); > > --- everything.orig/net/mac80211/wme.c 2008-04-30 16:55:37.000000000 +0200 > +++ everything/net/mac80211/wme.c 2008-04-30 16:55:37.000000000 +0200 > @@ -160,7 +160,7 @@ static int wme_qdiscop_enqueue(struct sk > u8 tid; > > if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { > - queue = pkt_data->queue; > + queue = skb_get_queue_mapping(skb); > rcu_read_lock(); > sta = sta_info_get(local, hdr->addr1); > tid = skb->priority & QOS_CONTROL_TAG1D_MASK; > @@ -221,7 +221,7 @@ static int wme_qdiscop_enqueue(struct sk > err = NET_XMIT_DROP; > } else { > tid = skb->priority & QOS_CONTROL_TAG1D_MASK; > - pkt_data->queue = (unsigned int) queue; > + skb_set_queue_mapping(skb, queue); > qdisc = q->queues[queue]; > err = qdisc->enqueue(skb, qdisc); > if (err == NET_XMIT_SUCCESS) { > @@ -239,13 +239,10 @@ static int wme_qdiscop_enqueue(struct sk > static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) > { > struct ieee80211_sched_data *q = qdisc_priv(qd); > - struct ieee80211_tx_packet_data *pkt_data = > - (struct ieee80211_tx_packet_data *) skb->cb; > struct Qdisc *qdisc; > int err; > > - /* We recorded which queue to use earlier. */ > - qdisc = q->queues[pkt_data->queue]; > + qdisc = q->queues[skb_get_queue_mapping(skb)]; > > if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { > qd->q.qlen++; > @@ -269,9 +266,7 @@ static struct sk_buff *wme_qdiscop_deque > /* check all the h/w queues in numeric/priority order */ > for (queue = 0; queue < QD_NUM(hw); queue++) { > /* see if there is room in this hardware queue */ > - if ((test_bit(IEEE80211_LINK_STATE_XOFF, > - &local->state[queue])) || > - (!test_bit(queue, q->qdisc_pool))) > + if (__netif_subqueue_stopped(local->mdev, queue)) > continue; > > /* there is space - try and get a frame */ > --- everything.orig/net/mac80211/wme.h 2008-04-30 16:53:47.000000000 +0200 > +++ everything/net/mac80211/wme.h 2008-04-30 16:55:37.000000000 +0200 > @@ -31,7 +31,7 @@ static inline int WLAN_FC_IS_QOS_DATA(u1 > return (fc & 0x8C) == 0x88; > } > > -#ifdef CONFIG_NET_SCHED > +#ifdef CONFIG_MAC80211_QOS > void ieee80211_install_qdisc(struct net_device *dev); > int ieee80211_qdisc_installed(struct net_device *dev); > int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, > --- everything.orig/drivers/net/wireless/b43/dma.c 2008-04-30 16:55:34.000000000 +0200 > +++ everything/drivers/net/wireless/b43/dma.c 2008-04-30 16:55:37.000000000 +0200 > @@ -1298,7 +1298,8 @@ int b43_dma_tx(struct b43_wldev *dev, > hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); > } else { > /* Decide by priority where to put this frame. */ > - ring = select_ring_by_priority(dev, ctl->queue); > + ring = select_ring_by_priority( > + dev, skb_get_queue_mapping(skb)); > } > > spin_lock_irqsave(&ring->lock, flags); > @@ -1316,7 +1317,7 @@ int b43_dma_tx(struct b43_wldev *dev, > /* Assign the queue number to the ring (if not already done before) > * so TX status handling can use it. The queue to ring mapping is > * static, so we don't need to store it per frame. */ > - ring->queue_prio = ctl->queue; > + ring->queue_prio = skb_get_queue_mapping(skb); > > err = dma_tx_fragment(ring, skb, ctl); > if (unlikely(err == -ENOKEY)) { > @@ -1334,7 +1335,7 @@ int b43_dma_tx(struct b43_wldev *dev, > if ((free_slots(ring) < SLOTS_PER_PACKET) || > should_inject_overflow(ring)) { > /* This TX ring is full. */ > - ieee80211_stop_queue(dev->wl->hw, ctl->queue); > + ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); > ring->stopped = 1; > if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { > b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); > --- everything.orig/drivers/net/wireless/b43/pio.c 2008-04-30 16:55:34.000000000 +0200 > +++ everything/drivers/net/wireless/b43/pio.c 2008-04-30 16:55:37.000000000 +0200 > @@ -510,7 +510,7 @@ int b43_pio_tx(struct b43_wldev *dev, > hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); > } else { > /* Decide by priority where to put this frame. */ > - q = select_queue_by_priority(dev, ctl->queue); > + q = select_queue_by_priority(dev, skb_get_queue_mapping(skb)); > } > > spin_lock_irqsave(&q->lock, flags); > @@ -533,7 +533,7 @@ int b43_pio_tx(struct b43_wldev *dev, > if (total_len > (q->buffer_size - q->buffer_used)) { > /* Not enough memory on the queue. */ > err = -EBUSY; > - ieee80211_stop_queue(dev->wl->hw, ctl->queue); > + ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); > q->stopped = 1; > goto out_unlock; > } > @@ -541,7 +541,7 @@ int b43_pio_tx(struct b43_wldev *dev, > /* Assign the queue number to the ring (if not already done before) > * so TX status handling can use it. The mac80211-queue to b43-queue > * mapping is static, so we don't need to store it per frame. */ > - q->queue_prio = ctl->queue; > + q->queue_prio = skb_get_queue_mapping(skb); > > err = pio_tx_frame(q, skb, ctl); > if (unlikely(err == -ENOKEY)) { > @@ -561,7 +561,7 @@ int b43_pio_tx(struct b43_wldev *dev, > if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || > (q->free_packet_slots == 0)) { > /* The queue is full. */ > - ieee80211_stop_queue(dev->wl->hw, ctl->queue); > + ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); > q->stopped = 1; > } > > --- everything.orig/drivers/net/wireless/b43legacy/dma.c 2008-04-30 16:55:34.000000000 +0200 > +++ everything/drivers/net/wireless/b43legacy/dma.c 2008-04-30 16:55:37.000000000 +0200 > @@ -1330,7 +1330,7 @@ int b43legacy_dma_tx(struct b43legacy_wl > int err = 0; > unsigned long flags; > > - ring = priority_to_txring(dev, ctl->queue); > + ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); > spin_lock_irqsave(&ring->lock, flags); > B43legacy_WARN_ON(!ring->tx); > if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) { > --- everything.orig/drivers/net/wireless/rt2x00/rt2x00mac.c 2008-04-30 16:55:35.000000000 +0200 > +++ everything/drivers/net/wireless/rt2x00/rt2x00mac.c 2008-04-30 16:55:37.000000000 +0200 > @@ -81,7 +81,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw > { > struct rt2x00_dev *rt2x00dev = hw->priv; > struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; > - enum data_queue_qid qid = mac80211_queue_to_qid(control->queue); > + enum data_queue_qid qid = skb_get_queue_mapping(skb); > struct data_queue *queue; > struct skb_frame_desc *skbdesc; > u16 frame_control; > @@ -129,12 +129,12 @@ int rt2x00mac_tx(struct ieee80211_hw *hw > IEEE80211_TXCTL_USE_CTS_PROTECT)) && > !rt2x00dev->ops->hw->set_rts_threshold) { > if (rt2x00queue_available(queue) <= 1) { > - ieee80211_stop_queue(rt2x00dev->hw, control->queue); > + ieee80211_stop_queue(rt2x00dev->hw, qid); > return NETDEV_TX_BUSY; > } > > if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) { > - ieee80211_stop_queue(rt2x00dev->hw, control->queue); > + ieee80211_stop_queue(rt2x00dev->hw, qid); > return NETDEV_TX_BUSY; > } > } > @@ -146,12 +146,12 @@ int rt2x00mac_tx(struct ieee80211_hw *hw > memset(skbdesc, 0, sizeof(*skbdesc)); > > if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { > - ieee80211_stop_queue(rt2x00dev->hw, control->queue); > + ieee80211_stop_queue(rt2x00dev->hw, qid); > return NETDEV_TX_BUSY; > } > > if (rt2x00queue_full(queue)) > - ieee80211_stop_queue(rt2x00dev->hw, control->queue); > + ieee80211_stop_queue(rt2x00dev->hw, qid); > > if (rt2x00dev->ops->lib->kick_tx_queue) > rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); > --- everything.orig/drivers/net/wireless/rt2x00/rt2x00pci.c 2008-04-30 16:55:33.000000000 +0200 > +++ everything/drivers/net/wireless/rt2x00/rt2x00pci.c 2008-04-30 16:55:37.000000000 +0200 > @@ -178,7 +178,7 @@ void rt2x00pci_txdone(struct rt2x00_dev > * is reenabled when the txdone handler has finished. > */ > if (!rt2x00queue_full(entry->queue)) > - ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); > + ieee80211_wake_queue(rt2x00dev->hw, entry->queue->qid); > > } > EXPORT_SYMBOL_GPL(rt2x00pci_txdone); > --- everything.orig/drivers/net/wireless/rt2x00/rt2x00queue.h 2008-04-30 16:55:35.000000000 +0200 > +++ everything/drivers/net/wireless/rt2x00/rt2x00queue.h 2008-04-30 16:55:37.000000000 +0200 > @@ -80,19 +80,6 @@ enum data_queue_qid { > }; > > /** > - * mac80211_queue_to_qid - Convert mac80211 queue to rt2x00 qid > - * @queue: mac80211 queue. > - */ > -static inline enum data_queue_qid mac80211_queue_to_qid(unsigned int queue) > -{ > - /* Regular TX queues are mapped directly */ > - if (queue < 4) > - return queue; > - WARN_ON(1); > - return QID_OTHER; > -} > - > -/** > * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc > * > * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver > --- everything.orig/drivers/net/wireless/rt2x00/rt2x00usb.c 2008-04-30 16:56:02.000000000 +0200 > +++ everything/drivers/net/wireless/rt2x00/rt2x00usb.c 2008-04-30 16:56:16.000000000 +0200 > @@ -166,7 +166,7 @@ static void rt2x00usb_interrupt_txdone(s > * is reenabled when the txdone handler has finished. > */ > if (!rt2x00queue_full(entry->queue)) > - ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); > + ieee80211_wake_queue(rt2x00dev->hw, entry->queue->qid); > } > > int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, > > >