diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-09-05 07:41:37 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-09-14 08:06:51 -0400 |
commit | 04b7b2ff50fc77380c1e711f1d7223734547e41b (patch) | |
tree | 0f048db9f4324e9db134bdbbddc139df9bceffab /net/mac80211/main.c | |
parent | 3a6a0d8ee88d23e7dda28808c2c890c4db50ccb2 (diff) |
mac80211: handle power constraint/country IE better
Currently, mac80211 uses the power constraint IE, and reduces
the regulatory max TX power by it. This can cause issues if
the AP is advertising a large power constraint value matching
a high TX power in its country IE, for example in this case:
...
Country: US Environment: Indoor/Outdoor
...
Channels [157 - 157] @ 30 dBm
...
Power constraint: 13 dB
...
What happened here is that our local regulatory TX power is
15 dBm, and gets reduced by 13 dB so we end up with only
2 dBm effective TX power, which is way too low.
Instead, handle the country IE/power constraint IE combined
and restrict our TX power to the max of the regulatory power
and the maximum power advertised by the AP, in this case
17 dBm (= 30 dBm - 13 dB).
Also print a message when this happens to let the user know
and help us debug issues with it.
Reported-by: Carl A. Cook <CACook@quantum-equities.com>
Tested-by: Carl A. Cook <CACook@quantum-equities.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index bd7529363193..416e85eae2d2 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -150,13 +150,11 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
150 | 150 | ||
151 | if (test_bit(SCAN_SW_SCANNING, &local->scanning) || | 151 | if (test_bit(SCAN_SW_SCANNING, &local->scanning) || |
152 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | 152 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || |
153 | test_bit(SCAN_HW_SCANNING, &local->scanning)) | 153 | test_bit(SCAN_HW_SCANNING, &local->scanning) || |
154 | !local->ap_power_level) | ||
154 | power = chan->max_power; | 155 | power = chan->max_power; |
155 | else | 156 | else |
156 | power = local->power_constr_level ? | 157 | power = min(chan->max_power, local->ap_power_level); |
157 | min(chan->max_power, | ||
158 | (chan->max_reg_power - local->power_constr_level)) : | ||
159 | chan->max_power; | ||
160 | 158 | ||
161 | if (local->user_power_level >= 0) | 159 | if (local->user_power_level >= 0) |
162 | power = min(power, local->user_power_level); | 160 | power = min(power, local->user_power_level); |