aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath9k/regd.c93
1 files changed, 61 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index eb0d1b754d20..f4595e248875 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -160,13 +160,18 @@ static bool ath9k_is_radar_freq(u16 center_freq)
160} 160}
161 161
162/* 162/*
163 * Enable adhoc on 5 GHz if allowed by 11d. 163 * N.B: These exception rules do not apply radar freqs.
164 * Remove passive scan if channel is allowed by 11d, 164 *
165 * except when on radar frequencies. 165 * - We enable adhoc (or beaconing) if allowed by 11d
166 * - We enable active scan if the channel is allowed by 11d
167 * - If no country IE has been processed and a we determine we have
168 * received a beacon on a channel we can enable active scan and
169 * adhoc (or beaconing).
166 */ 170 */
167static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy, 171static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy,
168 enum reg_set_by setby) 172 enum reg_set_by setby)
169{ 173{
174 enum ieee80211_band band;
170 struct ieee80211_supported_band *sband; 175 struct ieee80211_supported_band *sband;
171 const struct ieee80211_reg_rule *reg_rule; 176 const struct ieee80211_reg_rule *reg_rule;
172 struct ieee80211_channel *ch; 177 struct ieee80211_channel *ch;
@@ -174,29 +179,50 @@ static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy,
174 u32 bandwidth = 0; 179 u32 bandwidth = 0;
175 int r; 180 int r;
176 181
177 if (setby != REGDOM_SET_BY_COUNTRY_IE) 182 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
178 return;
179 if (!wiphy->bands[IEEE80211_BAND_5GHZ])
180 return;
181 183
182 sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 184 if (!wiphy->bands[band])
183 for (i = 0; i < sband->n_channels; i++) {
184 ch = &sband->channels[i];
185 r = freq_reg_info(wiphy, ch->center_freq,
186 &bandwidth, &reg_rule);
187 if (r)
188 continue; 185 continue;
189 /* If 11d had a rule for this channel ensure we enable adhoc 186
190 * if it allows us to use it. Note that we would have disabled 187 sband = wiphy->bands[band];
191 * it by applying our static world regdomain by default during 188
192 * probe */ 189 for (i = 0; i < sband->n_channels; i++) {
193 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 190
194 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 191 ch = &sband->channels[i];
195 if (!ath9k_is_radar_freq(ch->center_freq)) 192
196 continue; 193 if (ath9k_is_radar_freq(ch->center_freq) ||
197 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 194 (ch->flags & IEEE80211_CHAN_RADAR))
198 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 195 continue;
196
197 if (setby == REGDOM_SET_BY_COUNTRY_IE) {
198 r = freq_reg_info(wiphy, ch->center_freq,
199 &bandwidth, &reg_rule);
200 if (r)
201 continue;
202 /*
203 * If 11d had a rule for this channel ensure
204 * we enable adhoc/beaconing if it allows us to
205 * use it. Note that we would have disabled it
206 * by applying our static world regdomain by
207 * default during init, prior to calling our
208 * regulatory_hint().
209 */
210 if (!(reg_rule->flags &
211 NL80211_RRF_NO_IBSS))
212 ch->flags &=
213 ~IEEE80211_CHAN_NO_IBSS;
214 if (!(reg_rule->flags &
215 NL80211_RRF_PASSIVE_SCAN))
216 ch->flags &=
217 ~IEEE80211_CHAN_PASSIVE_SCAN;
218 } else {
219 if (ch->beacon_found)
220 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
221 IEEE80211_CHAN_PASSIVE_SCAN);
222 }
223 }
199 } 224 }
225
200} 226}
201 227
202/* Allows active scan scan on Ch 12 and 13 */ 228/* Allows active scan scan on Ch 12 and 13 */
@@ -209,11 +235,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
209 u32 bandwidth = 0; 235 u32 bandwidth = 0;
210 int r; 236 int r;
211 237
212 /* Force passive scan on Channels 12-13 */
213 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 238 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
214 239
215 /* If no country IE has been received always enable active scan 240 /*
216 * on these channels */ 241 * If no country IE has been received always enable active scan
242 * on these channels. This is only done for specific regulatory SKUs
243 */
217 if (setby != REGDOM_SET_BY_COUNTRY_IE) { 244 if (setby != REGDOM_SET_BY_COUNTRY_IE) {
218 ch = &sband->channels[11]; /* CH 12 */ 245 ch = &sband->channels[11]; /* CH 12 */
219 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 246 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
@@ -224,10 +251,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
224 return; 251 return;
225 } 252 }
226 253
227 /* If a country IE has been recieved check its rule for this 254 /*
255 * If a country IE has been recieved check its rule for this
228 * channel first before enabling active scan. The passive scan 256 * channel first before enabling active scan. The passive scan
229 * would have been enforced by the initial probe processing on 257 * would have been enforced by the initial processing of our
230 * our custom regulatory domain. */ 258 * custom regulatory domain.
259 */
231 260
232 ch = &sband->channels[11]; /* CH 12 */ 261 ch = &sband->channels[11]; /* CH 12 */
233 r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule); 262 r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
@@ -290,10 +319,10 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
290 case 0x63: 319 case 0x63:
291 case 0x66: 320 case 0x66:
292 case 0x67: 321 case 0x67:
293 ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); 322 ath9k_reg_apply_beaconing_flags(wiphy, setby);
294 break; 323 break;
295 case 0x68: 324 case 0x68:
296 ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); 325 ath9k_reg_apply_beaconing_flags(wiphy, setby);
297 ath9k_reg_apply_active_scan_flags(wiphy, setby); 326 ath9k_reg_apply_active_scan_flags(wiphy, setby);
298 break; 327 break;
299 } 328 }