Return-path: Received: from xc.sipsolutions.net ([83.246.72.84]:52834 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756076AbYD3OHe (ORCPT ); Wed, 30 Apr 2008 10:07:34 -0400 Message-Id: <20080430130051.397094000@sipsolutions.net> (sfid-20080430_160732_760587_3A31AB06) References: <20080430124055.091382000@sipsolutions.net> Date: Wed, 30 Apr 2008 14:40:59 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org, Ron Rindjunsky , Tomas Winkler , Ivo van Doorn , Peter P Waskiewicz Jr Subject: [RFC/RFT 4/4] mac80211: use multi-queue master netdevice Mime-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org List-ID: 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 | 12 +++--- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 - drivers/net/wireless/rt2x00/rt2x00queue.h | 13 ------ 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 - 20 files changed, 109 insertions(+), 93 deletions(-) --- everything.orig/drivers/net/wireless/ath5k/base.c 2008-04-30 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/ath5k/base.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/p54/p54common.c 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/drivers/net/wireless/rtl8180_dev.c 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/include/net/mac80211.h 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/Kconfig 2008-04-30 14:25:39.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/Makefile 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/ieee80211_i.h 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/main.c 2008-04-30 14:18:53.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/tx.c 2008-04-30 14:02:34.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/util.c 2008-04-30 14:20:06.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/wme.c 2008-04-30 14:35:44.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 14:02:31.000000000 +0200 +++ everything/net/mac80211/wme.h 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/b43/dma.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/b43/pio.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/b43legacy/dma.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/rt2x00/rt2x00mac.c 2008-04-30 14:02:34.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,14 @@ 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, skb_get_queue_mapping(skb)); 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, skb_get_queue_mapping(skb)); return NETDEV_TX_BUSY; } } @@ -146,12 +148,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, skb_get_queue_mapping(skb)); return NETDEV_TX_BUSY; } if (rt2x00queue_full(queue)) - ieee80211_stop_queue(rt2x00dev->hw, control->queue); + ieee80211_stop_queue(rt2x00dev->hw, skb_get_queue_mapping(skb)); 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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/rt2x00/rt2x00pci.c 2008-04-30 14:02:34.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 14:02:32.000000000 +0200 +++ everything/drivers/net/wireless/rt2x00/rt2x00queue.h 2008-04-30 14:02:34.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 --