Subject: Re: [RFC/RFT 4/4] mac80211: use multi-queue master netdevice

From: Ivo van Doorn <[email-masked]>
Date: Thu, 1 May 2008 10:21:04 +0200

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 <[email-masked]>
> ---
> 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,
> 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to [email-masked]
More majordomo info at  http://vger.kernel.org/majordomo-info.html