Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 369579
b: refs/heads/master
c: cd64f2a
h: refs/heads/master
i:
  369577: 183d633
  369575: 79ff37f
v: v3
  • Loading branch information
Johannes Berg committed Apr 16, 2013
1 parent 22b4c01 commit a8be22a
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 18 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: b2e506bfc4d752b68a0ccaae1e977898263eba4c
refs/heads/master: cd64f2a9b4a9eb055e4adc14b559055775b1b62f
96 changes: 79 additions & 17 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
u8 new_chan_no;
u8 count;
u8 mode;
struct ieee80211_channel *new_chan;
struct cfg80211_chan_def new_chandef = {};
struct cfg80211_chan_def new_vht_chandef = {};
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
int secondary_channel_offset = -1;

ASSERT_MGD_MTX(ifmgd);
Expand All @@ -1042,18 +1046,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
return;

if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
/* if HT is enabled and the IE not present, it's still HT */
secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
if (elems->sec_chan_offs)
secondary_channel_offset =
elems->sec_chan_offs->sec_chan_offs;
sec_chan_offs = elems->sec_chan_offs;
wide_bw_chansw_ie = elems->wide_bw_chansw_ie;

if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
IEEE80211_STA_DISABLE_40MHZ)) {
sec_chan_offs = NULL;
wide_bw_chansw_ie = NULL;
}

if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
(secondary_channel_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE ||
secondary_channel_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW))
secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
wide_bw_chansw_ie = NULL;

if (elems->ext_chansw_ie) {
if (!ieee80211_operating_class_to_band(
Expand Down Expand Up @@ -1081,9 +1084,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
bss = (void *)cbss->priv;

new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
new_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
if (!new_chandef.chan ||
new_chandef.chan->flags & IEEE80211_CHAN_DISABLED) {
new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) {
sdata_info(sdata,
"AP %pM switches to unsupported channel (%d MHz), disconnecting\n",
ifmgd->associated->bssid, new_freq);
Expand All @@ -1092,27 +1094,87 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return;
}

if (sec_chan_offs) {
secondary_channel_offset = sec_chan_offs->sec_chan_offs;
} else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
/* if HT is enabled and the IE not present, it's still HT */
secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
}

switch (secondary_channel_offset) {
default:
/* secondary_channel_offset was present but is invalid */
case IEEE80211_HT_PARAM_CHA_SEC_NONE:
cfg80211_chandef_create(&new_chandef, new_chandef.chan,
cfg80211_chandef_create(&new_chandef, new_chan,
NL80211_CHAN_HT20);
break;
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
cfg80211_chandef_create(&new_chandef, new_chandef.chan,
cfg80211_chandef_create(&new_chandef, new_chan,
NL80211_CHAN_HT40PLUS);
break;
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
cfg80211_chandef_create(&new_chandef, new_chandef.chan,
cfg80211_chandef_create(&new_chandef, new_chan,
NL80211_CHAN_HT40MINUS);
break;
case -1:
cfg80211_chandef_create(&new_chandef, new_chandef.chan,
cfg80211_chandef_create(&new_chandef, new_chan,
NL80211_CHAN_NO_HT);
break;
}

if (wide_bw_chansw_ie) {
new_vht_chandef.chan = new_chan;
new_vht_chandef.center_freq1 =
ieee80211_channel_to_frequency(
wide_bw_chansw_ie->new_center_freq_seg0,
new_band);

switch (wide_bw_chansw_ie->new_channel_width) {
default:
/* hmmm, ignore VHT and use HT if present */
case IEEE80211_VHT_CHANWIDTH_USE_HT:
new_vht_chandef.chan = NULL;
break;
case IEEE80211_VHT_CHANWIDTH_80MHZ:
new_vht_chandef.width = NL80211_CHAN_WIDTH_80;
break;
case IEEE80211_VHT_CHANWIDTH_160MHZ:
new_vht_chandef.width = NL80211_CHAN_WIDTH_160;
break;
case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
/* field is otherwise reserved */
new_vht_chandef.center_freq2 =
ieee80211_channel_to_frequency(
wide_bw_chansw_ie->new_center_freq_seg1,
new_band);
new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
break;
}
if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ &&
new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
chandef_downgrade(&new_vht_chandef);
if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
chandef_downgrade(&new_vht_chandef);
if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
new_vht_chandef.width > NL80211_CHAN_WIDTH_20)
chandef_downgrade(&new_vht_chandef);
}

/* if VHT data is there validate & use it */
if (new_vht_chandef.chan) {
if (!cfg80211_chandef_compatible(&new_vht_chandef,
&new_chandef)) {
sdata_info(sdata,
"AP %pM CSA has inconsistent channel data, disconnecting\n",
ifmgd->associated->bssid);
ieee80211_queue_work(&local->hw,
&ifmgd->csa_connection_drop_work);
return;
}
new_chandef = new_vht_chandef;
}

if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef,
IEEE80211_CHAN_DISABLED)) {
sdata_info(sdata,
Expand Down

0 comments on commit a8be22a

Please sign in to comment.