mac80211: use multiqueue netdev
Subsystems (2)
Johannes Berg
maintainercover mac80211: use multiqueue netdev
This patch (well, there are two, but the first one is just some sanity checking) converts mac80211 to use a multiqueue netdev.
The next step will be to re-do fragmentation taking into account proper A-MPDU handling etc. but I would love to have Ron look over that too since he's much more familiar with the A-MPDU stuff.
johannes
Johannes Berg
maintainerPATCH 1/2 mac80211: dont allow fragmentation and requeuing on A-MPDU queues
There really is no reason for a driver to reject a frame on an A-MPDU queue when it can stop that queue for any period of time and is given frames one by one. Hence, disallow it with a big warning and reduce mac80211-internal state.
Also add a warning when we try to fragment a frame destined for an A-MPDU queue and drop it, the actual bug needs to be fixed elsewhere but I'm not exactly sure how to yet.
--- include/net/mac80211.h | 6 ++++-- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/tx.c | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-)
net/mac80211/ieee80211_i.h +1 -1
@@ -596,7 +596,7 @@ struct ieee80211_local {struct timer_list sta_cleanup;unsigned long state[IEEE80211_MAX_QUEUES +IEEE80211_MAX_AMPDU_QUEUES ]; -struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES +IEEE80211_MAX_AMPDU_QUEUES ]; +struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES ];struct tasklet_struct tx_pending_tasklet;/* number of interfaces with corresponding IFF_ flags */
net/mac80211/tx.c +21 -2
@@ -673,6 +673,16 @@ ieee80211_tx_h_fragment(struct ieee80211if (!(tx->flags &IEEE80211_TX_FRAGMENTED ))return TX_CONTINUE ; +/* +* Warn when submitting a fragmented A-MPDU frame and drop it. +* This is an error and needs to be fixed elsewhere, but when +* done needs to take care of monitor interfaces (injection) +* etc. +*/ +if (WARN_ON (tx->flags &IEEE80211_TX_CTL_AMPDU || +IEEE80211_SKB_CB (tx->skb)->queue >= tx->local->hw.queues)) +return TX_DROP ; + first = tx->skb; hdrlen =ieee80211_get_hdrlen (tx->fc);
@@ -1216,8 +1226,17 @@ static int ieee80211_tx(struct net_devic retry: ret =__ieee80211_tx (local, skb, &tx);if (ret) { -struct ieee80211_tx_stored_packet *store = - &local->pending_packet[info->queue]; +struct ieee80211_tx_stored_packet *store; + +/* +* Since there are no fragmented frames on A-MPDU +* queues, there's no reason for a driver to reject +* a frame there, warn and drop it. +*/ +if (WARN_ON (queue >= local->hw.queues)) + goto drop; + + store = &local->pending_packet[queue];if (ret ==IEEE80211_TX_FRAG_AGAIN ) skb =NULL ;
include/net/mac80211.h +4 -2
@@ -986,8 +986,10 @@ enum ieee80211_ampdu_mlme_action {* @tx: Handler that 802.11 module calls for each transmitted frame. * skb contains the buffer starting from the IEEE 802.11 header. * The low-level driver should send the frame out based on -* configuration in the TX control data. Must be implemented and -* atomic. +* configuration in the TX control data. This handler should, +* preferably, never fail and stop queues appropriately, more +* importantly, however, it must never fail for A-MPDU-queues. +* Must be implemented and atomic. * * @start: Called before the first netdevice attached to the hardware * is enabled. This should turn on the hardware and must turn on
Johannes Berg
maintainerPATCH 2/2 mac80211: use multi-queue master netdevice
In reply to Johannes BergThis patch updates mac80211 and drivers to be multi-queue aware and use that instead of the internal queue mapping. Also does a number of cleanups in various pieces of the code that fall out and reduces internal mac80211 state size.
---
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 | 3 drivers/net/wireless/iwlwifi/iwl-tx.c | 4 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 - drivers/net/wireless/p54/p54common.c | 8 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 10 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 13 --- drivers/net/wireless/rtl8180_dev.c | 4 - include/net/mac80211.h | 20 +++++ net/mac80211/Kconfig | 14 +++- net/mac80211/Makefile | 2 net/mac80211/ieee80211_i.h | 16 ++-- net/mac80211/iface.c | 2 net/mac80211/main.c | 29 ++++++-- net/mac80211/sta_info.c | 2 net/mac80211/tx.c | 97 ++++++++++++---------------- net/mac80211/util.c | 29 ++++---- net/mac80211/wme.c | 14 +--- net/mac80211/wme.h | 2 21 files changed, 158 insertions(+), 132 deletions(-)
drivers/net/wireless/ath5k/base.c +1 -1
@@ -2657,7 +2657,7 @@ ath5k_tx(struct ieee80211_hw *hw, structif (list_empty (&sc->txbuf)) {ATH5K_ERR (sc,"no further txbuf available, dropping packet\n" );spin_unlock_irqrestore (&sc->txbuflock, flags); -ieee80211_stop_queue (hw, info->queue); +ieee80211_stop_queue (hw,skb_get_queue_mapping (skb));return -1 ; } bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
drivers/net/wireless/iwlwifi/iwl3945-base.c +2 -2
@@ -2552,7 +2552,7 @@ static int iwl3945_tx_skb(struct iwl3945struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct iwl3945_tfd_frame *tfd;u32 *control_flags; -int txq_id = info->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;
@@ -2765,7 +2765,7 @@ static int iwl3945_tx_skb(struct iwl3945spin_unlock_irqrestore (&priv->lock, flags); } -ieee80211_stop_queue (priv->hw, info->queue); +ieee80211_stop_queue (priv->hw,skb_get_queue_mapping (skb)); }return 0 ;
drivers/net/wireless/p54/p54common.c +4 -4
@@ -407,7 +407,7 @@ static void p54_rx_frame_sent(struct iee last_addr = range->end_addr;__skb_unlink (entry, &priv->tx_queue);memset (&info->status,0 ,sizeof (info->status)); - priv->tx_stats[info->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 )
@@ -551,13 +551,13 @@ static int p54_tx(struct ieee80211_hw *dsize_t padding, len;u8 rate; - current_queue = &priv->tx_stats[info->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, info->queue); +ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); padding = (unsigned long )(skb->data - (sizeof (*hdr) +sizeof (*txhdr))) &3 ; len = skb->len;
@@ -589,7 +589,7 @@ static int p54_tx(struct ieee80211_hw *dmemset (txhdr->rateset, rate,8 ); txhdr->wep_key_present =0 ; txhdr->wep_key_len =0 ; - txhdr->frame_type =cpu_to_le32 (info->queue +4 ); + txhdr->frame_type =cpu_to_le32 (skb_get_queue_mapping (skb) +4 ); txhdr->magic4 =0 ; txhdr->antenna = (info->antenna_sel_tx ==0 ) ?2 : info->antenna_sel_tx -1 ;
drivers/net/wireless/rtl8180_dev.c +2 -2
@@ -246,7 +246,7 @@ static int rtl8180_tx(struct ieee80211_hu16 plcp_len =0 ;__le16 rts_duration =0 ; - prio = info->queue; + prio =skb_get_queue_mapping (skb); ring = &priv->tx_ring[prio]; mapping = pci_map_single(priv->pdev, skb->data,
@@ -298,7 +298,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, info->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 )));
net/mac80211/Kconfig +13 -1
@@ -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 && !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
net/mac80211/Makefile +1 -1
@@ -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 \
net/mac80211/main.c +22 -7
@@ -1694,12 +1694,32 @@ int ieee80211_register_hw(struct ieee802if (result <0 )return result; +/* +* We use the number of queues for feature tests (QoS, HT) internally +* so restrict them appropriately. +*/ +#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 ; +if (hw->queues <4 ) + hw->ampdu_queues =0 ; +#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, +ieee80211_num_queues (hw));if (!mdev) goto fail_mdev_alloc; +if (ieee80211_num_queues (hw) >1 ) + mdev->features |=NETIF_F_MULTI_QUEUE ; + sdata =IEEE80211_DEV_TO_SUB_IF (mdev); mdev->ieee80211_ptr = &sdata->wdev; sdata->wdev.wiphy = local->hw.wiphy;
@@ -1788,11 +1808,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 */
net/mac80211/tx.c +45 -52
192 lines not on this page · raw message
net/mac80211/util.c +15 -14
@@ -331,17 +331,15 @@ void ieee80211_wake_queue(struct ieee802 {struct ieee80211_local *local =hw_to_local (hw); -if (test_and_clear_bit (IEEE80211_LINK_STATE_XOFF , - &local->state[queue])) { -if (test_bit (IEEE80211_LINK_STATE_PENDING , - &local->state[queue])) -tasklet_schedule (&local->tx_pending_tasklet); -else -if (!ieee80211_qdisc_installed (local->mdev)) { -if (queue ==0 ) -netif_wake_queue (local->mdev); - }else -__netif_schedule (local->mdev); +if (test_bit (queue, local->queues_pending)) { +tasklet_schedule (&local->tx_pending_tasklet); + }else { +if (ieee80211_is_multiqueue (local)) { +netif_wake_subqueue (local->mdev, queue); + }else { +WARN_ON (queue !=0 ); +netif_wake_queue (local->mdev); + } } }EXPORT_SYMBOL (ieee80211_wake_queue);
@@ -350,9 +348,12 @@ void ieee80211_stop_queue(struct ieee802 {struct ieee80211_local *local =hw_to_local (hw); -if (!ieee80211_qdisc_installed (local->mdev) && queue ==0 ) +if (ieee80211_is_multiqueue (local)) { +netif_stop_subqueue (local->mdev, queue); + }else { +WARN_ON (queue !=0 );netif_stop_queue (local->mdev); -set_bit (IEEE80211_LINK_STATE_XOFF , &local->state[queue]); + } }EXPORT_SYMBOL (ieee80211_stop_queue);
@@ -360,7 +361,7 @@ void ieee80211_stop_queues(struct ieee80 {int i; -for (i =0 ; i < hw->queues + hw->ampdu_queues; i++) +for (i =0 ; i <ieee80211_num_queues (hw); i++)ieee80211_stop_queue (hw, i); }EXPORT_SYMBOL (ieee80211_stop_queues);
net/mac80211/wme.c +5 -9
@@ -158,7 +158,7 @@ static int wme_qdiscop_enqueue(struct sku8 tid;if (info->flags &IEEE80211_TX_CTL_REQUEUE ) { - queue = info->queue; + queue =skb_get_queue_mapping (skb);rcu_read_lock (); sta =sta_info_get (local, hdr->addr1); tid = skb->priority &QOS_CONTROL_TAG1D_MASK ;
@@ -219,7 +219,7 @@ static int wme_qdiscop_enqueue(struct sk err =NET_XMIT_DROP ; }else { tid = skb->priority &QOS_CONTROL_TAG1D_MASK ; - info->queue = (unsigned int ) queue; +skb_set_queue_mapping (skb, queue); qdisc = q->queues[queue]; err = qdisc->enqueue (skb, qdisc);if (err ==NET_XMIT_SUCCESS ) {
@@ -240,12 +240,11 @@ static int wme_qdiscop_enqueue(struct skstatic int wme_qdiscop_requeue (struct sk_buff *skb,struct Qdisc * qd) {struct ieee80211_sched_data *q =qdisc_priv (qd); -struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct Qdisc *qdisc;int err;/* we recorded which queue to use earlier! */ - qdisc = q->queues[info->queue]; + qdisc = q->queues[skb_get_queue_mapping (skb)];if ((err = qdisc->ops->requeue (skb, qdisc)) ==0 ) { qd->q.qlen++;
@@ -269,11 +268,8 @@ 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 (IEEE80211_LINK_STATE_PENDING , - &local->state[queue])) || - (!test_bit (queue, q->qdisc_pool))) +if (__netif_subqueue_stopped (local->mdev, queue) || + !test_bit (queue, q->qdisc_pool))continue ;/* there is space - try and get a frame */
net/mac80211/wme.h +1 -1
@@ -31,7 +31,7 @@ static inline int WLAN_FC_IS_QOS_DATA(u1return (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,
drivers/net/wireless/b43/dma.c +4 -3
@@ -1297,7 +1297,8 @@ int b43_dma_tx(struct b43_wldev *dev, st hdr->frame_control |=cpu_to_le16 (IEEE80211_FCTL_MOREDATA ); }else {/* Decide by priority where to put this frame. */ - ring =select_ring_by_priority (dev, info->queue); + ring =select_ring_by_priority ( + dev,skb_get_queue_mapping (skb)); }spin_lock_irqsave (&ring->lock, flags);
@@ -1315,7 +1316,7 @@ int b43_dma_tx(struct b43_wldev *dev, st/* 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 = info->queue; + ring->queue_prio =skb_get_queue_mapping (skb); err =dma_tx_fragment (ring, skb);if (unlikely (err == -ENOKEY )) {
@@ -1333,7 +1334,7 @@ int b43_dma_tx(struct b43_wldev *dev, stif ((free_slots (ring) <SLOTS_PER_PACKET ) ||should_inject_overflow (ring)) {/* This TX ring is full. */ -ieee80211_stop_queue (dev->wl->hw, info->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);
drivers/net/wireless/b43/pio.c +4 -4
@@ -509,7 +509,7 @@ int b43_pio_tx(struct b43_wldev *dev, st hdr->frame_control |=cpu_to_le16 (IEEE80211_FCTL_MOREDATA ); }else {/* Decide by priority where to put this frame. */ - q =select_queue_by_priority (dev, info->queue); + q =select_queue_by_priority (dev,skb_get_queue_mapping (skb)); }spin_lock_irqsave (&q->lock, flags);
@@ -532,7 +532,7 @@ int b43_pio_tx(struct b43_wldev *dev, stif (total_len > (q->buffer_size - q->buffer_used)) {/* Not enough memory on the queue. */ err = -EBUSY ; -ieee80211_stop_queue (dev->wl->hw, info->queue); +ieee80211_stop_queue (dev->wl->hw,skb_get_queue_mapping (skb)); q->stopped =1 ; goto out_unlock; }
@@ -540,7 +540,7 @@ int b43_pio_tx(struct b43_wldev *dev, st/* 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 = info->queue; + q->queue_prio =skb_get_queue_mapping (skb); err =pio_tx_frame (q, skb);if (unlikely (err == -ENOKEY )) {
@@ -560,7 +560,7 @@ int b43_pio_tx(struct b43_wldev *dev, stif (((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, info->queue); +ieee80211_stop_queue (dev->wl->hw,skb_get_queue_mapping (skb)); q->stopped =1 ; }
drivers/net/wireless/b43legacy/dma.c +1 -2
@@ -1325,11 +1325,10 @@ int b43legacy_dma_tx(struct b43legacy_wl struct sk_buff *skb) {struct b43legacy_dmaring *ring; -struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);int err =0 ;unsigned long flags; - ring =priority_to_txring (dev, info->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 )) {
drivers/net/wireless/rt2x00/rt2x00mac.c +5 -5
@@ -102,7 +102,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hwstruct rt2x00_dev *rt2x00dev = hw->priv;struct ieee80211_tx_info *tx_info =IEEE80211_SKB_CB (skb);struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; -enum data_queue_qid qid =mac80211_queue_to_qid (tx_info->queue); +enum data_queue_qid qid =skb_get_queue_mapping (skb);struct data_queue *queue;u16 frame_control;
@@ -149,23 +149,23 @@ int rt2x00mac_tx(struct ieee80211_hw *hw IEEE80211_TX_CTL_USE_CTS_PROTECT)) && !rt2x00dev->ops->hw->set_rts_threshold) {if (rt2x00queue_available (queue) <=1 ) { -ieee80211_stop_queue (rt2x00dev->hw, tx_info->queue); +ieee80211_stop_queue (rt2x00dev->hw, qid);return NETDEV_TX_BUSY ; }if (rt2x00mac_tx_rts_cts (rt2x00dev, queue, skb)) { -ieee80211_stop_queue (rt2x00dev->hw, tx_info->queue); +ieee80211_stop_queue (rt2x00dev->hw, qid);return NETDEV_TX_BUSY ; } }if (rt2x00dev->ops->lib->write_tx_data (rt2x00dev, queue, skb)) { -ieee80211_stop_queue (rt2x00dev->hw, tx_info->queue); +ieee80211_stop_queue (rt2x00dev->hw, qid);return NETDEV_TX_BUSY ; }if (rt2x00queue_full (queue)) -ieee80211_stop_queue (rt2x00dev->hw, tx_info->queue); +ieee80211_stop_queue (rt2x00dev->hw, qid);if (rt2x00dev->ops->lib->kick_tx_queue) rt2x00dev->ops->lib->kick_tx_queue (rt2x00dev, qid);
drivers/net/wireless/rt2x00/rt2x00queue.h +0 -13
@@ -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
include/net/mac80211.h +19 -1
@@ -293,7 +293,7 @@ struct ieee80211_tx_info {s8 tx_rate_idx;u8 antenna_sel_tx; -u8 queue;/* use skb_queue_mapping soon */ +/* 1 byte hole */ union { struct {
@@ -802,6 +802,24 @@ static inline void SET_IEEE80211_PERM_ADmemcpy (hw->wiphy->perm_addr, addr,ETH_ALEN ); } +static inline int ieee80211_num_regular_queues (struct ieee80211_hw *hw) +{ +#ifdef CONFIG_MAC80211_QOS +return hw->queues; +#else +return 1 ; +#endif +} + +static inline int ieee80211_num_queues (struct ieee80211_hw *hw) +{ +#ifdef CONFIG_MAC80211_QOS +return hw->queues + hw->ampdu_queues; +#else +return 1 ; +#endif +} +static inline struct ieee80211_rate *ieee80211_get_tx_rate (const struct ieee80211_hw *hw,const struct ieee80211_tx_info *c)
net/mac80211/ieee80211_i.h +10 -6
@@ -595,7 +595,7 @@ struct ieee80211_local {struct sta_info *sta_hash[STA_HASH_SIZE ];struct timer_list sta_cleanup; -unsigned long state[IEEE80211_MAX_QUEUES +IEEE80211_MAX_AMPDU_QUEUES ]; +unsigned long queues_pending[BITS_TO_LONGS (IEEE80211_MAX_QUEUES )];struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES ];struct tasklet_struct tx_pending_tasklet;
@@ -759,6 +759,15 @@ struct ieee80211_local {#endif }; +static inline int ieee80211_is_multiqueue (struct ieee80211_local *local) +{ +#ifdef CONFIG_MAC80211_QOS +return netif_is_multiqueue (local->mdev); +#else +return 0 ; +#endif +} +/* this struct represents 802.11n's RA/TID combination */ struct ieee80211_ra_tid {u8 ra[ETH_ALEN ];
@@ -828,11 +837,6 @@ static inline struct ieee80211_hw *localreturn &local->hw; } -enum ieee80211_link_state_t { -IEEE80211_LINK_STATE_XOFF =0 , -IEEE80211_LINK_STATE_PENDING , -}; -struct sta_attribute {struct attribute attr;ssize_t (*show)(const struct sta_info *,char *buf);
drivers/net/wireless/iwlwifi/iwl-tx.c +2 -2
@@ -696,7 +696,7 @@ int iwl_tx_skb(struct iwl_priv *priv, ststruct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct iwl_tfd_frame *tfd;u32 *control_flags; -int txq_id = info->queue; +int txq_id =skb_get_queue_mapping (skb);struct iwl_tx_queue *txq =NULL ;struct iwl_queue *q =NULL ;dma_addr_t phys_addr;
@@ -917,7 +917,7 @@ int iwl_tx_skb(struct iwl_priv *priv, stspin_unlock_irqrestore (&priv->lock, flags); } -ieee80211_stop_queue (priv->hw, info->queue); +ieee80211_stop_queue (priv->hw,skb_get_queue_mapping (skb)); }return 0 ;
net/mac80211/iface.c +1 -1
@@ -175,7 +175,7 @@ void ieee80211_if_set_type(struct net_de ifsta->flags |=IEEE80211_STA_CREATE_IBSS |IEEE80211_STA_AUTO_BSSID_SEL |IEEE80211_STA_AUTO_CHANNEL_SEL ; -if (sdata->local->hw.queues >=4 ) +if (ieee80211_num_regular_queues (&sdata->local->hw) >=4 ) ifsta->flags |=IEEE80211_STA_WMM_ENABLED ; msdata =IEEE80211_DEV_TO_SUB_IF (sdata->local->mdev);
net/mac80211/sta_info.c +1 -1
@@ -255,7 +255,7 @@ struct sta_info *sta_info_alloc(struct i* sta_rx_agg_session_timer_expired for useage */ sta->timer_to_tid[i] = i;/* tid to tx queue: initialize according to HW (0 is valid) */ - sta->tid_to_tx_q[i] = local->hw.queues + local->hw.ampdu_queues; + sta->tid_to_tx_q[i] =ieee80211_num_queues (&local->hw);/* rx */ sta->ampdu_mlme.tid_state_rx[i] =HT_AGG_STATE_IDLE ; sta->ampdu_mlme.tid_rx[i] =NULL ;
RE: [PATCH 2/2] mac80211: use multi-queue master netdevice
Quoted 25 lines
This patch updates mac80211 and drivers to be multi-queue aware and use that instead of the internal queue mapping. Also does a number of cleanups in various pieces of the code that fall out and reduces internal mac80211 state size.
Signed-off-by Johannes Berg <[email protected]>---
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 | 3 drivers/net/wireless/iwlwifi/iwl-tx.c | 4 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 - drivers/net/wireless/p54/p54common.c | 8 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 10 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 13 --- drivers/net/wireless/rtl8180_dev.c | 4 - include/net/mac80211.h | 20 +++++ net/mac80211/Kconfig | 14 +++- net/mac80211/Makefile | 2 net/mac80211/ieee80211_i.h | 16 ++-- net/mac80211/iface.c | 2
Quoted 8 lines
net/mac80211/main.c | 29 ++++++-- net/mac80211/sta_info.c | 2 net/mac80211/tx.c | 97 ++++++++++++---------------- net/mac80211/util.c | 29 ++++---- net/mac80211/wme.c | 14 +--- net/mac80211/wme.h | 2 21 files changed, 158 insertions(+), 132 deletions(-)
This patch looks fine to me. Thanks for porting the wireless tree to use these bits Johannes.
-PJ Waskiewicz
Johannes Berg
maintainerQuoted 6 lines · Johannes Berg
This patch (well, there are two, but the first one is just some sanity checking) converts mac80211 to use a multiqueue netdev.
The next step will be to re-do fragmentation taking into account proper A-MPDU handling etc. but I would love to have Ron look over that too since he's much more familiar with the A-MPDU stuff.
Ouch, sorry about messing up your name in the CC list, Ron. (and if anyone else wants to reply substitute the i by a y like I have done now)
johannes
This series looks good to me
Thanks
Ron