aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-05 15:18:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-07 16:02:59 -0500
commite6f5b934fba8c44c87c551e066aa7ca6fde2939e (patch)
treeb3fabd1b35a044fe0f50d1ab16ca0dd697c3f59a /drivers/net/wireless/b43
parente5f98f2df903af627a9b9ac55b9352fd54fc431a (diff)
b43: Add QOS support
This adds QOS support to the b43 driver. QOS can be disabled on driver level with a module parameter for debugging purposes. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/b43.h37
-rw-r--r--drivers/net/wireless/b43/dma.c90
-rw-r--r--drivers/net/wireless/b43/dma.h3
-rw-r--r--drivers/net/wireless/b43/main.c180
-rw-r--r--drivers/net/wireless/b43/main.h4
-rw-r--r--drivers/net/wireless/b43/xmit.c27
-rw-r--r--drivers/net/wireless/b43/xmit.h12
7 files changed, 262 insertions, 91 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 33459d61a717..55031463c396 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -99,6 +99,8 @@
99#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ 99#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
100#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ 100#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
101#define B43_MMIO_RNG 0x65A 101#define B43_MMIO_RNG 0x65A
102#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
103#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
102#define B43_MMIO_POWERUP_DELAY 0x6A8 104#define B43_MMIO_POWERUP_DELAY 0x6A8
103 105
104/* SPROM boardflags_lo values */ 106/* SPROM boardflags_lo values */
@@ -621,6 +623,35 @@ struct b43_key {
621 u8 algorithm; 623 u8 algorithm;
622}; 624};
623 625
626/* SHM offsets to the QOS data structures for the 4 different queues. */
627#define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \
628 (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
629#define B43_QOS_BACKGROUND B43_QOS_PARAMS(0)
630#define B43_QOS_BESTEFFORT B43_QOS_PARAMS(1)
631#define B43_QOS_VIDEO B43_QOS_PARAMS(2)
632#define B43_QOS_VOICE B43_QOS_PARAMS(3)
633
634/* QOS parameter hardware data structure offsets. */
635#define B43_NR_QOSPARAMS 22
636enum {
637 B43_QOSPARAM_TXOP = 0,
638 B43_QOSPARAM_CWMIN,
639 B43_QOSPARAM_CWMAX,
640 B43_QOSPARAM_CWCUR,
641 B43_QOSPARAM_AIFS,
642 B43_QOSPARAM_BSLOTS,
643 B43_QOSPARAM_REGGAP,
644 B43_QOSPARAM_STATUS,
645};
646
647/* QOS parameters for a queue. */
648struct b43_qos_params {
649 /* The QOS parameters */
650 struct ieee80211_tx_queue_params p;
651 /* Does this need to get uploaded to hardware? */
652 bool need_hw_update;
653};
654
624struct b43_wldev; 655struct b43_wldev;
625 656
626/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ 657/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
@@ -673,6 +704,12 @@ struct b43_wl {
673 struct sk_buff *current_beacon; 704 struct sk_buff *current_beacon;
674 bool beacon0_uploaded; 705 bool beacon0_uploaded;
675 bool beacon1_uploaded; 706 bool beacon1_uploaded;
707
708 /* The current QOS parameters for the 4 queues.
709 * This is protected by the irq_lock. */
710 struct b43_qos_params qos_params[4];
711 /* Workqueue for updating QOS parameters in hardware. */
712 struct work_struct qos_update_work;
676}; 713};
677 714
678/* In-memory representation of a cached microcode file. */ 715/* In-memory representation of a cached microcode file. */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3dfb28a34be9..c8ead465497a 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -291,52 +291,6 @@ static inline int request_slot(struct b43_dmaring *ring)
291 return slot; 291 return slot;
292} 292}
293 293
294/* Mac80211-queue to b43-ring mapping */
295static struct b43_dmaring *priority_to_txring(struct b43_wldev *dev,
296 int queue_priority)
297{
298 struct b43_dmaring *ring;
299
300/*FIXME: For now we always run on TX-ring-1 */
301 return dev->dma.tx_ring1;
302
303 /* 0 = highest priority */
304 switch (queue_priority) {
305 default:
306 B43_WARN_ON(1);
307 /* fallthrough */
308 case 0:
309 ring = dev->dma.tx_ring3;
310 break;
311 case 1:
312 ring = dev->dma.tx_ring2;
313 break;
314 case 2:
315 ring = dev->dma.tx_ring1;
316 break;
317 case 3:
318 ring = dev->dma.tx_ring0;
319 break;
320 }
321
322 return ring;
323}
324
325/* b43-ring to mac80211-queue mapping */
326static inline int txring_to_priority(struct b43_dmaring *ring)
327{
328 static const u8 idx_to_prio[] = { 3, 2, 1, 0, };
329 unsigned int index;
330
331/*FIXME: have only one queue, for now */
332 return 0;
333
334 index = ring->index;
335 if (B43_WARN_ON(index >= ARRAY_SIZE(idx_to_prio)))
336 index = 0;
337 return idx_to_prio[index];
338}
339
340static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx) 294static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx)
341{ 295{
342 static const u16 map64[] = { 296 static const u16 map64[] = {
@@ -1272,6 +1226,37 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
1272 return 0; 1226 return 0;
1273} 1227}
1274 1228
1229/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
1230static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
1231 u8 queue_prio)
1232{
1233 struct b43_dmaring *ring;
1234
1235 if (b43_modparam_qos) {
1236 /* 0 = highest priority */
1237 switch (queue_prio) {
1238 default:
1239 B43_WARN_ON(1);
1240 /* fallthrough */
1241 case 0:
1242 ring = dev->dma.tx_ring3; /* AC_VO */
1243 break;
1244 case 1:
1245 ring = dev->dma.tx_ring2; /* AC_VI */
1246 break;
1247 case 2:
1248 ring = dev->dma.tx_ring1; /* AC_BE */
1249 break;
1250 case 3:
1251 ring = dev->dma.tx_ring0; /* AC_BK */
1252 break;
1253 }
1254 } else
1255 ring = dev->dma.tx_ring1;
1256
1257 return ring;
1258}
1259
1275int b43_dma_tx(struct b43_wldev *dev, 1260int b43_dma_tx(struct b43_wldev *dev,
1276 struct sk_buff *skb, struct ieee80211_tx_control *ctl) 1261 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
1277{ 1262{
@@ -1294,7 +1279,7 @@ int b43_dma_tx(struct b43_wldev *dev,
1294 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1279 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1295 } else { 1280 } else {
1296 /* Decide by priority where to put this frame. */ 1281 /* Decide by priority where to put this frame. */
1297 ring = priority_to_txring(dev, ctl->queue); 1282 ring = select_ring_by_priority(dev, ctl->queue);
1298 } 1283 }
1299 1284
1300 spin_lock_irqsave(&ring->lock, flags); 1285 spin_lock_irqsave(&ring->lock, flags);
@@ -1309,6 +1294,11 @@ int b43_dma_tx(struct b43_wldev *dev,
1309 * That would be a mac80211 bug. */ 1294 * That would be a mac80211 bug. */
1310 B43_WARN_ON(ring->stopped); 1295 B43_WARN_ON(ring->stopped);
1311 1296
1297 /* Assign the queue number to the ring (if not already done before)
1298 * so TX status handling can use it. The queue to ring mapping is
1299 * static, so we don't need to store it per frame. */
1300 ring->queue_prio = ctl->queue;
1301
1312 err = dma_tx_fragment(ring, skb, ctl); 1302 err = dma_tx_fragment(ring, skb, ctl);
1313 if (unlikely(err == -ENOKEY)) { 1303 if (unlikely(err == -ENOKEY)) {
1314 /* Drop this packet, as we don't have the encryption key 1304 /* Drop this packet, as we don't have the encryption key
@@ -1325,7 +1315,7 @@ int b43_dma_tx(struct b43_wldev *dev,
1325 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1315 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1326 should_inject_overflow(ring)) { 1316 should_inject_overflow(ring)) {
1327 /* This TX ring is full. */ 1317 /* This TX ring is full. */
1328 ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); 1318 ieee80211_stop_queue(dev->wl->hw, ctl->queue);
1329 ring->stopped = 1; 1319 ring->stopped = 1;
1330 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1320 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1331 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1321 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1404,7 +1394,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1404 dev->stats.last_tx = jiffies; 1394 dev->stats.last_tx = jiffies;
1405 if (ring->stopped) { 1395 if (ring->stopped) {
1406 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); 1396 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
1407 ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); 1397 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1408 ring->stopped = 0; 1398 ring->stopped = 0;
1409 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1399 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1410 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); 1400 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
@@ -1425,7 +1415,7 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
1425 1415
1426 for (i = 0; i < nr_queues; i++) { 1416 for (i = 0; i < nr_queues; i++) {
1427 data = &(stats->data[i]); 1417 data = &(stats->data[i]);
1428 ring = priority_to_txring(dev, i); 1418 ring = select_ring_by_priority(dev, i);
1429 1419
1430 spin_lock_irqsave(&ring->lock, flags); 1420 spin_lock_irqsave(&ring->lock, flags);
1431 data->len = ring->used_slots / SLOTS_PER_PACKET; 1421 data->len = ring->used_slots / SLOTS_PER_PACKET;
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index c0d6b69e6501..9336286d97a7 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -245,6 +245,9 @@ struct b43_dmaring {
245 enum b43_dmatype type; 245 enum b43_dmatype type;
246 /* Boolean. Is this ring stopped at ieee80211 level? */ 246 /* Boolean. Is this ring stopped at ieee80211 level? */
247 bool stopped; 247 bool stopped;
248 /* The QOS priority assigned to this ring. Only used for TX rings.
249 * This is the mac80211 "queue" value. */
250 u8 queue_prio;
248 /* Lock, only used for TX. */ 251 /* Lock, only used for TX. */
249 spinlock_t lock; 252 spinlock_t lock;
250 struct b43_wldev *dev; 253 struct b43_wldev *dev;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c93b62fb5f65..dbacb58d9527 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -78,6 +78,11 @@ static int modparam_nohwcrypt;
78module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 78module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
79MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 79MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
80 80
81int b43_modparam_qos = 1;
82module_param_named(qos, b43_modparam_qos, int, 0444);
83MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
84
85
81static const struct ssb_device_id b43_ssb_tbl[] = { 86static const struct ssb_device_id b43_ssb_tbl[] = {
82 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), 87 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
83 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), 88 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
@@ -2708,10 +2713,178 @@ out:
2708 return NETDEV_TX_OK; 2713 return NETDEV_TX_OK;
2709} 2714}
2710 2715
2716/* Locking: wl->irq_lock */
2717static void b43_qos_params_upload(struct b43_wldev *dev,
2718 const struct ieee80211_tx_queue_params *p,
2719 u16 shm_offset)
2720{
2721 u16 params[B43_NR_QOSPARAMS];
2722 int cw_min, cw_max, aifs, bslots, tmp;
2723 unsigned int i;
2724
2725 const u16 aCWmin = 0x0001;
2726 const u16 aCWmax = 0x03FF;
2727
2728 /* Calculate the default values for the parameters, if needed. */
2729 switch (shm_offset) {
2730 case B43_QOS_VOICE:
2731 aifs = (p->aifs == -1) ? 2 : p->aifs;
2732 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 4 - 1) : p->cw_min;
2733 cw_max = (p->cw_max == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_max;
2734 break;
2735 case B43_QOS_VIDEO:
2736 aifs = (p->aifs == -1) ? 2 : p->aifs;
2737 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_min;
2738 cw_max = (p->cw_max == 0) ? aCWmin : p->cw_max;
2739 break;
2740 case B43_QOS_BESTEFFORT:
2741 aifs = (p->aifs == -1) ? 3 : p->aifs;
2742 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2743 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2744 break;
2745 case B43_QOS_BACKGROUND:
2746 aifs = (p->aifs == -1) ? 7 : p->aifs;
2747 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2748 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2749 break;
2750 default:
2751 B43_WARN_ON(1);
2752 return;
2753 }
2754 if (cw_min <= 0)
2755 cw_min = aCWmin;
2756 if (cw_max <= 0)
2757 cw_max = aCWmin;
2758 bslots = b43_read16(dev, B43_MMIO_RNG) % cw_min;
2759
2760 memset(&params, 0, sizeof(params));
2761
2762 params[B43_QOSPARAM_TXOP] = p->txop * 32;
2763 params[B43_QOSPARAM_CWMIN] = cw_min;
2764 params[B43_QOSPARAM_CWMAX] = cw_max;
2765 params[B43_QOSPARAM_CWCUR] = cw_min;
2766 params[B43_QOSPARAM_AIFS] = aifs;
2767 params[B43_QOSPARAM_BSLOTS] = bslots;
2768 params[B43_QOSPARAM_REGGAP] = bslots + aifs;
2769
2770 for (i = 0; i < ARRAY_SIZE(params); i++) {
2771 if (i == B43_QOSPARAM_STATUS) {
2772 tmp = b43_shm_read16(dev, B43_SHM_SHARED,
2773 shm_offset + (i * 2));
2774 /* Mark the parameters as updated. */
2775 tmp |= 0x100;
2776 b43_shm_write16(dev, B43_SHM_SHARED,
2777 shm_offset + (i * 2),
2778 tmp);
2779 } else {
2780 b43_shm_write16(dev, B43_SHM_SHARED,
2781 shm_offset + (i * 2),
2782 params[i]);
2783 }
2784 }
2785}
2786
2787/* Update the QOS parameters in hardware. */
2788static void b43_qos_update(struct b43_wldev *dev)
2789{
2790 struct b43_wl *wl = dev->wl;
2791 struct b43_qos_params *params;
2792 unsigned long flags;
2793 unsigned int i;
2794
2795 /* Mapping of mac80211 queues to b43 SHM offsets. */
2796 static const u16 qos_shm_offsets[] = {
2797 [0] = B43_QOS_VOICE,
2798 [1] = B43_QOS_VIDEO,
2799 [2] = B43_QOS_BESTEFFORT,
2800 [3] = B43_QOS_BACKGROUND,
2801 };
2802 BUILD_BUG_ON(ARRAY_SIZE(qos_shm_offsets) != ARRAY_SIZE(wl->qos_params));
2803
2804 b43_mac_suspend(dev);
2805 spin_lock_irqsave(&wl->irq_lock, flags);
2806
2807 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2808 params = &(wl->qos_params[i]);
2809 if (params->need_hw_update) {
2810 b43_qos_params_upload(dev, &(params->p),
2811 qos_shm_offsets[i]);
2812 params->need_hw_update = 0;
2813 }
2814 }
2815
2816 spin_unlock_irqrestore(&wl->irq_lock, flags);
2817 b43_mac_enable(dev);
2818}
2819
2820static void b43_qos_clear(struct b43_wl *wl)
2821{
2822 struct b43_qos_params *params;
2823 unsigned int i;
2824
2825 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2826 params = &(wl->qos_params[i]);
2827
2828 memset(&(params->p), 0, sizeof(params->p));
2829 params->p.aifs = -1;
2830 params->need_hw_update = 1;
2831 }
2832}
2833
2834/* Initialize the core's QOS capabilities */
2835static void b43_qos_init(struct b43_wldev *dev)
2836{
2837 struct b43_wl *wl = dev->wl;
2838 unsigned int i;
2839
2840 /* Upload the current QOS parameters. */
2841 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++)
2842 wl->qos_params[i].need_hw_update = 1;
2843 b43_qos_update(dev);
2844
2845 /* Enable QOS support. */
2846 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
2847 b43_write16(dev, B43_MMIO_IFSCTL,
2848 b43_read16(dev, B43_MMIO_IFSCTL)
2849 | B43_MMIO_IFSCTL_USE_EDCF);
2850}
2851
2852static void b43_qos_update_work(struct work_struct *work)
2853{
2854 struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
2855 struct b43_wldev *dev;
2856
2857 mutex_lock(&wl->mutex);
2858 dev = wl->current_dev;
2859 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
2860 b43_qos_update(dev);
2861 mutex_unlock(&wl->mutex);
2862}
2863
2711static int b43_op_conf_tx(struct ieee80211_hw *hw, 2864static int b43_op_conf_tx(struct ieee80211_hw *hw,
2712 int queue, 2865 int _queue,
2713 const struct ieee80211_tx_queue_params *params) 2866 const struct ieee80211_tx_queue_params *params)
2714{ 2867{
2868 struct b43_wl *wl = hw_to_b43_wl(hw);
2869 unsigned long flags;
2870 unsigned int queue = (unsigned int)_queue;
2871 struct b43_qos_params *p;
2872
2873 if (queue >= ARRAY_SIZE(wl->qos_params)) {
2874 /* Queue not available or don't support setting
2875 * params on this queue. Return success to not
2876 * confuse mac80211. */
2877 return 0;
2878 }
2879
2880 spin_lock_irqsave(&wl->irq_lock, flags);
2881 p = &(wl->qos_params[queue]);
2882 memcpy(&(p->p), params, sizeof(p->p));
2883 p->need_hw_update = 1;
2884 spin_unlock_irqrestore(&wl->irq_lock, flags);
2885
2886 queue_work(hw->workqueue, &wl->qos_update_work);
2887
2715 return 0; 2888 return 0;
2716} 2889}
2717 2890
@@ -3732,6 +3905,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
3732 memset(wl->mac_addr, 0, ETH_ALEN); 3905 memset(wl->mac_addr, 0, ETH_ALEN);
3733 wl->filter_flags = 0; 3906 wl->filter_flags = 0;
3734 wl->radiotap_enabled = 0; 3907 wl->radiotap_enabled = 0;
3908 b43_qos_clear(wl);
3735 3909
3736 /* First register RFkill. 3910 /* First register RFkill.
3737 * LEDs that are registered later depend on it. */ 3911 * LEDs that are registered later depend on it. */
@@ -3773,6 +3947,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
3773 struct b43_wldev *dev = wl->current_dev; 3947 struct b43_wldev *dev = wl->current_dev;
3774 3948
3775 b43_rfkill_exit(dev); 3949 b43_rfkill_exit(dev);
3950 cancel_work_sync(&(wl->qos_update_work));
3776 3951
3777 mutex_lock(&wl->mutex); 3952 mutex_lock(&wl->mutex);
3778 if (b43_status(dev) >= B43_STAT_STARTED) 3953 if (b43_status(dev) >= B43_STAT_STARTED)
@@ -4133,7 +4308,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4133 hw->max_signal = 100; 4308 hw->max_signal = 100;
4134 hw->max_rssi = -110; 4309 hw->max_rssi = -110;
4135 hw->max_noise = -110; 4310 hw->max_noise = -110;
4136 hw->queues = 1; /* FIXME: hardware has more queues */ 4311 hw->queues = b43_modparam_qos ? 4 : 1;
4137 SET_IEEE80211_DEV(hw, dev->dev); 4312 SET_IEEE80211_DEV(hw, dev->dev);
4138 if (is_valid_ether_addr(sprom->et1mac)) 4313 if (is_valid_ether_addr(sprom->et1mac))
4139 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); 4314 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
@@ -4149,6 +4324,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4149 spin_lock_init(&wl->shm_lock); 4324 spin_lock_init(&wl->shm_lock);
4150 mutex_init(&wl->mutex); 4325 mutex_init(&wl->mutex);
4151 INIT_LIST_HEAD(&wl->devlist); 4326 INIT_LIST_HEAD(&wl->devlist);
4327 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4152 4328
4153 ssb_set_devtypedata(dev, wl); 4329 ssb_set_devtypedata(dev, wl);
4154 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); 4330 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 24a79f5d6ff5..1197975f9207 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -38,6 +38,10 @@
38/* Magic helper macro to pad structures. Ignore those above. It's magic. */ 38/* Magic helper macro to pad structures. Ignore those above. It's magic. */
39#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) 39#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
40 40
41
42extern int b43_modparam_qos;
43
44
41/* Lightweight function to convert a frequency (in Mhz) to a channel number. */ 45/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
42static inline u8 b43_freq_to_channel_5ghz(int freq) 46static inline u8 b43_freq_to_channel_5ghz(int freq)
43{ 47{
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 187c11bee0f1..ec10a8e182f9 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -705,30 +705,3 @@ void b43_tx_resume(struct b43_wldev *dev)
705{ 705{
706 b43_dma_tx_resume(dev); 706 b43_dma_tx_resume(dev);
707} 707}
708
709#if 0
710static void upload_qos_parms(struct b43_wldev *dev,
711 const u16 * parms, u16 offset)
712{
713 int i;
714
715 for (i = 0; i < B43_NR_QOSPARMS; i++) {
716 b43_shm_write16(dev, B43_SHM_SHARED,
717 offset + (i * 2), parms[i]);
718 }
719}
720#endif
721
722/* Initialize the QoS parameters */
723void b43_qos_init(struct b43_wldev *dev)
724{
725 /* FIXME: This function must probably be called from the mac80211
726 * config callback. */
727 return;
728
729 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
730 //FIXME kill magic
731 b43_write16(dev, 0x688, b43_read16(dev, 0x688) | 0x4);
732
733 /*TODO: We might need some stack support here to get the values. */
734}
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 41765039552b..bf58a8a85258 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -302,18 +302,6 @@ void b43_handle_hwtxstatus(struct b43_wldev *dev,
302void b43_tx_suspend(struct b43_wldev *dev); 302void b43_tx_suspend(struct b43_wldev *dev);
303void b43_tx_resume(struct b43_wldev *dev); 303void b43_tx_resume(struct b43_wldev *dev);
304 304
305#define B43_NR_QOSPARMS 22
306enum {
307 B43_QOSPARM_TXOP = 0,
308 B43_QOSPARM_CWMIN,
309 B43_QOSPARM_CWMAX,
310 B43_QOSPARM_CWCUR,
311 B43_QOSPARM_AIFS,
312 B43_QOSPARM_BSLOTS,
313 B43_QOSPARM_REGGAP,
314 B43_QOSPARM_STATUS,
315};
316void b43_qos_init(struct b43_wldev *dev);
317 305
318/* Helper functions for converting the key-table index from "firmware-format" 306/* Helper functions for converting the key-table index from "firmware-format"
319 * to "raw-format" and back. The firmware API changed for this at some revision. 307 * to "raw-format" and back. The firmware API changed for this at some revision.