Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 328164
b: refs/heads/master
c: 04b7b2f
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg committed Sep 14, 2012
1 parent 5bc1d9f commit 48b7d19
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a6a0d8ee88d23e7dda28808c2c890c4db50ccb2
refs/heads/master: 04b7b2ff50fc77380c1e711f1d7223734547e41b
2 changes: 1 addition & 1 deletion trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ struct ieee80211_local {
bool disable_dynamic_ps;

int user_power_level; /* in dBm */
int power_constr_level; /* in dBm */
int ap_power_level; /* in dBm */

enum ieee80211_smps_mode smps_mode;

Expand Down
8 changes: 3 additions & 5 deletions trunk/net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,11 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)

if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
test_bit(SCAN_HW_SCANNING, &local->scanning))
test_bit(SCAN_HW_SCANNING, &local->scanning) ||
!local->ap_power_level)
power = chan->max_power;
else
power = local->power_constr_level ?
min(chan->max_power,
(chan->max_reg_power - local->power_constr_level)) :
chan->max_power;
power = min(chan->max_power, local->ap_power_level);

if (local->user_power_level >= 0)
power = min(power, local->user_power_level);
Expand Down
84 changes: 68 additions & 16 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,18 +779,71 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
}

static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem)
struct ieee80211_channel *channel,
const u8 *country_ie, u8 country_ie_len,
const u8 *pwr_constr_elem)
{
struct ieee80211_conf *conf = &sdata->local->hw.conf;
struct ieee80211_country_ie_triplet *triplet;
int chan = ieee80211_frequency_to_channel(channel->center_freq);
int i, chan_pwr, chan_increment, new_ap_level;
bool have_chan_pwr = false;

if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
/* Invalid IE */
if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
return;

if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
(*pwr_constr_elem != sdata->local->power_constr_level)) {
sdata->local->power_constr_level = *pwr_constr_elem;
ieee80211_hw_config(sdata->local, 0);
triplet = (void *)(country_ie + 3);
country_ie_len -= 3;

switch (channel->band) {
default:
WARN_ON_ONCE(1);
/* fall through */
case IEEE80211_BAND_2GHZ:
case IEEE80211_BAND_60GHZ:
chan_increment = 1;
break;
case IEEE80211_BAND_5GHZ:
chan_increment = 4;
break;
}

/* find channel */
while (country_ie_len >= 3) {
u8 first_channel = triplet->chans.first_channel;

if (first_channel >= IEEE80211_COUNTRY_EXTENSION_ID)
goto next;

for (i = 0; i < triplet->chans.num_channels; i++) {
if (first_channel + i * chan_increment == chan) {
have_chan_pwr = true;
chan_pwr = triplet->chans.max_power;
break;
}
}
if (have_chan_pwr)
break;

next:
triplet++;
country_ie_len -= 3;
}

if (!have_chan_pwr)
return;

new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);

if (sdata->local->ap_power_level == new_ap_level)
return;

sdata_info(sdata,
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
new_ap_level, chan_pwr, *pwr_constr_elem,
sdata->u.mgd.bssid);
sdata->local->ap_power_level = new_ap_level;
ieee80211_hw_config(sdata->local, 0);
}

void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
Expand Down Expand Up @@ -1394,7 +1447,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));

local->power_constr_level = 0;
local->ap_power_level = 0;

del_timer_sync(&local->dynamic_ps_timer);
cancel_work_sync(&local->dynamic_ps_enable_work);
Expand Down Expand Up @@ -2499,14 +2552,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
bssid, true);
}

/* Note: country IE parsing is done for us by cfg80211 */
if (elems.country_elem) {
/* TODO: IBSS also needs this */
if (elems.pwr_constr_elem)
ieee80211_handle_pwr_constr(sdata,
le16_to_cpu(mgmt->u.probe_resp.capab_info),
elems.pwr_constr_elem);
}
if (elems.country_elem && elems.pwr_constr_elem &&
mgmt->u.probe_resp.capab_info &
cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
ieee80211_handle_pwr_constr(sdata, local->oper_channel,
elems.country_elem,
elems.country_elem_len,
elems.pwr_constr_elem);

ieee80211_bss_info_change_notify(sdata, changed);
}
Expand Down

0 comments on commit 48b7d19

Please sign in to comment.