bcm43xx QoS support
RFC PATCH 1/1 bcm43xx QoS support
This incomplete patch tries to implement QoS support in the bcm43xx driver.
It's incomplete, because we don't upload the QoS parameters to the hardware, yet.
http://bcm-v4.sipsolutions.net/802.11/QoS
We might need some stack support to implement this (I'm not entirely sure, as I didn't read the whole ieee 802.11e, yet). Does some stack support for QoS exist? We need to upload some TX-opportunity, Interframe-space and some other values to the firmware. Not sure where to get them from, yet (didn't completely read 802.11e, yet :) ).
The bcm43xx device has 6 DMA rings, but I think only 4 are usable for 802.11e QoS. The other two seem to be useful for APs, though.
This patch also implements per-DMAring-locking. So this (theoretically) enables the stack to simultaneously transmit on two (or more) rings. Though, I'm not sure the stack exploits this behaviour, yet.
drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c +87 -21
@@ -290,6 +290,50 @@ void return_slot(struct bcm43xx_dmaring ring->used_slots--; } +/* Mac80211-queue to bcm43xx-ring mapping */ +static struct bcm43xx_dmaring *priority_to_txring (struct bcm43xx_wldev *dev, +int queue_priority) +{ +struct bcm43xx_dmaring *ring; + +/* 0 = highest priority */ +switch (queue_priority) { +default : +assert (0 ); +/* fallthrough */ +case 0 : + ring = dev->dma.tx_ring3; +break ; +case 1 : + ring = dev->dma.tx_ring2; +break ; +case 2 : + ring = dev->dma.tx_ring1; +break ; +case 3 : + ring = dev->dma.tx_ring0; +break ; +case 4 : + ring = dev->dma.tx_ring4; +break ; +case 5 : + ring = dev->dma.tx_ring5; +break ; + } + +return ring; +} + +/* Bcm43xx-ring to mac80211-queue mapping */ +static inline int txring_to_priority (struct bcm43xx_dmaring *ring) +{ +static const u8 idx_to_prio[] = + {3 ,2 ,1 ,0 ,4 ,5 , }; + +return idx_to_prio[ring->index]; +} + +u16 bcm43xx_dmacontroller_base (int dma64bit,int controller_idx) {static const u16 map64[] = {
@@ -816,6 +860,7 @@ struct bcm43xx_dmaring * bcm43xx_setup_d }else assert (0 ); } +spin_lock_init (&ring->lock);#ifdef CONFIG_BCM43XX_MAC80211_DEBUG ring->last_injected_overflow = jiffies;#endif
@@ -1171,37 +1216,39 @@ int bcm43xx_dma_tx(struct bcm43xx_wldevstruct sk_buff *skb, struct ieee80211_tx_control *ctl) { - struct bcm43xx_dmaring *ring = dev->dma.tx_ring1; + struct bcm43xx_dmaring *ring;int err =0 ; +unsigned long flags; + ring =priority_to_txring (dev, ctl->queue); +spin_lock_irqsave (&ring->lock, flags);assert (ring->tx);if (unlikely (free_slots (ring) <SLOTS_PER_PACKET )) { -/* This should never trigger, as we call -* ieee80211_stop_queue() when it's full. -*/ printkl(KERN_ERR PFX "DMA queue overflow\n"); -return NETDEV_TX_BUSY ; + err = -ENOSPC ; + goto out_unlock; }/* Check if the queue was stopped in mac80211, -* but we got called nevertheless. */ +* but we got called nevertheless. +* That would be a mac80211 bug. */ assert (!ring->stopped); err =dma_tx_fragment (ring, skb, ctl);if (unlikely (err)) { printkl(KERN_ERR PFX "DMA tx mapping failure\n"); -return NETDEV_TX_BUSY ; + goto out_unlock; } - ring->nr_tx_packets++;if ((free_slots (ring) <SLOTS_PER_PACKET ) ||should_inject_overflow (ring)) {/* This TX ring is full. */ -/* FIXME: we currently only have one queue, so hardcode queue 0 here. */ -ieee80211_stop_queue (dev->wl->hw,0 ); +ieee80211_stop_queue (dev->wl->hw,txring_to_priority (ring)); ring->stopped =1 ; } +out_unlock: +spin_unlock_irqrestore (&ring->lock, flags); -return 0 ; +return err; } void bcm43xx_dma_handle_txstatus(struct bcm43xx_wldev *dev,
@@ -1216,6 +1263,9 @@ void bcm43xx_dma_handle_txstatus(struct ring =parse_cookie (dev, status->cookie, &slot);if (unlikely (!ring))return ; +assert (irqs_disabled ()); +spin_lock (&ring->lock); +assert (ring->tx); ops = ring->ops;while (1 ) {
@@ -1257,24 +1307,32 @@ void bcm43xx_dma_handle_txstatus(struct dev->stats.last_tx = jiffies;if (ring->stopped) {assert (free_slots (ring) >=SLOTS_PER_PACKET ); -/* FIXME: we currently only have one queue, co hardcode queue 0 here. */ -ieee80211_wake_queue (dev->wl->hw,0 ); +ieee80211_wake_queue (dev->wl->hw,txring_to_priority (ring)); ring->stopped =0 ; } + +spin_unlock (&ring->lock); }void bcm43xx_dma_get_tx_stats (struct bcm43xx_wldev *dev,struct ieee80211_tx_queue_stats *stats) { -struct bcm43xx_dma *dma = &dev->dma; +const int nr_queues = dev->wl->hw->queues;struct bcm43xx_dmaring *ring;struct ieee80211_tx_queue_stats_data *data; +unsigned long flags; +int i; - ring = dma->tx_ring1; - data = &(stats->data[0 ]); - data->len = ring->used_slots /SLOTS_PER_PACKET ; - data->limit = ring->nr_slots /SLOTS_PER_PACKET ; - data->count = ring->nr_tx_packets; +for (i =0 ; i < nr_queues; i++) { + data = &(stats->data[i]); + ring =priority_to_txring (dev, i); + +spin_lock_irqsave (&ring->lock, flags); + data->len = ring->used_slots /SLOTS_PER_PACKET ; + data->limit = ring->nr_slots /SLOTS_PER_PACKET ; + data->count = ring->nr_tx_packets; +spin_unlock_irqrestore (&ring->lock, flags); + } } static void dma_rx(struct bcm43xx_dmaring *ring,
@@ -1397,16 +1455,24 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari ring->current_slot = slot; } -static inline void bcm43xx_dma_tx_suspend_ring (struct bcm43xx_dmaring *ring) +static void bcm43xx_dma_tx_suspend_ring (struct bcm43xx_dmaring *ring) { +unsigned long flags; + +spin_lock_irqsave (&ring->lock, flags);assert (ring->tx); ring->ops->tx_suspend (ring); +spin_unlock_irqrestore (&ring->lock, flags); } -static inline void bcm43xx_dma_tx_resume_ring (struct bcm43xx_dmaring *ring) +static void bcm43xx_dma_tx_resume_ring (struct bcm43xx_dmaring *ring) { +unsigned long flags; + +spin_lock_irqsave (&ring->lock, flags);assert (ring->tx); ring->ops->tx_resume (ring); +spin_unlock_irqrestore (&ring->lock, flags); }void bcm43xx_dma_tx_suspend (struct bcm43xx_wldev *dev)
drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.h +2 -0
@@ -252,6 +252,8 @@ struct bcm43xx_dmaring {u8 dma64;/* Boolean. Is this ring stopped at ieee80211 level? */ u8 stopped; +/* Lock, only used for TX. */ +spinlock_t lock;struct bcm43xx_wldev *dev;#ifdef CONFIG_BCM43XX_MAC80211_DEBUG /* Maximum number of used slots. */
drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c +15 -11
@@ -2448,16 +2448,17 @@ static int bcm43xx_tx(struct ieee80211_hint err = -ENODEV ;unsigned long flags; +/* DMA-TX is done without a global lock. */ if (unlikely (!dev)) goto out; -spin_lock_irqsave (&wl->irq_lock, flags); -if (likely (bcm43xx_status (dev) == BCM43xx_STAT_INITIALIZED)) { -if (bcm43xx_using_pio (dev)) - err =bcm43xx_pio_tx (dev, skb, ctl); -else - err =bcm43xx_dma_tx (dev, skb, ctl); - } -spin_unlock_irqrestore (&wl->irq_lock, flags); +assert (bcm43xx_status (dev) == BCM43xx_STAT_INITIALIZED); +assert (dev->started); +if (bcm43xx_using_pio (dev)) { +spin_lock_irqsave (&wl->irq_lock, flags); + err =bcm43xx_pio_tx (dev, skb, ctl); +spin_unlock_irqrestore (&wl->irq_lock, flags); + }else + err =bcm43xx_dma_tx (dev, skb, ctl); out:if (unlikely (err))return NETDEV_TX_BUSY ;
@@ -3313,10 +3314,13 @@ static int bcm43xx_wireless_core_init(stbcm43xx_write_mac_bssid_templates (dev);do { -if (bcm43xx_using_pio (dev)) +if (bcm43xx_using_pio (dev)) { err =bcm43xx_pio_init (dev); -else + }else { err =bcm43xx_dma_init (dev); +if (!err) +bcm43xx_qos_init (dev); + } }while (err == -EAGAIN );if (err) goto err_chip_exit;
@@ -3798,7 +3802,7 @@ static int bcm43xx_wireless_init(struct hw->max_signal =100 ; hw->max_rssi =-110 ; hw->max_noise =-110 ; - hw->queues =1 ; + hw->queues =4 ;SET_IEEE80211_DEV (hw, dev->dev);if (is_valid_ether_addr (sprom->r1.et1mac))SET_IEEE80211_PERM_ADDR (hw, sprom->r1.et1mac);
drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.c +25 -0
@@ -619,3 +619,28 @@ void bcm43xx_tx_resume(struct bcm43xx_wlelse bcm43xx_dma_tx_resume (dev); } + +static void upload_qos_parms (struct bcm43xx_wldev *dev, +const u16 *parms, +u16 offset) +{ +int i; + +for (i =0 ; i < BCM43xx_NR_QOSPARMS; i++) { +bcm43xx_shm_write16 (dev, BCM43xx_SHM_SHARED, + offset + i, parms[i]); + } +} + +/* Initialize the QoS parameters */ +void bcm43xx_qos_init (struct bcm43xx_wldev *dev) +{ +//TODO +bcm43xx_hf_write (dev,bcm43xx_hf_read (dev) | BCM43xx_HF_EDCF); +//FIXME kill magic +bcm43xx_write16 (dev,0x688 , +bcm43xx_read16 (dev,0x688 ) |0x4 ); + + +/*TODO: We might need some stack support here to get the values. */ +}
drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.h +15 -0
@@ -215,6 +215,21 @@ void bcm43xx_handle_hwtxstatus(struct bcvoid bcm43xx_tx_suspend (struct bcm43xx_wldev *dev);void bcm43xx_tx_resume (struct bcm43xx_wldev *dev); + +#define BCM43xx_NR_QOSPARMS 21 +enum { + BCM43xx_QOSPARM_TXOP =0 , + BCM43xx_QOSPARM_CWMIN, + BCM43xx_QOSPARM_CWMAX, + BCM43xx_QOSPARM_CWCUR, + BCM43xx_QOSPARM_AIFS, + BCM43xx_QOSPARM_BSLOTS, + BCM43xx_QOSPARM_REGGAP, + BCM43xx_QOSPARM_STATUS, +}; +void bcm43xx_qos_init (struct bcm43xx_wldev *dev); + +/* Helper functions for converting the key-table index from "firmware-format" * to "raw-format" and back. The firmware API changed for this at some revision. * We need to account for that here. */
Signature · 1 line
Greetings Michael.
iwlwifi supports QoS. It has queues 4 hw for WMM access categories 2 hw queus for HCCA.
There is also a discussion about supporting hardware queues in qdisc in netdev.
Quoted 349 lines · Michael Buesch
This incomplete patch tries to implement QoS support in the bcm43xx driver.
It's incomplete, because we don't upload the QoS parameters to the hardware, yet.
http://bcm-v4.sipsolutions.net/802.11/QoS
We might need some stack support to implement this (I'm not entirely sure, as I didn't read the whole ieee 802.11e, yet). Does some stack support for QoS exist? We need to upload some TX-opportunity, Interframe-space and some other values to the firmware. Not sure where to get them from, yet (didn't completely read 802.11e, yet :) ).The bcm43xx device has 6 DMA rings, but I think only 4 are usable for 802.11e QoS. The other two seem to be useful for APs, though.
This patch also implements per-DMAring-locking. So this (theoretically) enables the stack to simultaneously transmit on two (or more) rings. Though, I'm not sure the stack exploits this behaviour, yet.
Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c
===================================================================drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c 2007-06-16 00:38:59.000000000 +0200 renamed from drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c 2007-06-02 23:14:46.000000000 +0200 +87
-21@@ -290,6 +290,50 @@ void return_slot(struct bcm43xx_dmaring ring->used_slots--; } +/* Mac80211-queue to bcm43xx-ring mapping */ +static struct bcm43xx_dmaring * priority_to_txring(struct bcm43xx_wldev *dev, + int queue_priority) +{ + struct bcm43xx_dmaring *ring; + + /* 0 = highest priority */ + switch (queue_priority) { + default: + assert(0); + /* fallthrough */ + case 0: + ring = dev->dma.tx_ring3; + break; + case 1: + ring = dev->dma.tx_ring2; + break; + case 2: + ring = dev->dma.tx_ring1; + break; + case 3: + ring = dev->dma.tx_ring0; + break; + case 4: + ring = dev->dma.tx_ring4; + break; + case 5: + ring = dev->dma.tx_ring5; + break; + } + + return ring; +} + +/* Bcm43xx-ring to mac80211-queue mapping */ +static inline int txring_to_priority(struct bcm43xx_dmaring *ring) +{ + static const u8 idx_to_prio[] = + { 3, 2, 1, 0, 4, 5, }; + + return idx_to_prio[ring->index]; +} + + u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx) { static const u16 map64[] = {@@ -816,6 +860,7 @@ struct bcm43xx_dmaring * bcm43xx_setup_d } else assert(0); } + spin_lock_init(&ring->lock); #ifdef CONFIG_BCM43XX_MAC80211_DEBUG ring->last_injected_overflow = jiffies; #endif@@ -1171,37 +1216,39 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev struct sk_buff *skb, struct ieee80211_tx_control *ctl) { - struct bcm43xx_dmaring *ring = dev->dma.tx_ring1; + struct bcm43xx_dmaring *ring; int err = 0; + unsigned long flags; + ring = priority_to_txring(dev, ctl->queue); + spin_lock_irqsave(&ring->lock, flags); assert(ring->tx); if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) { - /* This should never trigger, as we call - * ieee80211_stop_queue() when it's full. - */ printkl(KERN_ERR PFX "DMA queue overflow\n"); - return NETDEV_TX_BUSY; + err = -ENOSPC; + goto out_unlock; } /* Check if the queue was stopped in mac80211, - * but we got called nevertheless. */ + * but we got called nevertheless. + * That would be a mac80211 bug. */ assert(!ring->stopped); err = dma_tx_fragment(ring, skb, ctl); if (unlikely(err)) { printkl(KERN_ERR PFX "DMA tx mapping failure\n"); - return NETDEV_TX_BUSY; + goto out_unlock; } - ring->nr_tx_packets++; if ((free_slots(ring) < SLOTS_PER_PACKET) || should_inject_overflow(ring)) { /* This TX ring is full. */ - /* FIXME: we currently only have one queue, so hardcode queue 0 here. */ - ieee80211_stop_queue(dev->wl->hw, 0); + ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); ring->stopped = 1; } +out_unlock: + spin_unlock_irqrestore(&ring->lock, flags); - return 0; + return err; } void bcm43xx_dma_handle_txstatus(struct bcm43xx_wldev *dev,@@ -1216,6 +1263,9 @@ void bcm43xx_dma_handle_txstatus(struct ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) return; + assert(irqs_disabled()); + spin_lock(&ring->lock); + assert(ring->tx); ops = ring->ops; while (1) {@@ -1257,24 +1307,32 @@ void bcm43xx_dma_handle_txstatus(struct dev->stats.last_tx = jiffies; if (ring->stopped) { assert(free_slots(ring) >= SLOTS_PER_PACKET); - /* FIXME: we currently only have one queue, co hardcode queue 0 here. */ - ieee80211_wake_queue(dev->wl->hw, 0); + ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); ring->stopped = 0; } + + spin_unlock(&ring->lock); } void bcm43xx_dma_get_tx_stats(struct bcm43xx_wldev *dev, struct ieee80211_tx_queue_stats *stats) { - struct bcm43xx_dma *dma = &dev->dma; + const int nr_queues = dev->wl->hw->queues; struct bcm43xx_dmaring *ring; struct ieee80211_tx_queue_stats_data *data; + unsigned long flags; + int i; - ring = dma->tx_ring1; - data = &(stats->data[0]); - data->len = ring->used_slots / SLOTS_PER_PACKET; - data->limit = ring->nr_slots / SLOTS_PER_PACKET; - data->count = ring->nr_tx_packets; + for (i = 0; i < nr_queues; i++) { + data = &(stats->data[i]); + ring = priority_to_txring(dev, i); + + spin_lock_irqsave(&ring->lock, flags); + data->len = ring->used_slots / SLOTS_PER_PACKET; + data->limit = ring->nr_slots / SLOTS_PER_PACKET; + data->count = ring->nr_tx_packets; + spin_unlock_irqrestore(&ring->lock, flags); + } } static void dma_rx(struct bcm43xx_dmaring *ring,@@ -1397,16 +1455,24 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari ring->current_slot = slot; } -static inline void bcm43xx_dma_tx_suspend_ring(struct bcm43xx_dmaring *ring) +static void bcm43xx_dma_tx_suspend_ring(struct bcm43xx_dmaring *ring) { + unsigned long flags; + + spin_lock_irqsave(&ring->lock, flags); assert(ring->tx); ring->ops->tx_suspend(ring); + spin_unlock_irqrestore(&ring->lock, flags); } -static inline void bcm43xx_dma_tx_resume_ring(struct bcm43xx_dmaring *ring) +static void bcm43xx_dma_tx_resume_ring(struct bcm43xx_dmaring *ring) { + unsigned long flags; + + spin_lock_irqsave(&ring->lock, flags); assert(ring->tx); ring->ops->tx_resume(ring); + spin_unlock_irqrestore(&ring->lock, flags); } void bcm43xx_dma_tx_suspend(struct bcm43xx_wldev *dev)Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.h
===================================================================drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.h 2007-06-16 00:43:40.000000000 +0200 renamed from drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.h 2007-06-02 22:54:41.000000000 +0200 +2
-0@@ -252,6 +252,8 @@ struct bcm43xx_dmaring { u8 dma64; /* Boolean. Is this ring stopped at ieee80211 level? */ u8 stopped; + /* Lock, only used for TX. */ + spinlock_t lock; struct bcm43xx_wldev *dev; #ifdef CONFIG_BCM43XX_MAC80211_DEBUG /* Maximum number of used slots. */Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c
===================================================================drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c 2007-06-16 00:50:26.000000000 +0200 renamed from drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c 2007-06-14 16:05:09.000000000 +0200 +15
-11@@ -2448,16 +2448,17 @@ static int bcm43xx_tx(struct ieee80211_h int err = -ENODEV; unsigned long flags; + /* DMA-TX is done without a global lock. */ if (unlikely(!dev)) goto out; - spin_lock_irqsave(&wl->irq_lock, flags); - if (likely(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED)) { - if (bcm43xx_using_pio(dev)) - err = bcm43xx_pio_tx(dev, skb, ctl); - else - err = bcm43xx_dma_tx(dev, skb, ctl); - } - spin_unlock_irqrestore(&wl->irq_lock, flags); + assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED); + assert(dev->started); + if (bcm43xx_using_pio(dev)) { + spin_lock_irqsave(&wl->irq_lock, flags); + err = bcm43xx_pio_tx(dev, skb, ctl); + spin_unlock_irqrestore(&wl->irq_lock, flags); + } else + err = bcm43xx_dma_tx(dev, skb, ctl); out: if (unlikely(err)) return NETDEV_TX_BUSY;@@ -3313,10 +3314,13 @@ static int bcm43xx_wireless_core_init(st bcm43xx_write_mac_bssid_templates(dev); do { - if (bcm43xx_using_pio(dev)) + if (bcm43xx_using_pio(dev)) { err = bcm43xx_pio_init(dev); - else + } else { err = bcm43xx_dma_init(dev); + if (!err) + bcm43xx_qos_init(dev); + } } while (err == -EAGAIN); if (err) goto err_chip_exit;@@ -3798,7 +3802,7 @@ static int bcm43xx_wireless_init(struct hw->max_signal = 100; hw->max_rssi = -110; hw->max_noise = -110; - hw->queues = 1; + hw->queues = 4; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->r1.et1mac)) SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac);Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.c
===================================================================drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.c 2007-06-16 13:14:30.000000000 +0200 renamed from drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.c 2007-06-10 14:37:06.000000000 +0200 +25
-0@@ -619,3 +619,28 @@ void bcm43xx_tx_resume(struct bcm43xx_wl else bcm43xx_dma_tx_resume(dev); } + +static void upload_qos_parms(struct bcm43xx_wldev *dev, + const u16 *parms, + u16 offset) +{ + int i; + + for (i = 0; i < BCM43xx_NR_QOSPARMS; i++) { + bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, + offset + i, parms[i]); + } +} + +/* Initialize the QoS parameters */ +void bcm43xx_qos_init(struct bcm43xx_wldev *dev) +{ + //TODO + bcm43xx_hf_write(dev, bcm43xx_hf_read(dev) | BCM43xx_HF_EDCF); + //FIXME kill magic + bcm43xx_write16(dev, 0x688, + bcm43xx_read16(dev, 0x688) | 0x4); + + + /*TODO: We might need some stack support here to get the values. */ +}Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.h
===================================================================drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.h 2007-06-16 01:09:03.000000000 +0200 renamed from drivers/net/wireless/mac80211/bcm43xx/bcm43xx_xmit.h 2007-06-01 01:14:02.000000000 +0200 +15
-1@@ -215,6 +215,21 @@ void bcm43xx_handle_hwtxstatus(struct bc void bcm43xx_tx_suspend(struct bcm43xx_wldev *dev); void bcm43xx_tx_resume(struct bcm43xx_wldev *dev); + +#define BCM43xx_NR_QOSPARMS 21 +enum { + BCM43xx_QOSPARM_TXOP = 0, + BCM43xx_QOSPARM_CWMIN, + BCM43xx_QOSPARM_CWMAX, + BCM43xx_QOSPARM_CWCUR, + BCM43xx_QOSPARM_AIFS, + BCM43xx_QOSPARM_BSLOTS, + BCM43xx_QOSPARM_REGGAP, + BCM43xx_QOSPARM_STATUS, +}; +void bcm43xx_qos_init(struct bcm43xx_wldev *dev); + + /* Helper functions for converting the key-table index from "firmware-format" * to "raw-format" and back. The firmware API changed for this at some revision. * We need to account for that here. */ --Greetings Michael.
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Johannes Berg
maintainerQuoted 2 lines · Tomas Winkler
iwlwifi supports QoS. It has queues 4 hw for WMM access categories 2 hw queus for HCCA.
But it too can't ever create QoS-data frames or negotiate TXOPs afaict, unless it does more than we want in hardware.
Quoted 2 lines
There is also a discussion about supporting hardware queues in qdisc in netdev.
Which isn't really a concern to the driver since only mac80211 will need to be changed for that.
I suppose the question is: what are we missing in mac80211 now? It seems that we have no way of sending out QoS-data frames and that seems weird. Nor do we parse TXOP information etc. Possibly this is because we support WME and that's based on an early 802.11e draft?
johannes
Quoted 6 lines · Johannes Berg
Quoted 2 lines · Tomas Winkler
iwlwifi supports QoS. It has queues 4 hw for WMM access categories 2 hw queus for HCCA.
But it too can't ever create QoS-data frames or negotiate TXOPs afaict, unless it does more than we want in hardware.
True
Quoted 6 lines
Quoted 2 lines
There is also a discussion about supporting hardware queues in qdisc in netdev.
Which isn't really a concern to the driver since only mac80211 will need to be changed for that.
I'm not sure it's only mac80211 problem as driver is responsible for stopping and waking up the queues. Only driver knows whether hw queue is full or not.
Quoted 2 lines
I suppose the question is: what are we missing in mac80211 now? It seems that we have no way of sending out QoS-data frames and that seems weird.
QoS frame are send just fine by mac80211 (at least under iwlwifi), only the sequence numbers has to be overwritten in driver since the current handler doesn't advance them per TID.
Quoted 2 lines
Nor do we parse TXOP information etc. Possibly this is because we support WME and that's based on an early 802.11e draft?
I addition wme.c qdisc scheduler is rather naive one, it only statically assign priorities, it wouldn't pass WMM certification I guess.
Quoted 3 lines
johannes
Johannes Berg
maintainerQuoted 9 lines · Tomas Winkler
Quoted 6 lines
Quoted 2 lines
There is also a discussion about supporting hardware queues in qdisc in netdev.
Which isn't really a concern to the driver since only mac80211 will need to be changed for that.
I'm not sure it's only mac80211 problem as driver is responsible for stopping and waking up the queues. Only driver knows whether hw queue is full or not.
Of course, but we already have that API in mac80211, hence well-written drivers already tell mac80211 about it so all we'd need to do is change mac80211 to tell the net layer :)
Quoted 6 lines
Quoted 2 lines
I suppose the question is: what are we missing in mac80211 now? It seems that we have no way of sending out QoS-data frames and that seems weird..
QoS frame are send just fine by mac80211 (at least under iwlwifi), only the sequence numbers has to be overwritten in driver since the current handler doesn't advance them per TID.
Oh, you're right, I missed that wme_qdiscop_enqueue does that.
Quoted 6 lines
Quoted 2 lines
Nor do we parse TXOP information etc. Possibly this is because we support WME and that's based on an early 802.11e draft?
I addition
wme.cqdisc scheduler is rather naive one, it only statically assign priorities, it wouldn't pass WMM certification I guess.
I have no idea what WMM certification contains. All I've been trying to say is that this area really needs some work to be useful.
For the problem at hand, namely some QoS support in bcm43xx, we'll just have to hardcode some QoS parameters for now, I'd think, but I don't know what those would be.
johannes