aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/b43.h53
-rw-r--r--drivers/net/wireless/b43/dma.c386
-rw-r--r--drivers/net/wireless/b43/dma.h11
-rw-r--r--drivers/net/wireless/b43/main.c196
-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, 427 insertions, 262 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 33459d61a717..d40be1568517 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 */
@@ -587,15 +589,13 @@ struct b43_phy {
587 589
588/* Data structures for DMA transmission, per 80211 core. */ 590/* Data structures for DMA transmission, per 80211 core. */
589struct b43_dma { 591struct b43_dma {
590 struct b43_dmaring *tx_ring0; 592 struct b43_dmaring *tx_ring_AC_BK; /* Background */
591 struct b43_dmaring *tx_ring1; 593 struct b43_dmaring *tx_ring_AC_BE; /* Best Effort */
592 struct b43_dmaring *tx_ring2; 594 struct b43_dmaring *tx_ring_AC_VI; /* Video */
593 struct b43_dmaring *tx_ring3; 595 struct b43_dmaring *tx_ring_AC_VO; /* Voice */
594 struct b43_dmaring *tx_ring4; 596 struct b43_dmaring *tx_ring_mcast; /* Multicast */
595 struct b43_dmaring *tx_ring5; 597
596 598 struct b43_dmaring *rx_ring;
597 struct b43_dmaring *rx_ring0;
598 struct b43_dmaring *rx_ring3; /* only available on core.rev < 5 */
599}; 599};
600 600
601/* Context information for a noise calculation (Link Quality). */ 601/* Context information for a noise calculation (Link Quality). */
@@ -621,6 +621,35 @@ struct b43_key {
621 u8 algorithm; 621 u8 algorithm;
622}; 622};
623 623
624/* SHM offsets to the QOS data structures for the 4 different queues. */
625#define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \
626 (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
627#define B43_QOS_BACKGROUND B43_QOS_PARAMS(0)
628#define B43_QOS_BESTEFFORT B43_QOS_PARAMS(1)
629#define B43_QOS_VIDEO B43_QOS_PARAMS(2)
630#define B43_QOS_VOICE B43_QOS_PARAMS(3)
631
632/* QOS parameter hardware data structure offsets. */
633#define B43_NR_QOSPARAMS 22
634enum {
635 B43_QOSPARAM_TXOP = 0,
636 B43_QOSPARAM_CWMIN,
637 B43_QOSPARAM_CWMAX,
638 B43_QOSPARAM_CWCUR,
639 B43_QOSPARAM_AIFS,
640 B43_QOSPARAM_BSLOTS,
641 B43_QOSPARAM_REGGAP,
642 B43_QOSPARAM_STATUS,
643};
644
645/* QOS parameters for a queue. */
646struct b43_qos_params {
647 /* The QOS parameters */
648 struct ieee80211_tx_queue_params p;
649 /* Does this need to get uploaded to hardware? */
650 bool need_hw_update;
651};
652
624struct b43_wldev; 653struct b43_wldev;
625 654
626/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ 655/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
@@ -673,6 +702,12 @@ struct b43_wl {
673 struct sk_buff *current_beacon; 702 struct sk_buff *current_beacon;
674 bool beacon0_uploaded; 703 bool beacon0_uploaded;
675 bool beacon1_uploaded; 704 bool beacon1_uploaded;
705
706 /* The current QOS parameters for the 4 queues.
707 * This is protected by the irq_lock. */
708 struct b43_qos_params qos_params[4];
709 /* Workqueue for updating QOS parameters in hardware. */
710 struct work_struct qos_update_work;
676}; 711};
677 712
678/* In-memory representation of a cached microcode file. */ 713/* 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..663aed4e9e05 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/etherdevice.h> 40#include <linux/etherdevice.h>
41#include <asm/div64.h>
41 42
42 43
43/* 32bit DMA ops. */ 44/* 32bit DMA ops. */
@@ -291,52 +292,6 @@ static inline int request_slot(struct b43_dmaring *ring)
291 return slot; 292 return slot;
292} 293}
293 294
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) 295static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx)
341{ 296{
342 static const u16 map64[] = { 297 static const u16 map64[] = {
@@ -924,16 +879,52 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
924 goto out; 879 goto out;
925} 880}
926 881
882#define divide(a, b) ({ \
883 typeof(a) __a = a; \
884 do_div(__a, b); \
885 __a; \
886 })
887
888#define modulo(a, b) ({ \
889 typeof(a) __a = a; \
890 do_div(__a, b); \
891 })
892
927/* Main cleanup function. */ 893/* Main cleanup function. */
928static void b43_destroy_dmaring(struct b43_dmaring *ring) 894static void b43_destroy_dmaring(struct b43_dmaring *ring,
895 const char *ringname)
929{ 896{
930 if (!ring) 897 if (!ring)
931 return; 898 return;
932 899
933 b43dbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots: %d/%d\n", 900#ifdef CONFIG_B43_DEBUG
934 (unsigned int)(ring->type), 901 {
935 ring->mmio_base, 902 /* Print some statistics. */
936 (ring->tx) ? "TX" : "RX", ring->max_used_slots, ring->nr_slots); 903 u64 failed_packets = ring->nr_failed_tx_packets;
904 u64 succeed_packets = ring->nr_succeed_tx_packets;
905 u64 nr_packets = failed_packets + succeed_packets;
906 u64 permille_failed = 0, average_tries = 0;
907
908 if (nr_packets)
909 permille_failed = divide(failed_packets * 1000, nr_packets);
910 if (nr_packets)
911 average_tries = divide(ring->nr_total_packet_tries * 100, nr_packets);
912
913 b43dbg(ring->dev->wl, "DMA-%u %s: "
914 "Used slots %d/%d, Failed frames %llu/%llu = %llu.%01llu%%, "
915 "Average tries %llu.%02llu\n",
916 (unsigned int)(ring->type), ringname,
917 ring->max_used_slots,
918 ring->nr_slots,
919 (unsigned long long)failed_packets,
920 (unsigned long long)nr_packets,
921 (unsigned long long)divide(permille_failed, 10),
922 (unsigned long long)modulo(permille_failed, 10),
923 (unsigned long long)divide(average_tries, 100),
924 (unsigned long long)modulo(average_tries, 100));
925 }
926#endif /* DEBUG */
927
937 /* Device IRQs are disabled prior entering this function, 928 /* Device IRQs are disabled prior entering this function,
938 * so no need to take care of concurrency with rx handler stuff. 929 * so no need to take care of concurrency with rx handler stuff.
939 */ 930 */
@@ -946,33 +937,26 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring)
946 kfree(ring); 937 kfree(ring);
947} 938}
948 939
940#define destroy_ring(dma, ring) do { \
941 b43_destroy_dmaring((dma)->ring, __stringify(ring)); \
942 (dma)->ring = NULL; \
943 } while (0)
944
949void b43_dma_free(struct b43_wldev *dev) 945void b43_dma_free(struct b43_wldev *dev)
950{ 946{
951 struct b43_dma *dma = &dev->dma; 947 struct b43_dma *dma = &dev->dma;
952 948
953 b43_destroy_dmaring(dma->rx_ring3); 949 destroy_ring(dma, rx_ring);
954 dma->rx_ring3 = NULL; 950 destroy_ring(dma, tx_ring_AC_BK);
955 b43_destroy_dmaring(dma->rx_ring0); 951 destroy_ring(dma, tx_ring_AC_BE);
956 dma->rx_ring0 = NULL; 952 destroy_ring(dma, tx_ring_AC_VI);
957 953 destroy_ring(dma, tx_ring_AC_VO);
958 b43_destroy_dmaring(dma->tx_ring5); 954 destroy_ring(dma, tx_ring_mcast);
959 dma->tx_ring5 = NULL;
960 b43_destroy_dmaring(dma->tx_ring4);
961 dma->tx_ring4 = NULL;
962 b43_destroy_dmaring(dma->tx_ring3);
963 dma->tx_ring3 = NULL;
964 b43_destroy_dmaring(dma->tx_ring2);
965 dma->tx_ring2 = NULL;
966 b43_destroy_dmaring(dma->tx_ring1);
967 dma->tx_ring1 = NULL;
968 b43_destroy_dmaring(dma->tx_ring0);
969 dma->tx_ring0 = NULL;
970} 955}
971 956
972int b43_dma_init(struct b43_wldev *dev) 957int b43_dma_init(struct b43_wldev *dev)
973{ 958{
974 struct b43_dma *dma = &dev->dma; 959 struct b43_dma *dma = &dev->dma;
975 struct b43_dmaring *ring;
976 int err; 960 int err;
977 u64 dmamask; 961 u64 dmamask;
978 enum b43_dmatype type; 962 enum b43_dmatype type;
@@ -1002,83 +986,57 @@ int b43_dma_init(struct b43_wldev *dev)
1002 986
1003 err = -ENOMEM; 987 err = -ENOMEM;
1004 /* setup TX DMA channels. */ 988 /* setup TX DMA channels. */
1005 ring = b43_setup_dmaring(dev, 0, 1, type); 989 dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
1006 if (!ring) 990 if (!dma->tx_ring_AC_BK)
1007 goto out; 991 goto out;
1008 dma->tx_ring0 = ring;
1009 992
1010 ring = b43_setup_dmaring(dev, 1, 1, type); 993 dma->tx_ring_AC_BE = b43_setup_dmaring(dev, 1, 1, type);
1011 if (!ring) 994 if (!dma->tx_ring_AC_BE)
1012 goto err_destroy_tx0; 995 goto err_destroy_bk;
1013 dma->tx_ring1 = ring;
1014 996
1015 ring = b43_setup_dmaring(dev, 2, 1, type); 997 dma->tx_ring_AC_VI = b43_setup_dmaring(dev, 2, 1, type);
1016 if (!ring) 998 if (!dma->tx_ring_AC_VI)
1017 goto err_destroy_tx1; 999 goto err_destroy_be;
1018 dma->tx_ring2 = ring;
1019 1000
1020 ring = b43_setup_dmaring(dev, 3, 1, type); 1001 dma->tx_ring_AC_VO = b43_setup_dmaring(dev, 3, 1, type);
1021 if (!ring) 1002 if (!dma->tx_ring_AC_VO)
1022 goto err_destroy_tx2; 1003 goto err_destroy_vi;
1023 dma->tx_ring3 = ring;
1024 1004
1025 ring = b43_setup_dmaring(dev, 4, 1, type); 1005 dma->tx_ring_mcast = b43_setup_dmaring(dev, 4, 1, type);
1026 if (!ring) 1006 if (!dma->tx_ring_mcast)
1027 goto err_destroy_tx3; 1007 goto err_destroy_vo;
1028 dma->tx_ring4 = ring;
1029 1008
1030 ring = b43_setup_dmaring(dev, 5, 1, type); 1009 /* setup RX DMA channel. */
1031 if (!ring) 1010 dma->rx_ring = b43_setup_dmaring(dev, 0, 0, type);
1032 goto err_destroy_tx4; 1011 if (!dma->rx_ring)
1033 dma->tx_ring5 = ring; 1012 goto err_destroy_mcast;
1034 1013
1035 /* setup RX DMA channels. */ 1014 /* No support for the TX status DMA ring. */
1036 ring = b43_setup_dmaring(dev, 0, 0, type); 1015 B43_WARN_ON(dev->dev->id.revision < 5);
1037 if (!ring)
1038 goto err_destroy_tx5;
1039 dma->rx_ring0 = ring;
1040
1041 if (dev->dev->id.revision < 5) {
1042 ring = b43_setup_dmaring(dev, 3, 0, type);
1043 if (!ring)
1044 goto err_destroy_rx0;
1045 dma->rx_ring3 = ring;
1046 }
1047 1016
1048 b43dbg(dev->wl, "%u-bit DMA initialized\n", 1017 b43dbg(dev->wl, "%u-bit DMA initialized\n",
1049 (unsigned int)type); 1018 (unsigned int)type);
1050 err = 0; 1019 err = 0;
1051 out: 1020out:
1052 return err; 1021 return err;
1053 1022
1054 err_destroy_rx0: 1023err_destroy_mcast:
1055 b43_destroy_dmaring(dma->rx_ring0); 1024 destroy_ring(dma, tx_ring_mcast);
1056 dma->rx_ring0 = NULL; 1025err_destroy_vo:
1057 err_destroy_tx5: 1026 destroy_ring(dma, tx_ring_AC_VO);
1058 b43_destroy_dmaring(dma->tx_ring5); 1027err_destroy_vi:
1059 dma->tx_ring5 = NULL; 1028 destroy_ring(dma, tx_ring_AC_VI);
1060 err_destroy_tx4: 1029err_destroy_be:
1061 b43_destroy_dmaring(dma->tx_ring4); 1030 destroy_ring(dma, tx_ring_AC_BE);
1062 dma->tx_ring4 = NULL; 1031err_destroy_bk:
1063 err_destroy_tx3: 1032 destroy_ring(dma, tx_ring_AC_BK);
1064 b43_destroy_dmaring(dma->tx_ring3); 1033 return err;
1065 dma->tx_ring3 = NULL;
1066 err_destroy_tx2:
1067 b43_destroy_dmaring(dma->tx_ring2);
1068 dma->tx_ring2 = NULL;
1069 err_destroy_tx1:
1070 b43_destroy_dmaring(dma->tx_ring1);
1071 dma->tx_ring1 = NULL;
1072 err_destroy_tx0:
1073 b43_destroy_dmaring(dma->tx_ring0);
1074 dma->tx_ring0 = NULL;
1075 goto out;
1076} 1034}
1077 1035
1078/* Generate a cookie for the TX header. */ 1036/* Generate a cookie for the TX header. */
1079static u16 generate_cookie(struct b43_dmaring *ring, int slot) 1037static u16 generate_cookie(struct b43_dmaring *ring, int slot)
1080{ 1038{
1081 u16 cookie = 0x1000; 1039 u16 cookie;
1082 1040
1083 /* Use the upper 4 bits of the cookie as 1041 /* Use the upper 4 bits of the cookie as
1084 * DMA controller ID and store the slot number 1042 * DMA controller ID and store the slot number
@@ -1088,30 +1046,9 @@ static u16 generate_cookie(struct b43_dmaring *ring, int slot)
1088 * It can also not be 0xFFFF because that is special 1046 * It can also not be 0xFFFF because that is special
1089 * for multicast frames. 1047 * for multicast frames.
1090 */ 1048 */
1091 switch (ring->index) { 1049 cookie = (((u16)ring->index + 1) << 12);
1092 case 0:
1093 cookie = 0x1000;
1094 break;
1095 case 1:
1096 cookie = 0x2000;
1097 break;
1098 case 2:
1099 cookie = 0x3000;
1100 break;
1101 case 3:
1102 cookie = 0x4000;
1103 break;
1104 case 4:
1105 cookie = 0x5000;
1106 break;
1107 case 5:
1108 cookie = 0x6000;
1109 break;
1110 default:
1111 B43_WARN_ON(1);
1112 }
1113 B43_WARN_ON(slot & ~0x0FFF); 1050 B43_WARN_ON(slot & ~0x0FFF);
1114 cookie |= (u16) slot; 1051 cookie |= (u16)slot;
1115 1052
1116 return cookie; 1053 return cookie;
1117} 1054}
@@ -1125,22 +1062,19 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
1125 1062
1126 switch (cookie & 0xF000) { 1063 switch (cookie & 0xF000) {
1127 case 0x1000: 1064 case 0x1000:
1128 ring = dma->tx_ring0; 1065 ring = dma->tx_ring_AC_BK;
1129 break; 1066 break;
1130 case 0x2000: 1067 case 0x2000:
1131 ring = dma->tx_ring1; 1068 ring = dma->tx_ring_AC_BE;
1132 break; 1069 break;
1133 case 0x3000: 1070 case 0x3000:
1134 ring = dma->tx_ring2; 1071 ring = dma->tx_ring_AC_VI;
1135 break; 1072 break;
1136 case 0x4000: 1073 case 0x4000:
1137 ring = dma->tx_ring3; 1074 ring = dma->tx_ring_AC_VO;
1138 break; 1075 break;
1139 case 0x5000: 1076 case 0x5000:
1140 ring = dma->tx_ring4; 1077 ring = dma->tx_ring_mcast;
1141 break;
1142 case 0x6000:
1143 ring = dma->tx_ring5;
1144 break; 1078 break;
1145 default: 1079 default:
1146 B43_WARN_ON(1); 1080 B43_WARN_ON(1);
@@ -1272,6 +1206,37 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
1272 return 0; 1206 return 0;
1273} 1207}
1274 1208
1209/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
1210static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
1211 u8 queue_prio)
1212{
1213 struct b43_dmaring *ring;
1214
1215 if (b43_modparam_qos) {
1216 /* 0 = highest priority */
1217 switch (queue_prio) {
1218 default:
1219 B43_WARN_ON(1);
1220 /* fallthrough */
1221 case 0:
1222 ring = dev->dma.tx_ring_AC_VO;
1223 break;
1224 case 1:
1225 ring = dev->dma.tx_ring_AC_VI;
1226 break;
1227 case 2:
1228 ring = dev->dma.tx_ring_AC_BE;
1229 break;
1230 case 3:
1231 ring = dev->dma.tx_ring_AC_BK;
1232 break;
1233 }
1234 } else
1235 ring = dev->dma.tx_ring_AC_BE;
1236
1237 return ring;
1238}
1239
1275int b43_dma_tx(struct b43_wldev *dev, 1240int b43_dma_tx(struct b43_wldev *dev,
1276 struct sk_buff *skb, struct ieee80211_tx_control *ctl) 1241 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
1277{ 1242{
@@ -1288,13 +1253,13 @@ int b43_dma_tx(struct b43_wldev *dev,
1288 hdr = (struct ieee80211_hdr *)skb->data; 1253 hdr = (struct ieee80211_hdr *)skb->data;
1289 if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) { 1254 if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
1290 /* The multicast ring will be sent after the DTIM */ 1255 /* The multicast ring will be sent after the DTIM */
1291 ring = dev->dma.tx_ring4; 1256 ring = dev->dma.tx_ring_mcast;
1292 /* Set the more-data bit. Ucode will clear it on 1257 /* Set the more-data bit. Ucode will clear it on
1293 * the last frame for us. */ 1258 * the last frame for us. */
1294 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1259 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1295 } else { 1260 } else {
1296 /* Decide by priority where to put this frame. */ 1261 /* Decide by priority where to put this frame. */
1297 ring = priority_to_txring(dev, ctl->queue); 1262 ring = select_ring_by_priority(dev, ctl->queue);
1298 } 1263 }
1299 1264
1300 spin_lock_irqsave(&ring->lock, flags); 1265 spin_lock_irqsave(&ring->lock, flags);
@@ -1309,6 +1274,11 @@ int b43_dma_tx(struct b43_wldev *dev,
1309 * That would be a mac80211 bug. */ 1274 * That would be a mac80211 bug. */
1310 B43_WARN_ON(ring->stopped); 1275 B43_WARN_ON(ring->stopped);
1311 1276
1277 /* Assign the queue number to the ring (if not already done before)
1278 * so TX status handling can use it. The queue to ring mapping is
1279 * static, so we don't need to store it per frame. */
1280 ring->queue_prio = ctl->queue;
1281
1312 err = dma_tx_fragment(ring, skb, ctl); 1282 err = dma_tx_fragment(ring, skb, ctl);
1313 if (unlikely(err == -ENOKEY)) { 1283 if (unlikely(err == -ENOKEY)) {
1314 /* Drop this packet, as we don't have the encryption key 1284 /* Drop this packet, as we don't have the encryption key
@@ -1325,7 +1295,7 @@ int b43_dma_tx(struct b43_wldev *dev,
1325 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1295 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1326 should_inject_overflow(ring)) { 1296 should_inject_overflow(ring)) {
1327 /* This TX ring is full. */ 1297 /* This TX ring is full. */
1328 ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); 1298 ieee80211_stop_queue(dev->wl->hw, ctl->queue);
1329 ring->stopped = 1; 1299 ring->stopped = 1;
1330 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1300 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1331 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1301 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1337,6 +1307,38 @@ out_unlock:
1337 return err; 1307 return err;
1338} 1308}
1339 1309
1310static void b43_fill_txstatus_report(struct b43_dmaring *ring,
1311 struct ieee80211_tx_status *report,
1312 const struct b43_txstatus *status)
1313{
1314 bool frame_failed = 0;
1315
1316 if (status->acked) {
1317 /* The frame was ACKed. */
1318 report->flags |= IEEE80211_TX_STATUS_ACK;
1319 } else {
1320 /* The frame was not ACKed... */
1321 if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
1322 /* ...but we expected an ACK. */
1323 frame_failed = 1;
1324 report->excessive_retries = 1;
1325 }
1326 }
1327 if (status->frame_count == 0) {
1328 /* The frame was not transmitted at all. */
1329 report->retry_count = 0;
1330 } else {
1331 report->retry_count = status->frame_count - 1;
1332#ifdef CONFIG_B43_DEBUG
1333 if (frame_failed)
1334 ring->nr_failed_tx_packets++;
1335 else
1336 ring->nr_succeed_tx_packets++;
1337 ring->nr_total_packet_tries += status->frame_count;
1338#endif /* DEBUG */
1339 }
1340}
1341
1340void b43_dma_handle_txstatus(struct b43_wldev *dev, 1342void b43_dma_handle_txstatus(struct b43_wldev *dev,
1341 const struct b43_txstatus *status) 1343 const struct b43_txstatus *status)
1342{ 1344{
@@ -1371,18 +1373,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1371 * status of the transmission. 1373 * status of the transmission.
1372 * Some fields of txstat are already filled in dma_tx(). 1374 * Some fields of txstat are already filled in dma_tx().
1373 */ 1375 */
1374 if (status->acked) { 1376 b43_fill_txstatus_report(ring, &(meta->txstat), status);
1375 meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
1376 } else {
1377 if (!(meta->txstat.control.flags
1378 & IEEE80211_TXCTL_NO_ACK))
1379 meta->txstat.excessive_retries = 1;
1380 }
1381 if (status->frame_count == 0) {
1382 /* The frame was not transmitted at all. */
1383 meta->txstat.retry_count = 0;
1384 } else
1385 meta->txstat.retry_count = status->frame_count - 1;
1386 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb, 1377 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
1387 &(meta->txstat)); 1378 &(meta->txstat));
1388 /* skb is freed by ieee80211_tx_status_irqsafe() */ 1379 /* skb is freed by ieee80211_tx_status_irqsafe() */
@@ -1404,7 +1395,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1404 dev->stats.last_tx = jiffies; 1395 dev->stats.last_tx = jiffies;
1405 if (ring->stopped) { 1396 if (ring->stopped) {
1406 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); 1397 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
1407 ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); 1398 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1408 ring->stopped = 0; 1399 ring->stopped = 0;
1409 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1400 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1410 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); 1401 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
@@ -1425,7 +1416,7 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
1425 1416
1426 for (i = 0; i < nr_queues; i++) { 1417 for (i = 0; i < nr_queues; i++) {
1427 data = &(stats->data[i]); 1418 data = &(stats->data[i]);
1428 ring = priority_to_txring(dev, i); 1419 ring = select_ring_by_priority(dev, i);
1429 1420
1430 spin_lock_irqsave(&ring->lock, flags); 1421 spin_lock_irqsave(&ring->lock, flags);
1431 data->len = ring->used_slots / SLOTS_PER_PACKET; 1422 data->len = ring->used_slots / SLOTS_PER_PACKET;
@@ -1451,25 +1442,6 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
1451 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); 1442 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1452 skb = meta->skb; 1443 skb = meta->skb;
1453 1444
1454 if (ring->index == 3) {
1455 /* We received an xmit status. */
1456 struct b43_hwtxstatus *hw = (struct b43_hwtxstatus *)skb->data;
1457 int i = 0;
1458
1459 while (hw->cookie == 0) {
1460 if (i > 100)
1461 break;
1462 i++;
1463 udelay(2);
1464 barrier();
1465 }
1466 b43_handle_hwtxstatus(ring->dev, hw);
1467 /* recycle the descriptor buffer. */
1468 sync_descbuffer_for_device(ring, meta->dmaaddr,
1469 ring->rx_buffersize);
1470
1471 return;
1472 }
1473 rxhdr = (struct b43_rxhdr_fw4 *)skb->data; 1445 rxhdr = (struct b43_rxhdr_fw4 *)skb->data;
1474 len = le16_to_cpu(rxhdr->frame_len); 1446 len = le16_to_cpu(rxhdr->frame_len);
1475 if (len == 0) { 1447 if (len == 0) {
@@ -1526,7 +1498,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
1526 skb_pull(skb, ring->frameoffset); 1498 skb_pull(skb, ring->frameoffset);
1527 1499
1528 b43_rx(ring->dev, skb, rxhdr); 1500 b43_rx(ring->dev, skb, rxhdr);
1529 drop: 1501drop:
1530 return; 1502 return;
1531} 1503}
1532 1504
@@ -1572,21 +1544,19 @@ static void b43_dma_tx_resume_ring(struct b43_dmaring *ring)
1572void b43_dma_tx_suspend(struct b43_wldev *dev) 1544void b43_dma_tx_suspend(struct b43_wldev *dev)
1573{ 1545{
1574 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); 1546 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
1575 b43_dma_tx_suspend_ring(dev->dma.tx_ring0); 1547 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BK);
1576 b43_dma_tx_suspend_ring(dev->dma.tx_ring1); 1548 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BE);
1577 b43_dma_tx_suspend_ring(dev->dma.tx_ring2); 1549 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VI);
1578 b43_dma_tx_suspend_ring(dev->dma.tx_ring3); 1550 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VO);
1579 b43_dma_tx_suspend_ring(dev->dma.tx_ring4); 1551 b43_dma_tx_suspend_ring(dev->dma.tx_ring_mcast);
1580 b43_dma_tx_suspend_ring(dev->dma.tx_ring5);
1581} 1552}
1582 1553
1583void b43_dma_tx_resume(struct b43_wldev *dev) 1554void b43_dma_tx_resume(struct b43_wldev *dev)
1584{ 1555{
1585 b43_dma_tx_resume_ring(dev->dma.tx_ring5); 1556 b43_dma_tx_resume_ring(dev->dma.tx_ring_mcast);
1586 b43_dma_tx_resume_ring(dev->dma.tx_ring4); 1557 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VO);
1587 b43_dma_tx_resume_ring(dev->dma.tx_ring3); 1558 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VI);
1588 b43_dma_tx_resume_ring(dev->dma.tx_ring2); 1559 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BE);
1589 b43_dma_tx_resume_ring(dev->dma.tx_ring1); 1560 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BK);
1590 b43_dma_tx_resume_ring(dev->dma.tx_ring0);
1591 b43_power_saving_ctl_bits(dev, 0); 1561 b43_power_saving_ctl_bits(dev, 0);
1592} 1562}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index c0d6b69e6501..ea27085dec0e 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;
@@ -253,7 +256,13 @@ struct b43_dmaring {
253 int max_used_slots; 256 int max_used_slots;
254 /* Last time we injected a ring overflow. */ 257 /* Last time we injected a ring overflow. */
255 unsigned long last_injected_overflow; 258 unsigned long last_injected_overflow;
256#endif /* CONFIG_B43_DEBUG */ 259 /* Statistics: Number of successfully transmitted packets */
260 u64 nr_succeed_tx_packets;
261 /* Statistics: Number of failed TX packets */
262 u64 nr_failed_tx_packets;
263 /* Statistics: Total number of TX plus all retries. */
264 u64 nr_total_packet_tries;
265#endif /* CONFIG_B43_DEBUG */
257}; 266};
258 267
259static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset) 268static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index f745308faaad..694e29570e5d 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),
@@ -1589,11 +1594,10 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1589 1594
1590 /* Check the DMA reason registers for received data. */ 1595 /* Check the DMA reason registers for received data. */
1591 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) 1596 if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
1592 b43_dma_rx(dev->dma.rx_ring0); 1597 b43_dma_rx(dev->dma.rx_ring);
1593 if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
1594 b43_dma_rx(dev->dma.rx_ring3);
1595 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE); 1598 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
1596 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE); 1599 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
1600 B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
1597 B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE); 1601 B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
1598 B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE); 1602 B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
1599 1603
@@ -2708,10 +2712,178 @@ out:
2708 return NETDEV_TX_OK; 2712 return NETDEV_TX_OK;
2709} 2713}
2710 2714
2715/* Locking: wl->irq_lock */
2716static void b43_qos_params_upload(struct b43_wldev *dev,
2717 const struct ieee80211_tx_queue_params *p,
2718 u16 shm_offset)
2719{
2720 u16 params[B43_NR_QOSPARAMS];
2721 int cw_min, cw_max, aifs, bslots, tmp;
2722 unsigned int i;
2723
2724 const u16 aCWmin = 0x0001;
2725 const u16 aCWmax = 0x03FF;
2726
2727 /* Calculate the default values for the parameters, if needed. */
2728 switch (shm_offset) {
2729 case B43_QOS_VOICE:
2730 aifs = (p->aifs == -1) ? 2 : p->aifs;
2731 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 4 - 1) : p->cw_min;
2732 cw_max = (p->cw_max == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_max;
2733 break;
2734 case B43_QOS_VIDEO:
2735 aifs = (p->aifs == -1) ? 2 : p->aifs;
2736 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_min;
2737 cw_max = (p->cw_max == 0) ? aCWmin : p->cw_max;
2738 break;
2739 case B43_QOS_BESTEFFORT:
2740 aifs = (p->aifs == -1) ? 3 : p->aifs;
2741 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2742 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2743 break;
2744 case B43_QOS_BACKGROUND:
2745 aifs = (p->aifs == -1) ? 7 : p->aifs;
2746 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2747 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2748 break;
2749 default:
2750 B43_WARN_ON(1);
2751 return;
2752 }
2753 if (cw_min <= 0)
2754 cw_min = aCWmin;
2755 if (cw_max <= 0)
2756 cw_max = aCWmin;
2757 bslots = b43_read16(dev, B43_MMIO_RNG) % cw_min;
2758
2759 memset(&params, 0, sizeof(params));
2760
2761 params[B43_QOSPARAM_TXOP] = p->txop * 32;
2762 params[B43_QOSPARAM_CWMIN] = cw_min;
2763 params[B43_QOSPARAM_CWMAX] = cw_max;
2764 params[B43_QOSPARAM_CWCUR] = cw_min;
2765 params[B43_QOSPARAM_AIFS] = aifs;
2766 params[B43_QOSPARAM_BSLOTS] = bslots;
2767 params[B43_QOSPARAM_REGGAP] = bslots + aifs;
2768
2769 for (i = 0; i < ARRAY_SIZE(params); i++) {
2770 if (i == B43_QOSPARAM_STATUS) {
2771 tmp = b43_shm_read16(dev, B43_SHM_SHARED,
2772 shm_offset + (i * 2));
2773 /* Mark the parameters as updated. */
2774 tmp |= 0x100;
2775 b43_shm_write16(dev, B43_SHM_SHARED,
2776 shm_offset + (i * 2),
2777 tmp);
2778 } else {
2779 b43_shm_write16(dev, B43_SHM_SHARED,
2780 shm_offset + (i * 2),
2781 params[i]);
2782 }
2783 }
2784}
2785
2786/* Update the QOS parameters in hardware. */
2787static void b43_qos_update(struct b43_wldev *dev)
2788{
2789 struct b43_wl *wl = dev->wl;
2790 struct b43_qos_params *params;
2791 unsigned long flags;
2792 unsigned int i;
2793
2794 /* Mapping of mac80211 queues to b43 SHM offsets. */
2795 static const u16 qos_shm_offsets[] = {
2796 [0] = B43_QOS_VOICE,
2797 [1] = B43_QOS_VIDEO,
2798 [2] = B43_QOS_BESTEFFORT,
2799 [3] = B43_QOS_BACKGROUND,
2800 };
2801 BUILD_BUG_ON(ARRAY_SIZE(qos_shm_offsets) != ARRAY_SIZE(wl->qos_params));
2802
2803 b43_mac_suspend(dev);
2804 spin_lock_irqsave(&wl->irq_lock, flags);
2805
2806 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2807 params = &(wl->qos_params[i]);
2808 if (params->need_hw_update) {
2809 b43_qos_params_upload(dev, &(params->p),
2810 qos_shm_offsets[i]);
2811 params->need_hw_update = 0;
2812 }
2813 }
2814
2815 spin_unlock_irqrestore(&wl->irq_lock, flags);
2816 b43_mac_enable(dev);
2817}
2818
2819static void b43_qos_clear(struct b43_wl *wl)
2820{
2821 struct b43_qos_params *params;
2822 unsigned int i;
2823
2824 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2825 params = &(wl->qos_params[i]);
2826
2827 memset(&(params->p), 0, sizeof(params->p));
2828 params->p.aifs = -1;
2829 params->need_hw_update = 1;
2830 }
2831}
2832
2833/* Initialize the core's QOS capabilities */
2834static void b43_qos_init(struct b43_wldev *dev)
2835{
2836 struct b43_wl *wl = dev->wl;
2837 unsigned int i;
2838
2839 /* Upload the current QOS parameters. */
2840 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++)
2841 wl->qos_params[i].need_hw_update = 1;
2842 b43_qos_update(dev);
2843
2844 /* Enable QOS support. */
2845 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
2846 b43_write16(dev, B43_MMIO_IFSCTL,
2847 b43_read16(dev, B43_MMIO_IFSCTL)
2848 | B43_MMIO_IFSCTL_USE_EDCF);
2849}
2850
2851static void b43_qos_update_work(struct work_struct *work)
2852{
2853 struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
2854 struct b43_wldev *dev;
2855
2856 mutex_lock(&wl->mutex);
2857 dev = wl->current_dev;
2858 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
2859 b43_qos_update(dev);
2860 mutex_unlock(&wl->mutex);
2861}
2862
2711static int b43_op_conf_tx(struct ieee80211_hw *hw, 2863static int b43_op_conf_tx(struct ieee80211_hw *hw,
2712 int queue, 2864 int _queue,
2713 const struct ieee80211_tx_queue_params *params) 2865 const struct ieee80211_tx_queue_params *params)
2714{ 2866{
2867 struct b43_wl *wl = hw_to_b43_wl(hw);
2868 unsigned long flags;
2869 unsigned int queue = (unsigned int)_queue;
2870 struct b43_qos_params *p;
2871
2872 if (queue >= ARRAY_SIZE(wl->qos_params)) {
2873 /* Queue not available or don't support setting
2874 * params on this queue. Return success to not
2875 * confuse mac80211. */
2876 return 0;
2877 }
2878
2879 spin_lock_irqsave(&wl->irq_lock, flags);
2880 p = &(wl->qos_params[queue]);
2881 memcpy(&(p->p), params, sizeof(p->p));
2882 p->need_hw_update = 1;
2883 spin_unlock_irqrestore(&wl->irq_lock, flags);
2884
2885 queue_work(hw->workqueue, &wl->qos_update_work);
2886
2715 return 0; 2887 return 0;
2716} 2888}
2717 2889
@@ -3732,6 +3904,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
3732 memset(wl->mac_addr, 0, ETH_ALEN); 3904 memset(wl->mac_addr, 0, ETH_ALEN);
3733 wl->filter_flags = 0; 3905 wl->filter_flags = 0;
3734 wl->radiotap_enabled = 0; 3906 wl->radiotap_enabled = 0;
3907 b43_qos_clear(wl);
3735 3908
3736 /* First register RFkill. 3909 /* First register RFkill.
3737 * LEDs that are registered later depend on it. */ 3910 * LEDs that are registered later depend on it. */
@@ -3773,6 +3946,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
3773 struct b43_wldev *dev = wl->current_dev; 3946 struct b43_wldev *dev = wl->current_dev;
3774 3947
3775 b43_rfkill_exit(dev); 3948 b43_rfkill_exit(dev);
3949 cancel_work_sync(&(wl->qos_update_work));
3776 3950
3777 mutex_lock(&wl->mutex); 3951 mutex_lock(&wl->mutex);
3778 if (b43_status(dev) >= B43_STAT_STARTED) 3952 if (b43_status(dev) >= B43_STAT_STARTED)
@@ -3835,6 +4009,16 @@ static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
3835 return 0; 4009 return 0;
3836} 4010}
3837 4011
4012static void b43_op_sta_notify(struct ieee80211_hw *hw,
4013 struct ieee80211_vif *vif,
4014 enum sta_notify_cmd notify_cmd,
4015 const u8 *addr)
4016{
4017 struct b43_wl *wl = hw_to_b43_wl(hw);
4018
4019 B43_WARN_ON(!vif || wl->vif != vif);
4020}
4021
3838static const struct ieee80211_ops b43_hw_ops = { 4022static const struct ieee80211_ops b43_hw_ops = {
3839 .tx = b43_op_tx, 4023 .tx = b43_op_tx,
3840 .conf_tx = b43_op_conf_tx, 4024 .conf_tx = b43_op_conf_tx,
@@ -3851,6 +4035,7 @@ static const struct ieee80211_ops b43_hw_ops = {
3851 .set_retry_limit = b43_op_set_retry_limit, 4035 .set_retry_limit = b43_op_set_retry_limit,
3852 .set_tim = b43_op_beacon_set_tim, 4036 .set_tim = b43_op_beacon_set_tim,
3853 .beacon_update = b43_op_ibss_beacon_update, 4037 .beacon_update = b43_op_ibss_beacon_update,
4038 .sta_notify = b43_op_sta_notify,
3854}; 4039};
3855 4040
3856/* Hard-reset the chip. Do not call this directly. 4041/* Hard-reset the chip. Do not call this directly.
@@ -4122,7 +4307,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4122 hw->max_signal = 100; 4307 hw->max_signal = 100;
4123 hw->max_rssi = -110; 4308 hw->max_rssi = -110;
4124 hw->max_noise = -110; 4309 hw->max_noise = -110;
4125 hw->queues = 1; /* FIXME: hardware has more queues */ 4310 hw->queues = b43_modparam_qos ? 4 : 1;
4126 SET_IEEE80211_DEV(hw, dev->dev); 4311 SET_IEEE80211_DEV(hw, dev->dev);
4127 if (is_valid_ether_addr(sprom->et1mac)) 4312 if (is_valid_ether_addr(sprom->et1mac))
4128 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); 4313 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
@@ -4138,6 +4323,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4138 spin_lock_init(&wl->shm_lock); 4323 spin_lock_init(&wl->shm_lock);
4139 mutex_init(&wl->mutex); 4324 mutex_init(&wl->mutex);
4140 INIT_LIST_HEAD(&wl->devlist); 4325 INIT_LIST_HEAD(&wl->devlist);
4326 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4141 4327
4142 ssb_set_devtypedata(dev, wl); 4328 ssb_set_devtypedata(dev, wl);
4143 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); 4329 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.