aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2009-01-09 07:44:15 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:00:15 -0500
commita8302de934b5d1897ff146cd0c7ab87d1417c092 (patch)
tree5a73ad4dd787cc02e14aa8975d267adb5812d8fe /net/mac80211
parent01f8162a854df7f9c259c839ad3c1168ac13b7b8 (diff)
mac80211: Handle power constraint level advertised in 11d+h beacon
This patch uses power constraint level while determining the maximum transmit power, there by it makes sure that any power mitigation requirement for the channel in the current regulatory domain is met. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/main.c10
-rw-r--r--net/mac80211/mlme.c9
-rw-r--r--net/mac80211/spectmgmt.c21
4 files changed, 42 insertions, 2 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9112c5247c35..c9ffadb55d36 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -715,6 +715,7 @@ struct ieee80211_local {
715 struct timer_list dynamic_ps_timer; 715 struct timer_list dynamic_ps_timer;
716 716
717 int user_power_level; /* in dBm */ 717 int user_power_level; /* in dBm */
718 int power_constr_level; /* in dBm */
718 719
719#ifdef CONFIG_MAC80211_DEBUGFS 720#ifdef CONFIG_MAC80211_DEBUGFS
720 struct local_debugfsdentries { 721 struct local_debugfsdentries {
@@ -985,6 +986,9 @@ void ieee80211_chswitch_work(struct work_struct *work);
985void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata, 986void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
986 struct ieee80211_channel_sw_ie *sw_elem, 987 struct ieee80211_channel_sw_ie *sw_elem,
987 struct ieee80211_bss *bss); 988 struct ieee80211_bss *bss);
989void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
990 u16 capab_info, u8 *pwr_constr_elem,
991 u8 pwr_constr_elem_len);
988 992
989/* utility functions/constants */ 993/* utility functions/constants */
990extern void *mac80211_wiphy_privid; /* for wiphy privid */ 994extern void *mac80211_wiphy_privid; /* for wiphy privid */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e9f3e85d1a9e..c78304db475e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -214,10 +214,16 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
214 changed |= IEEE80211_CONF_CHANGE_CHANNEL; 214 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
215 } 215 }
216 216
217 if (!local->user_power_level) 217 if (local->sw_scanning)
218 power = chan->max_power; 218 power = chan->max_power;
219 else 219 else
220 power = min(chan->max_power, local->user_power_level); 220 power = local->power_constr_level ?
221 (chan->max_power - local->power_constr_level) :
222 chan->max_power;
223
224 if (local->user_power_level)
225 power = min(power, local->user_power_level);
226
221 if (local->hw.conf.power_level != power) { 227 if (local->hw.conf.power_level != power) {
222 changed |= IEEE80211_CONF_CHANGE_POWER; 228 changed |= IEEE80211_CONF_CHANGE_POWER;
223 local->hw.conf.power_level = power; 229 local->hw.conf.power_level = power;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 82c598a83687..f0d42498c257 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -905,6 +905,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
905 /* channel(_type) changes are handled by ieee80211_hw_config */ 905 /* channel(_type) changes are handled by ieee80211_hw_config */
906 local->oper_channel_type = NL80211_CHAN_NO_HT; 906 local->oper_channel_type = NL80211_CHAN_NO_HT;
907 907
908 local->power_constr_level = 0;
909
908 del_timer_sync(&local->dynamic_ps_timer); 910 del_timer_sync(&local->dynamic_ps_timer);
909 cancel_work_sync(&local->dynamic_ps_enable_work); 911 cancel_work_sync(&local->dynamic_ps_enable_work);
910 912
@@ -1849,6 +1851,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1849 * for the BSSID we are associated to */ 1851 * for the BSSID we are associated to */
1850 regulatory_hint_11d(local->hw.wiphy, 1852 regulatory_hint_11d(local->hw.wiphy,
1851 elems.country_elem, elems.country_elem_len); 1853 elems.country_elem, elems.country_elem_len);
1854
1855 /* TODO: IBSS also needs this */
1856 if (elems.pwr_constr_elem)
1857 ieee80211_handle_pwr_constr(sdata,
1858 le16_to_cpu(mgmt->u.probe_resp.capab_info),
1859 elems.pwr_constr_elem,
1860 elems.pwr_constr_elem_len);
1852 } 1861 }
1853 1862
1854 ieee80211_bss_info_change_notify(sdata, changed); 1863 ieee80211_bss_info_change_notify(sdata, changed);
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 8396b5a77e8d..8d4ec2968f8f 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -161,3 +161,24 @@ void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
161 jiffies + msecs_to_jiffies(sw_elem->count * bss->beacon_int)); 161 jiffies + msecs_to_jiffies(sw_elem->count * bss->beacon_int));
162 } 162 }
163} 163}
164
165void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
166 u16 capab_info, u8 *pwr_constr_elem,
167 u8 pwr_constr_elem_len)
168{
169 struct ieee80211_conf *conf = &sdata->local->hw.conf;
170
171 if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
172 return;
173
174 /* Power constraint IE length should be 1 octet */
175 if (pwr_constr_elem_len != 1)
176 return;
177
178 if ((*pwr_constr_elem <= conf->channel->max_power) &&
179 (*pwr_constr_elem != sdata->local->power_constr_level)) {
180 sdata->local->power_constr_level = *pwr_constr_elem;
181 ieee80211_hw_config(sdata->local, 0);
182 }
183}
184