aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/dma.c
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/dma.c
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/dma.c')
-rw-r--r--drivers/net/wireless/b43/dma.c90
1 files changed, 40 insertions, 50 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3dfb28a34be..c8ead465497 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;