diff options
author | Chun-Yeow Yeoh <yeohchunyeow@cozybit.com> | 2013-10-14 22:08:29 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-10-28 10:05:28 -0400 |
commit | c0f17eb9b2d4d322c099a0700437209149224583 (patch) | |
tree | ed32c2de60b9dc2dc50e2125ce49fae54e5507a8 /net | |
parent | 06be6b149f7e406bcf16098567f5a6c9f042bced (diff) |
mac80211: refactor the parsing of chan switch ie
Refactor the channel switch IE parsing to reduce the number
of function parameters.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ibss.c | 13 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 17 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 32 | ||||
-rw-r--r-- | net/mac80211/spectmgmt.c | 27 |
4 files changed, 48 insertions, 41 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 275bbb2c1a5a..a0ae02760139 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -836,13 +836,13 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
836 | bool beacon) | 836 | bool beacon) |
837 | { | 837 | { |
838 | struct cfg80211_csa_settings params; | 838 | struct cfg80211_csa_settings params; |
839 | struct ieee80211_csa_ie csa_ie; | ||
839 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 840 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
840 | struct ieee80211_chanctx_conf *chanctx_conf; | 841 | struct ieee80211_chanctx_conf *chanctx_conf; |
841 | struct ieee80211_chanctx *chanctx; | 842 | struct ieee80211_chanctx *chanctx; |
842 | enum nl80211_channel_type ch_type; | 843 | enum nl80211_channel_type ch_type; |
843 | int err, num_chanctx; | 844 | int err, num_chanctx; |
844 | u32 sta_flags; | 845 | u32 sta_flags; |
845 | u8 mode; | ||
846 | 846 | ||
847 | if (sdata->vif.csa_active) | 847 | if (sdata->vif.csa_active) |
848 | return true; | 848 | return true; |
@@ -865,12 +865,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
865 | } | 865 | } |
866 | 866 | ||
867 | memset(¶ms, 0, sizeof(params)); | 867 | memset(¶ms, 0, sizeof(params)); |
868 | memset(&csa_ie, 0, sizeof(csa_ie)); | ||
868 | err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, | 869 | err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, |
869 | ifibss->chandef.chan->band, | 870 | ifibss->chandef.chan->band, |
870 | sta_flags, ifibss->bssid, | 871 | sta_flags, ifibss->bssid, &csa_ie); |
871 | ¶ms.count, &mode, | ||
872 | ¶ms.chandef); | ||
873 | |||
874 | /* can't switch to destination channel, fail */ | 872 | /* can't switch to destination channel, fail */ |
875 | if (err < 0) | 873 | if (err < 0) |
876 | goto disconnect; | 874 | goto disconnect; |
@@ -879,6 +877,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
879 | if (err) | 877 | if (err) |
880 | return false; | 878 | return false; |
881 | 879 | ||
880 | params.count = csa_ie.count; | ||
881 | params.chandef = csa_ie.chandef; | ||
882 | |||
882 | if (ifibss->chandef.chan->band != params.chandef.chan->band) | 883 | if (ifibss->chandef.chan->band != params.chandef.chan->band) |
883 | goto disconnect; | 884 | goto disconnect; |
884 | 885 | ||
@@ -965,7 +966,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
965 | "received channel switch announcement to go to channel %d MHz\n", | 966 | "received channel switch announcement to go to channel %d MHz\n", |
966 | params.chandef.chan->center_freq); | 967 | params.chandef.chan->center_freq); |
967 | 968 | ||
968 | params.block_tx = !!mode; | 969 | params.block_tx = !!csa_ie.mode; |
969 | 970 | ||
970 | ieee80211_ibss_csa_beacon(sdata, ¶ms); | 971 | ieee80211_ibss_csa_beacon(sdata, ¶ms); |
971 | sdata->csa_radar_required = params.radar_required; | 972 | sdata->csa_radar_required = params.radar_required; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ff3c310142b5..cbaea32bccf1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1208,6 +1208,14 @@ struct ieee80211_ra_tid { | |||
1208 | u16 tid; | 1208 | u16 tid; |
1209 | }; | 1209 | }; |
1210 | 1210 | ||
1211 | /* this struct holds the value parsing from channel switch IE */ | ||
1212 | struct ieee80211_csa_ie { | ||
1213 | struct cfg80211_chan_def chandef; | ||
1214 | u8 mode; | ||
1215 | u8 count; | ||
1216 | u8 ttl; | ||
1217 | }; | ||
1218 | |||
1211 | /* Parsed Information Elements */ | 1219 | /* Parsed Information Elements */ |
1212 | struct ieee802_11_elems { | 1220 | struct ieee802_11_elems { |
1213 | const u8 *ie_start; | 1221 | const u8 *ie_start; |
@@ -1505,17 +1513,16 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | |||
1505 | * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, | 1513 | * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, |
1506 | * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, | 1514 | * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, |
1507 | * %IEEE80211_STA_DISABLE_160MHZ. | 1515 | * %IEEE80211_STA_DISABLE_160MHZ. |
1508 | * @count: to be filled with the counter until the switch (on success only) | ||
1509 | * @bssid: the currently connected bssid (for reporting) | 1516 | * @bssid: the currently connected bssid (for reporting) |
1510 | * @mode: to be filled with CSA mode (on success only) | 1517 | * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl. |
1511 | * @new_chandef: to be filled with destination chandef (on success only) | 1518 | All of them will be filled with if success only. |
1512 | * Return: 0 on success, <0 on error and >0 if there is nothing to parse. | 1519 | * Return: 0 on success, <0 on error and >0 if there is nothing to parse. |
1513 | */ | 1520 | */ |
1514 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | 1521 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, |
1515 | struct ieee802_11_elems *elems, bool beacon, | 1522 | struct ieee802_11_elems *elems, bool beacon, |
1516 | enum ieee80211_band current_band, | 1523 | enum ieee80211_band current_band, |
1517 | u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, | 1524 | u32 sta_flags, u8 *bssid, |
1518 | struct cfg80211_chan_def *new_chandef); | 1525 | struct ieee80211_csa_ie *csa_ie); |
1519 | 1526 | ||
1520 | /* Suspend/resume and hw reconfiguration */ | 1527 | /* Suspend/resume and hw reconfiguration */ |
1521 | int ieee80211_reconfig(struct ieee80211_local *local); | 1528 | int ieee80211_reconfig(struct ieee80211_local *local); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5cc1c274dd61..1305ff984d49 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -958,9 +958,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
958 | struct cfg80211_bss *cbss = ifmgd->associated; | 958 | struct cfg80211_bss *cbss = ifmgd->associated; |
959 | struct ieee80211_chanctx *chanctx; | 959 | struct ieee80211_chanctx *chanctx; |
960 | enum ieee80211_band current_band; | 960 | enum ieee80211_band current_band; |
961 | u8 count; | 961 | struct ieee80211_csa_ie csa_ie; |
962 | u8 mode; | ||
963 | struct cfg80211_chan_def new_chandef = {}; | ||
964 | int res; | 962 | int res; |
965 | 963 | ||
966 | sdata_assert_lock(sdata); | 964 | sdata_assert_lock(sdata); |
@@ -976,24 +974,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
976 | return; | 974 | return; |
977 | 975 | ||
978 | current_band = cbss->channel->band; | 976 | current_band = cbss->channel->band; |
977 | memset(&csa_ie, 0, sizeof(csa_ie)); | ||
979 | res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, | 978 | res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, |
980 | ifmgd->flags, | 979 | ifmgd->flags, |
981 | ifmgd->associated->bssid, &count, | 980 | ifmgd->associated->bssid, &csa_ie); |
982 | &mode, &new_chandef); | ||
983 | if (res < 0) | 981 | if (res < 0) |
984 | ieee80211_queue_work(&local->hw, | 982 | ieee80211_queue_work(&local->hw, |
985 | &ifmgd->csa_connection_drop_work); | 983 | &ifmgd->csa_connection_drop_work); |
986 | if (res) | 984 | if (res) |
987 | return; | 985 | return; |
988 | 986 | ||
989 | if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef, | 987 | if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, |
990 | IEEE80211_CHAN_DISABLED)) { | 988 | IEEE80211_CHAN_DISABLED)) { |
991 | sdata_info(sdata, | 989 | sdata_info(sdata, |
992 | "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", | 990 | "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", |
993 | ifmgd->associated->bssid, | 991 | ifmgd->associated->bssid, |
994 | new_chandef.chan->center_freq, | 992 | csa_ie.chandef.chan->center_freq, |
995 | new_chandef.width, new_chandef.center_freq1, | 993 | csa_ie.chandef.width, csa_ie.chandef.center_freq1, |
996 | new_chandef.center_freq2); | 994 | csa_ie.chandef.center_freq2); |
997 | ieee80211_queue_work(&local->hw, | 995 | ieee80211_queue_work(&local->hw, |
998 | &ifmgd->csa_connection_drop_work); | 996 | &ifmgd->csa_connection_drop_work); |
999 | return; | 997 | return; |
@@ -1037,9 +1035,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1037 | } | 1035 | } |
1038 | mutex_unlock(&local->chanctx_mtx); | 1036 | mutex_unlock(&local->chanctx_mtx); |
1039 | 1037 | ||
1040 | local->csa_chandef = new_chandef; | 1038 | local->csa_chandef = csa_ie.chandef; |
1041 | 1039 | ||
1042 | if (mode) | 1040 | if (csa_ie.mode) |
1043 | ieee80211_stop_queues_by_reason(&local->hw, | 1041 | ieee80211_stop_queues_by_reason(&local->hw, |
1044 | IEEE80211_MAX_QUEUE_MAP, | 1042 | IEEE80211_MAX_QUEUE_MAP, |
1045 | IEEE80211_QUEUE_STOP_REASON_CSA); | 1043 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -1048,9 +1046,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1048 | /* use driver's channel switch callback */ | 1046 | /* use driver's channel switch callback */ |
1049 | struct ieee80211_channel_switch ch_switch = { | 1047 | struct ieee80211_channel_switch ch_switch = { |
1050 | .timestamp = timestamp, | 1048 | .timestamp = timestamp, |
1051 | .block_tx = mode, | 1049 | .block_tx = csa_ie.mode, |
1052 | .chandef = new_chandef, | 1050 | .chandef = csa_ie.chandef, |
1053 | .count = count, | 1051 | .count = csa_ie.count, |
1054 | }; | 1052 | }; |
1055 | 1053 | ||
1056 | drv_channel_switch(local, &ch_switch); | 1054 | drv_channel_switch(local, &ch_switch); |
@@ -1058,11 +1056,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1058 | } | 1056 | } |
1059 | 1057 | ||
1060 | /* channel switch handled in software */ | 1058 | /* channel switch handled in software */ |
1061 | if (count <= 1) | 1059 | if (csa_ie.count <= 1) |
1062 | ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); | 1060 | ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); |
1063 | else | 1061 | else |
1064 | mod_timer(&ifmgd->chswitch_timer, | 1062 | mod_timer(&ifmgd->chswitch_timer, |
1065 | TU_TO_EXP_TIME(count * cbss->beacon_interval)); | 1063 | TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); |
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | 1066 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, |
@@ -3994,7 +3992,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3994 | } | 3992 | } |
3995 | 3993 | ||
3996 | /* prepare assoc data */ | 3994 | /* prepare assoc data */ |
3997 | 3995 | ||
3998 | ifmgd->beacon_crc_valid = false; | 3996 | ifmgd->beacon_crc_valid = false; |
3999 | 3997 | ||
4000 | /* | 3998 | /* |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 921597e279a3..a298e129633b 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -24,8 +24,8 @@ | |||
24 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | 24 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, |
25 | struct ieee802_11_elems *elems, bool beacon, | 25 | struct ieee802_11_elems *elems, bool beacon, |
26 | enum ieee80211_band current_band, | 26 | enum ieee80211_band current_band, |
27 | u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, | 27 | u32 sta_flags, u8 *bssid, |
28 | struct cfg80211_chan_def *new_chandef) | 28 | struct ieee80211_csa_ie *csa_ie) |
29 | { | 29 | { |
30 | enum ieee80211_band new_band; | 30 | enum ieee80211_band new_band; |
31 | int new_freq; | 31 | int new_freq; |
@@ -62,13 +62,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
62 | return -EINVAL; | 62 | return -EINVAL; |
63 | } | 63 | } |
64 | new_chan_no = elems->ext_chansw_ie->new_ch_num; | 64 | new_chan_no = elems->ext_chansw_ie->new_ch_num; |
65 | *count = elems->ext_chansw_ie->count; | 65 | csa_ie->count = elems->ext_chansw_ie->count; |
66 | *mode = elems->ext_chansw_ie->mode; | 66 | csa_ie->mode = elems->ext_chansw_ie->mode; |
67 | } else if (elems->ch_switch_ie) { | 67 | } else if (elems->ch_switch_ie) { |
68 | new_band = current_band; | 68 | new_band = current_band; |
69 | new_chan_no = elems->ch_switch_ie->new_ch_num; | 69 | new_chan_no = elems->ch_switch_ie->new_ch_num; |
70 | *count = elems->ch_switch_ie->count; | 70 | csa_ie->count = elems->ch_switch_ie->count; |
71 | *mode = elems->ch_switch_ie->mode; | 71 | csa_ie->mode = elems->ch_switch_ie->mode; |
72 | } else { | 72 | } else { |
73 | /* nothing here we understand */ | 73 | /* nothing here we understand */ |
74 | return 1; | 74 | return 1; |
@@ -103,25 +103,26 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
103 | default: | 103 | default: |
104 | /* secondary_channel_offset was present but is invalid */ | 104 | /* secondary_channel_offset was present but is invalid */ |
105 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | 105 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: |
106 | cfg80211_chandef_create(new_chandef, new_chan, | 106 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
107 | NL80211_CHAN_HT20); | 107 | NL80211_CHAN_HT20); |
108 | break; | 108 | break; |
109 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 109 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
110 | cfg80211_chandef_create(new_chandef, new_chan, | 110 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
111 | NL80211_CHAN_HT40PLUS); | 111 | NL80211_CHAN_HT40PLUS); |
112 | break; | 112 | break; |
113 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 113 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
114 | cfg80211_chandef_create(new_chandef, new_chan, | 114 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
115 | NL80211_CHAN_HT40MINUS); | 115 | NL80211_CHAN_HT40MINUS); |
116 | break; | 116 | break; |
117 | case -1: | 117 | case -1: |
118 | cfg80211_chandef_create(new_chandef, new_chan, | 118 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
119 | NL80211_CHAN_NO_HT); | 119 | NL80211_CHAN_NO_HT); |
120 | /* keep width for 5/10 MHz channels */ | 120 | /* keep width for 5/10 MHz channels */ |
121 | switch (sdata->vif.bss_conf.chandef.width) { | 121 | switch (sdata->vif.bss_conf.chandef.width) { |
122 | case NL80211_CHAN_WIDTH_5: | 122 | case NL80211_CHAN_WIDTH_5: |
123 | case NL80211_CHAN_WIDTH_10: | 123 | case NL80211_CHAN_WIDTH_10: |
124 | new_chandef->width = sdata->vif.bss_conf.chandef.width; | 124 | csa_ie->chandef.width = |
125 | sdata->vif.bss_conf.chandef.width; | ||
125 | break; | 126 | break; |
126 | default: | 127 | default: |
127 | break; | 128 | break; |
@@ -171,13 +172,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
171 | /* if VHT data is there validate & use it */ | 172 | /* if VHT data is there validate & use it */ |
172 | if (new_vht_chandef.chan) { | 173 | if (new_vht_chandef.chan) { |
173 | if (!cfg80211_chandef_compatible(&new_vht_chandef, | 174 | if (!cfg80211_chandef_compatible(&new_vht_chandef, |
174 | new_chandef)) { | 175 | &csa_ie->chandef)) { |
175 | sdata_info(sdata, | 176 | sdata_info(sdata, |
176 | "BSS %pM: CSA has inconsistent channel data, disconnecting\n", | 177 | "BSS %pM: CSA has inconsistent channel data, disconnecting\n", |
177 | bssid); | 178 | bssid); |
178 | return -EINVAL; | 179 | return -EINVAL; |
179 | } | 180 | } |
180 | *new_chandef = new_vht_chandef; | 181 | csa_ie->chandef = new_vht_chandef; |
181 | } | 182 | } |
182 | 183 | ||
183 | return 0; | 184 | return 0; |