aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-05 10:23:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-03-16 18:09:27 -0400
commit0eeb59fe2cd84b62f374874a59e62402e13f48b3 (patch)
tree2ee4860541aa3cea93b3bf98aec20f6fbf0b1e66 /net/mac80211
parent2bfc5cb57b55ed2204bca7668e082f7bf485760a (diff)
mac80211: Fix WMM ACM parsing and AC downgrade operation
Incorrect local->wmm_acm bits were set for AC_BK and AC_BE. Fix this and add some comments to make it easier to understand the AC-to-UP(pair) mapping. Set the wmm_acm bits (and show WMM debug) even if the driver does not implement conf_tx() handler. In addition, fix the ACM-based AC downgrade code to not use the highest priority in error cases. We need to break the loop to get the correct AC_BK value (3) instead of returning 0 (which would indicate AC_VO). The comment here was not really very useful either, so let's provide somewhat more helpful description of the situation. Since it is very unlikely that the ACM flag would be set for AC_BK and AC_BE, these bugs are not likely to be seen in real life networks. Anyway, better do these things correctly should someone really use silly AP configuration (and to pass some functionality tests, too). Remove the TODO comment about handling ACM. Downgrading AC is perfectly valid mechanism for ACM. Eventually, we may add support for WMM-AC and send a request for a TS, but anyway, that functionality won't be here at the location of this TODO comment. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mlme.c24
-rw-r--r--net/mac80211/wme.c9
2 files changed, 16 insertions, 17 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 391445c6b892..eeb6da8505c6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -417,9 +417,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
417 417
418 memset(&params, 0, sizeof(params)); 418 memset(&params, 0, sizeof(params));
419 419
420 if (!local->ops->conf_tx)
421 return;
422
423 local->wmm_acm = 0; 420 local->wmm_acm = 0;
424 for (; left >= 4; left -= 4, pos += 4) { 421 for (; left >= 4; left -= 4, pos += 4) {
425 int aci = (pos[0] >> 5) & 0x03; 422 int aci = (pos[0] >> 5) & 0x03;
@@ -427,26 +424,26 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
427 int queue; 424 int queue;
428 425
429 switch (aci) { 426 switch (aci) {
430 case 1: 427 case 1: /* AC_BK */
431 queue = 3; 428 queue = 3;
432 if (acm) 429 if (acm)
433 local->wmm_acm |= BIT(0) | BIT(3); 430 local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
434 break; 431 break;
435 case 2: 432 case 2: /* AC_VI */
436 queue = 1; 433 queue = 1;
437 if (acm) 434 if (acm)
438 local->wmm_acm |= BIT(4) | BIT(5); 435 local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
439 break; 436 break;
440 case 3: 437 case 3: /* AC_VO */
441 queue = 0; 438 queue = 0;
442 if (acm) 439 if (acm)
443 local->wmm_acm |= BIT(6) | BIT(7); 440 local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
444 break; 441 break;
445 case 0: 442 case 0: /* AC_BE */
446 default: 443 default:
447 queue = 2; 444 queue = 2;
448 if (acm) 445 if (acm)
449 local->wmm_acm |= BIT(1) | BIT(2); 446 local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
450 break; 447 break;
451 } 448 }
452 449
@@ -460,9 +457,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
460 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, 457 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
461 params.cw_max, params.txop); 458 params.cw_max, params.txop);
462#endif 459#endif
463 /* TODO: handle ACM (block TX, fallback to next lowest allowed 460 if (local->ops->conf_tx &&
464 * AC for now) */ 461 local->ops->conf_tx(local_to_hw(local), queue, &params)) {
465 if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
466 printk(KERN_DEBUG "%s: failed to set TX queue " 462 printk(KERN_DEBUG "%s: failed to set TX queue "
467 "parameters for queue %d\n", local->mdev->name, queue); 463 "parameters for queue %d\n", local->mdev->name, queue);
468 } 464 }
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 093a4ab7f28b..0b8ad1f4ecdd 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -99,10 +99,13 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
99 /* in case we are a client verify acm is not set for this ac */ 99 /* in case we are a client verify acm is not set for this ac */
100 while (unlikely(local->wmm_acm & BIT(skb->priority))) { 100 while (unlikely(local->wmm_acm & BIT(skb->priority))) {
101 if (wme_downgrade_ac(skb)) { 101 if (wme_downgrade_ac(skb)) {
102 /* The old code would drop the packet in this 102 /*
103 * case. 103 * This should not really happen. The AP has marked all
104 * lower ACs to require admission control which is not
105 * a reasonable configuration. Allow the frame to be
106 * transmitted using AC_BK as a workaround.
104 */ 107 */
105 return 0; 108 break;
106 } 109 }
107 } 110 }
108 111