1 /****************************************************************************** 2 * 3 * Copyright(c) 2009-2012 Realtek Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * The full GNU General Public License is included in this distribution in the 15 * file called LICENSE. 16 * 17 * Contact Information: 18 * wlanfae <wlanfae@realtek.com> 19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 20 * Hsinchu 300, Taiwan. 21 * 22 * Larry Finger <Larry.Finger@lwfinger.net> 23 * 24 *****************************************************************************/ 25 26 #include "wifi.h" 27 #include "regd.h" 28 29 static struct country_code_to_enum_rd allCountries[] = { 30 {COUNTRY_CODE_FCC, "US"}, 31 {COUNTRY_CODE_IC, "US"}, 32 {COUNTRY_CODE_ETSI, "EC"}, 33 {COUNTRY_CODE_SPAIN, "EC"}, 34 {COUNTRY_CODE_FRANCE, "EC"}, 35 {COUNTRY_CODE_MKK, "JP"}, 36 {COUNTRY_CODE_MKK1, "JP"}, 37 {COUNTRY_CODE_ISRAEL, "EC"}, 38 {COUNTRY_CODE_TELEC, "JP"}, 39 {COUNTRY_CODE_MIC, "JP"}, 40 {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, 41 {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, 42 {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, 43 {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"}, 44 }; 45 46 /* 47 *Only these channels all allow active 48 *scan on all world regulatory domains 49 */ 50 #define RTL819x_2GHZ_CH01_11 \ 51 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) 52 53 /* 54 *We enable active scan on these a case 55 *by case basis by regulatory domain 56 */ 57 #define RTL819x_2GHZ_CH12_13 \ 58 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 59 NL80211_RRF_PASSIVE_SCAN) 60 61 #define RTL819x_2GHZ_CH14 \ 62 REG_RULE(2484-10, 2484+10, 40, 0, 20, \ 63 NL80211_RRF_PASSIVE_SCAN | \ 64 NL80211_RRF_NO_OFDM) 65 66 67 /* 5G chan 36 - chan 64*/ 68 #define RTL819x_5GHZ_5150_5350 \ 69 REG_RULE(5150-10, 5350+10, 80, 0, 30, 0) 70 /* 5G chan 100 - chan 165*/ 71 #define RTL819x_5GHZ_5470_5850 \ 72 REG_RULE(5470-10, 5850+10, 80, 0, 30, 0) 73 /* 5G chan 149 - chan 165*/ 74 #define RTL819x_5GHZ_5725_5850 \ 75 REG_RULE(5725-10, 5850+10, 80, 0, 30, 0) 76 77 #define RTL819x_5GHZ_ALL \ 78 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) 79 80 static const struct ieee80211_regdomain rtl_regdom_11 = { 81 .n_reg_rules = 1, 82 .alpha2 = "99", 83 .reg_rules = { 84 RTL819x_2GHZ_CH01_11, 85 } 86 }; 87 88 static const struct ieee80211_regdomain rtl_regdom_12_13 = { 89 .n_reg_rules = 2, 90 .alpha2 = "99", 91 .reg_rules = { 92 RTL819x_2GHZ_CH01_11, 93 RTL819x_2GHZ_CH12_13, 94 } 95 }; 96 97 static const struct ieee80211_regdomain rtl_regdom_no_midband = { 98 .n_reg_rules = 3, 99 .alpha2 = "99", 100 .reg_rules = { 101 RTL819x_2GHZ_CH01_11, 102 RTL819x_5GHZ_5150_5350, 103 RTL819x_5GHZ_5725_5850, 104 } 105 }; 106 107 static const struct ieee80211_regdomain rtl_regdom_60_64 = { 108 .n_reg_rules = 3, 109 .alpha2 = "99", 110 .reg_rules = { 111 RTL819x_2GHZ_CH01_11, 112 RTL819x_2GHZ_CH12_13, 113 RTL819x_5GHZ_5725_5850, 114 } 115 }; 116 117 static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { 118 .n_reg_rules = 4, 119 .alpha2 = "99", 120 .reg_rules = { 121 RTL819x_2GHZ_CH01_11, 122 RTL819x_2GHZ_CH12_13, 123 RTL819x_2GHZ_CH14, 124 RTL819x_5GHZ_5725_5850, 125 } 126 }; 127 128 static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = { 129 .n_reg_rules = 4, 130 .alpha2 = "99", 131 .reg_rules = { 132 RTL819x_2GHZ_CH01_11, 133 RTL819x_2GHZ_CH12_13, 134 RTL819x_5GHZ_5150_5350, 135 RTL819x_5GHZ_5470_5850, 136 } 137 }; 138 139 static const struct ieee80211_regdomain rtl_regdom_14 = { 140 .n_reg_rules = 3, 141 .alpha2 = "99", 142 .reg_rules = { 143 RTL819x_2GHZ_CH01_11, 144 RTL819x_2GHZ_CH12_13, 145 RTL819x_2GHZ_CH14, 146 } 147 }; 148 149 static bool _rtl_is_radar_freq(u16 center_freq) 150 { 151 return center_freq >= 5260 && center_freq <= 5700; 152 } 153 154 static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, 155 enum nl80211_reg_initiator initiator) 156 { 157 enum ieee80211_band band; 158 struct ieee80211_supported_band *sband; 159 const struct ieee80211_reg_rule *reg_rule; 160 struct ieee80211_channel *ch; 161 unsigned int i; 162 163 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 164 165 if (!wiphy->bands[band]) 166 continue; 167 168 sband = wiphy->bands[band]; 169 170 for (i = 0; i < sband->n_channels; i++) { 171 ch = &sband->channels[i]; 172 if (_rtl_is_radar_freq(ch->center_freq) || 173 (ch->flags & IEEE80211_CHAN_RADAR)) 174 continue; 175 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 176 reg_rule = freq_reg_info(wiphy, 177 ch->center_freq); 178 if (IS_ERR(reg_rule)) 179 continue; 180 /* 181 *If 11d had a rule for this channel ensure 182 *we enable adhoc/beaconing if it allows us to 183 *use it. Note that we would have disabled it 184 *by applying our static world regdomain by 185 *default during init, prior to calling our 186 *regulatory_hint(). 187 */ 188 189 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 190 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 191 if (!(reg_rule->flags & 192 NL80211_RRF_PASSIVE_SCAN)) 193 ch->flags &= 194 ~IEEE80211_CHAN_PASSIVE_SCAN; 195 } else { 196 if (ch->beacon_found) 197 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 198 IEEE80211_CHAN_PASSIVE_SCAN); 199 } 200 } 201 } 202 } 203 204 /* Allows active scan scan on Ch 12 and 13 */ 205 static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, 206 enum nl80211_reg_initiator 207 initiator) 208 { 209 struct ieee80211_supported_band *sband; 210 struct ieee80211_channel *ch; 211 const struct ieee80211_reg_rule *reg_rule; 212 213 if (!wiphy->bands[IEEE80211_BAND_2GHZ]) 214 return; 215 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 216 217 /* 218 *If no country IE has been received always enable active scan 219 *on these channels. This is only done for specific regulatory SKUs 220 */ 221 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 222 ch = &sband->channels[11]; /* CH 12 */ 223 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 224 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 225 ch = &sband->channels[12]; /* CH 13 */ 226 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 227 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 228 return; 229 } 230 231 /* 232 *If a country IE has been recieved check its rule for this 233 *channel first before enabling active scan. The passive scan 234 *would have been enforced by the initial processing of our 235 *custom regulatory domain. 236 */ 237 238 ch = &sband->channels[11]; /* CH 12 */ 239 reg_rule = freq_reg_info(wiphy, ch->center_freq); 240 if (!IS_ERR(reg_rule)) { 241 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 242 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 243 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 244 } 245 246 ch = &sband->channels[12]; /* CH 13 */ 247 reg_rule = freq_reg_info(wiphy, ch->center_freq); 248 if (!IS_ERR(reg_rule)) { 249 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 250 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 251 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 252 } 253 } 254 255 /* 256 *Always apply Radar/DFS rules on 257 *freq range 5260 MHz - 5700 MHz 258 */ 259 static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) 260 { 261 struct ieee80211_supported_band *sband; 262 struct ieee80211_channel *ch; 263 unsigned int i; 264 265 if (!wiphy->bands[IEEE80211_BAND_5GHZ]) 266 return; 267 268 sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 269 270 for (i = 0; i < sband->n_channels; i++) { 271 ch = &sband->channels[i]; 272 if (!_rtl_is_radar_freq(ch->center_freq)) 273 continue; 274 275 /* 276 *We always enable radar detection/DFS on this 277 *frequency range. Additionally we also apply on 278 *this frequency range: 279 *- If STA mode does not yet have DFS supports disable 280 * active scanning 281 *- If adhoc mode does not support DFS yet then disable 282 * adhoc in the frequency. 283 *- If AP mode does not yet support radar detection/DFS 284 *do not allow AP mode 285 */ 286 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 287 ch->flags |= IEEE80211_CHAN_RADAR | 288 IEEE80211_CHAN_NO_IBSS | 289 IEEE80211_CHAN_PASSIVE_SCAN; 290 } 291 } 292 293 static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, 294 enum nl80211_reg_initiator initiator, 295 struct rtl_regulatory *reg) 296 { 297 _rtl_reg_apply_beaconing_flags(wiphy, initiator); 298 _rtl_reg_apply_active_scan_flags(wiphy, initiator); 299 return; 300 } 301 302 static void _rtl_dump_channel_map(struct wiphy *wiphy) 303 { 304 enum ieee80211_band band; 305 struct ieee80211_supported_band *sband; 306 struct ieee80211_channel *ch; 307 unsigned int i; 308 309 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 310 if (!wiphy->bands[band]) 311 continue; 312 sband = wiphy->bands[band]; 313 for (i = 0; i < sband->n_channels; i++) 314 ch = &sband->channels[i]; 315 } 316 } 317 318 static int _rtl_reg_notifier_apply(struct wiphy *wiphy, 319 struct regulatory_request *request, 320 struct rtl_regulatory *reg) 321 { 322 /* We always apply this */ 323 _rtl_reg_apply_radar_flags(wiphy); 324 325 switch (request->initiator) { 326 case NL80211_REGDOM_SET_BY_DRIVER: 327 case NL80211_REGDOM_SET_BY_CORE: 328 case NL80211_REGDOM_SET_BY_USER: 329 break; 330 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 331 _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); 332 break; 333 } 334 335 _rtl_dump_channel_map(wiphy); 336 337 return 0; 338 } 339 340 static const struct ieee80211_regdomain *_rtl_regdomain_select( 341 struct rtl_regulatory *reg) 342 { 343 switch (reg->country_code) { 344 case COUNTRY_CODE_FCC: 345 return &rtl_regdom_no_midband; 346 case COUNTRY_CODE_IC: 347 return &rtl_regdom_11; 348 case COUNTRY_CODE_ETSI: 349 case COUNTRY_CODE_TELEC_NETGEAR: 350 return &rtl_regdom_60_64; 351 case COUNTRY_CODE_SPAIN: 352 case COUNTRY_CODE_FRANCE: 353 case COUNTRY_CODE_ISRAEL: 354 case COUNTRY_CODE_WORLD_WIDE_13: 355 return &rtl_regdom_12_13; 356 case COUNTRY_CODE_MKK: 357 case COUNTRY_CODE_MKK1: 358 case COUNTRY_CODE_TELEC: 359 case COUNTRY_CODE_MIC: 360 return &rtl_regdom_14_60_64; 361 case COUNTRY_CODE_GLOBAL_DOMAIN: 362 return &rtl_regdom_14; 363 case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: 364 return &rtl_regdom_12_13_5g_all; 365 default: 366 return &rtl_regdom_no_midband; 367 } 368 } 369 370 static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, 371 struct wiphy *wiphy, 372 void (*reg_notifier)(struct wiphy *wiphy, 373 struct regulatory_request * 374 request)) 375 { 376 const struct ieee80211_regdomain *regd; 377 378 wiphy->reg_notifier = reg_notifier; 379 380 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 381 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; 382 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; 383 regd = _rtl_regdomain_select(reg); 384 wiphy_apply_custom_regulatory(wiphy, regd); 385 _rtl_reg_apply_radar_flags(wiphy); 386 _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); 387 return 0; 388 } 389 390 static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) 391 { 392 int i; 393 394 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 395 if (allCountries[i].countrycode == countrycode) 396 return &allCountries[i]; 397 } 398 return NULL; 399 } 400 401 static u8 channel_plan_to_country_code(u8 channelplan) 402 { 403 switch (channelplan) { 404 case 0x20: 405 case 0x21: 406 return COUNTRY_CODE_WORLD_WIDE_13; 407 case 0x22: 408 return COUNTRY_CODE_IC; 409 case 0x32: 410 return COUNTRY_CODE_TELEC_NETGEAR; 411 case 0x41: 412 return COUNTRY_CODE_GLOBAL_DOMAIN; 413 case 0x7f: 414 return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL; 415 default: 416 return COUNTRY_CODE_MAX; /*Error*/ 417 } 418 } 419 420 int rtl_regd_init(struct ieee80211_hw *hw, 421 void (*reg_notifier)(struct wiphy *wiphy, 422 struct regulatory_request *request)) 423 { 424 struct rtl_priv *rtlpriv = rtl_priv(hw); 425 struct wiphy *wiphy = hw->wiphy; 426 struct country_code_to_enum_rd *country = NULL; 427 428 if (wiphy == NULL || &rtlpriv->regd == NULL) 429 return -EINVAL; 430 431 /* init country_code from efuse channel plan */ 432 rtlpriv->regd.country_code = 433 channel_plan_to_country_code(rtlpriv->efuse.channel_plan); 434 435 RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, 436 "rtl: EEPROM regdomain: 0x%0x conuntry code: %d\n", 437 rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); 438 439 if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { 440 RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, 441 "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n"); 442 443 rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; 444 } 445 446 country = _rtl_regd_find_country(rtlpriv->regd.country_code); 447 448 if (country) { 449 rtlpriv->regd.alpha2[0] = country->iso_name[0]; 450 rtlpriv->regd.alpha2[1] = country->iso_name[1]; 451 } else { 452 rtlpriv->regd.alpha2[0] = '0'; 453 rtlpriv->regd.alpha2[1] = '0'; 454 } 455 456 RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, 457 "rtl: Country alpha2 being used: %c%c\n", 458 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); 459 460 _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); 461 462 return 0; 463 } 464 465 void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) 466 { 467 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 468 struct rtl_priv *rtlpriv = rtl_priv(hw); 469 470 RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); 471 472 _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); 473 } 474