diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-03-05 15:18:49 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-07 16:02:59 -0500 |
commit | e6f5b934fba8c44c87c551e066aa7ca6fde2939e (patch) | |
tree | b3fabd1b35a044fe0f50d1ab16ca0dd697c3f59a /drivers/net/wireless/b43/dma.c | |
parent | e5f98f2df903af627a9b9ac55b9352fd54fc431a (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.c | 90 |
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 */ | ||
295 | static 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 */ | ||
326 | static 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 | |||
340 | static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx) | 294 | static 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. */ | ||
1230 | static 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 | |||
1275 | int b43_dma_tx(struct b43_wldev *dev, | 1260 | int 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; |