18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "wifi.h" 58c2ecf20Sopenharmony_ci#include "regd.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_cistatic struct country_code_to_enum_rd all_countries[] = { 88c2ecf20Sopenharmony_ci {COUNTRY_CODE_FCC, "US"}, 98c2ecf20Sopenharmony_ci {COUNTRY_CODE_IC, "US"}, 108c2ecf20Sopenharmony_ci {COUNTRY_CODE_ETSI, "EC"}, 118c2ecf20Sopenharmony_ci {COUNTRY_CODE_SPAIN, "EC"}, 128c2ecf20Sopenharmony_ci {COUNTRY_CODE_FRANCE, "EC"}, 138c2ecf20Sopenharmony_ci {COUNTRY_CODE_MKK, "JP"}, 148c2ecf20Sopenharmony_ci {COUNTRY_CODE_MKK1, "JP"}, 158c2ecf20Sopenharmony_ci {COUNTRY_CODE_ISRAEL, "EC"}, 168c2ecf20Sopenharmony_ci {COUNTRY_CODE_TELEC, "JP"}, 178c2ecf20Sopenharmony_ci {COUNTRY_CODE_MIC, "JP"}, 188c2ecf20Sopenharmony_ci {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, 198c2ecf20Sopenharmony_ci {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, 208c2ecf20Sopenharmony_ci {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, 218c2ecf20Sopenharmony_ci {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"}, 228c2ecf20Sopenharmony_ci}; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci *Only these channels all allow active 268c2ecf20Sopenharmony_ci *scan on all world regulatory domains 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci#define RTL819x_2GHZ_CH01_11 \ 298c2ecf20Sopenharmony_ci REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci *We enable active scan on these a case 338c2ecf20Sopenharmony_ci *by case basis by regulatory domain 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci#define RTL819x_2GHZ_CH12_13 \ 368c2ecf20Sopenharmony_ci REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 378c2ecf20Sopenharmony_ci NL80211_RRF_PASSIVE_SCAN) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define RTL819x_2GHZ_CH14 \ 408c2ecf20Sopenharmony_ci REG_RULE(2484-10, 2484+10, 40, 0, 20, \ 418c2ecf20Sopenharmony_ci NL80211_RRF_PASSIVE_SCAN | \ 428c2ecf20Sopenharmony_ci NL80211_RRF_NO_OFDM) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 5G chan 36 - chan 64*/ 458c2ecf20Sopenharmony_ci#define RTL819x_5GHZ_5150_5350 \ 468c2ecf20Sopenharmony_ci REG_RULE(5150-10, 5350+10, 80, 0, 30, 0) 478c2ecf20Sopenharmony_ci/* 5G chan 100 - chan 165*/ 488c2ecf20Sopenharmony_ci#define RTL819x_5GHZ_5470_5850 \ 498c2ecf20Sopenharmony_ci REG_RULE(5470-10, 5850+10, 80, 0, 30, 0) 508c2ecf20Sopenharmony_ci/* 5G chan 149 - chan 165*/ 518c2ecf20Sopenharmony_ci#define RTL819x_5GHZ_5725_5850 \ 528c2ecf20Sopenharmony_ci REG_RULE(5725-10, 5850+10, 80, 0, 30, 0) 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define RTL819x_5GHZ_ALL \ 558c2ecf20Sopenharmony_ci (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_11 = { 588c2ecf20Sopenharmony_ci .n_reg_rules = 1, 598c2ecf20Sopenharmony_ci .alpha2 = "99", 608c2ecf20Sopenharmony_ci .reg_rules = { 618c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_12_13 = { 668c2ecf20Sopenharmony_ci .n_reg_rules = 2, 678c2ecf20Sopenharmony_ci .alpha2 = "99", 688c2ecf20Sopenharmony_ci .reg_rules = { 698c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 708c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH12_13, 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_no_midband = { 758c2ecf20Sopenharmony_ci .n_reg_rules = 3, 768c2ecf20Sopenharmony_ci .alpha2 = "99", 778c2ecf20Sopenharmony_ci .reg_rules = { 788c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 798c2ecf20Sopenharmony_ci RTL819x_5GHZ_5150_5350, 808c2ecf20Sopenharmony_ci RTL819x_5GHZ_5725_5850, 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_60_64 = { 858c2ecf20Sopenharmony_ci .n_reg_rules = 3, 868c2ecf20Sopenharmony_ci .alpha2 = "99", 878c2ecf20Sopenharmony_ci .reg_rules = { 888c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 898c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH12_13, 908c2ecf20Sopenharmony_ci RTL819x_5GHZ_5725_5850, 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci}; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_14_60_64 = { 958c2ecf20Sopenharmony_ci .n_reg_rules = 4, 968c2ecf20Sopenharmony_ci .alpha2 = "99", 978c2ecf20Sopenharmony_ci .reg_rules = { 988c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 998c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH12_13, 1008c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH14, 1018c2ecf20Sopenharmony_ci RTL819x_5GHZ_5725_5850, 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = { 1068c2ecf20Sopenharmony_ci .n_reg_rules = 4, 1078c2ecf20Sopenharmony_ci .alpha2 = "99", 1088c2ecf20Sopenharmony_ci .reg_rules = { 1098c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 1108c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH12_13, 1118c2ecf20Sopenharmony_ci RTL819x_5GHZ_5150_5350, 1128c2ecf20Sopenharmony_ci RTL819x_5GHZ_5470_5850, 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci}; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain rtl_regdom_14 = { 1178c2ecf20Sopenharmony_ci .n_reg_rules = 3, 1188c2ecf20Sopenharmony_ci .alpha2 = "99", 1198c2ecf20Sopenharmony_ci .reg_rules = { 1208c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH01_11, 1218c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH12_13, 1228c2ecf20Sopenharmony_ci RTL819x_2GHZ_CH14, 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic bool _rtl_is_radar_freq(u16 center_freq) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci return center_freq >= 5260 && center_freq <= 5700; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, 1328c2ecf20Sopenharmony_ci enum nl80211_reg_initiator initiator) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci enum nl80211_band band; 1358c2ecf20Sopenharmony_ci struct ieee80211_supported_band *sband; 1368c2ecf20Sopenharmony_ci const struct ieee80211_reg_rule *reg_rule; 1378c2ecf20Sopenharmony_ci struct ieee80211_channel *ch; 1388c2ecf20Sopenharmony_ci unsigned int i; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci for (band = 0; band < NUM_NL80211_BANDS; band++) { 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci if (!wiphy->bands[band]) 1438c2ecf20Sopenharmony_ci continue; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci sband = wiphy->bands[band]; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci for (i = 0; i < sband->n_channels; i++) { 1488c2ecf20Sopenharmony_ci ch = &sband->channels[i]; 1498c2ecf20Sopenharmony_ci if (_rtl_is_radar_freq(ch->center_freq) || 1508c2ecf20Sopenharmony_ci (ch->flags & IEEE80211_CHAN_RADAR)) 1518c2ecf20Sopenharmony_ci continue; 1528c2ecf20Sopenharmony_ci if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1538c2ecf20Sopenharmony_ci reg_rule = freq_reg_info(wiphy, 1548c2ecf20Sopenharmony_ci ch->center_freq); 1558c2ecf20Sopenharmony_ci if (IS_ERR(reg_rule)) 1568c2ecf20Sopenharmony_ci continue; 1578c2ecf20Sopenharmony_ci /* 1588c2ecf20Sopenharmony_ci *If 11d had a rule for this channel ensure 1598c2ecf20Sopenharmony_ci *we enable adhoc/beaconing if it allows us to 1608c2ecf20Sopenharmony_ci *use it. Note that we would have disabled it 1618c2ecf20Sopenharmony_ci *by applying our static world regdomain by 1628c2ecf20Sopenharmony_ci *default during init, prior to calling our 1638c2ecf20Sopenharmony_ci *regulatory_hint(). 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 1678c2ecf20Sopenharmony_ci ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 1688c2ecf20Sopenharmony_ci if (!(reg_rule->flags & 1698c2ecf20Sopenharmony_ci NL80211_RRF_PASSIVE_SCAN)) 1708c2ecf20Sopenharmony_ci ch->flags &= 1718c2ecf20Sopenharmony_ci ~IEEE80211_CHAN_PASSIVE_SCAN; 1728c2ecf20Sopenharmony_ci } else { 1738c2ecf20Sopenharmony_ci if (ch->beacon_found) 1748c2ecf20Sopenharmony_ci ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 1758c2ecf20Sopenharmony_ci IEEE80211_CHAN_PASSIVE_SCAN); 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci} 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/* Allows active scan scan on Ch 12 and 13 */ 1828c2ecf20Sopenharmony_cistatic void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, 1838c2ecf20Sopenharmony_ci enum nl80211_reg_initiator 1848c2ecf20Sopenharmony_ci initiator) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci struct ieee80211_supported_band *sband; 1878c2ecf20Sopenharmony_ci struct ieee80211_channel *ch; 1888c2ecf20Sopenharmony_ci const struct ieee80211_reg_rule *reg_rule; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (!wiphy->bands[NL80211_BAND_2GHZ]) 1918c2ecf20Sopenharmony_ci return; 1928c2ecf20Sopenharmony_ci sband = wiphy->bands[NL80211_BAND_2GHZ]; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci /* 1958c2ecf20Sopenharmony_ci *If no country IE has been received always enable active scan 1968c2ecf20Sopenharmony_ci *on these channels. This is only done for specific regulatory SKUs 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1998c2ecf20Sopenharmony_ci ch = &sband->channels[11]; /* CH 12 */ 2008c2ecf20Sopenharmony_ci if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2018c2ecf20Sopenharmony_ci ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 2028c2ecf20Sopenharmony_ci ch = &sband->channels[12]; /* CH 13 */ 2038c2ecf20Sopenharmony_ci if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2048c2ecf20Sopenharmony_ci ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 2058c2ecf20Sopenharmony_ci return; 2068c2ecf20Sopenharmony_ci } 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci /* 2098c2ecf20Sopenharmony_ci *If a country IE has been recieved check its rule for this 2108c2ecf20Sopenharmony_ci *channel first before enabling active scan. The passive scan 2118c2ecf20Sopenharmony_ci *would have been enforced by the initial processing of our 2128c2ecf20Sopenharmony_ci *custom regulatory domain. 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci ch = &sband->channels[11]; /* CH 12 */ 2168c2ecf20Sopenharmony_ci reg_rule = freq_reg_info(wiphy, ch->center_freq); 2178c2ecf20Sopenharmony_ci if (!IS_ERR(reg_rule)) { 2188c2ecf20Sopenharmony_ci if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 2198c2ecf20Sopenharmony_ci if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2208c2ecf20Sopenharmony_ci ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci ch = &sband->channels[12]; /* CH 13 */ 2248c2ecf20Sopenharmony_ci reg_rule = freq_reg_info(wiphy, ch->center_freq); 2258c2ecf20Sopenharmony_ci if (!IS_ERR(reg_rule)) { 2268c2ecf20Sopenharmony_ci if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 2278c2ecf20Sopenharmony_ci if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2288c2ecf20Sopenharmony_ci ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci/* 2338c2ecf20Sopenharmony_ci *Always apply Radar/DFS rules on 2348c2ecf20Sopenharmony_ci *freq range 5260 MHz - 5700 MHz 2358c2ecf20Sopenharmony_ci */ 2368c2ecf20Sopenharmony_cistatic void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) 2378c2ecf20Sopenharmony_ci{ 2388c2ecf20Sopenharmony_ci struct ieee80211_supported_band *sband; 2398c2ecf20Sopenharmony_ci struct ieee80211_channel *ch; 2408c2ecf20Sopenharmony_ci unsigned int i; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci if (!wiphy->bands[NL80211_BAND_5GHZ]) 2438c2ecf20Sopenharmony_ci return; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci sband = wiphy->bands[NL80211_BAND_5GHZ]; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci for (i = 0; i < sband->n_channels; i++) { 2488c2ecf20Sopenharmony_ci ch = &sband->channels[i]; 2498c2ecf20Sopenharmony_ci if (!_rtl_is_radar_freq(ch->center_freq)) 2508c2ecf20Sopenharmony_ci continue; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci /* 2538c2ecf20Sopenharmony_ci *We always enable radar detection/DFS on this 2548c2ecf20Sopenharmony_ci *frequency range. Additionally we also apply on 2558c2ecf20Sopenharmony_ci *this frequency range: 2568c2ecf20Sopenharmony_ci *- If STA mode does not yet have DFS supports disable 2578c2ecf20Sopenharmony_ci * active scanning 2588c2ecf20Sopenharmony_ci *- If adhoc mode does not support DFS yet then disable 2598c2ecf20Sopenharmony_ci * adhoc in the frequency. 2608c2ecf20Sopenharmony_ci *- If AP mode does not yet support radar detection/DFS 2618c2ecf20Sopenharmony_ci *do not allow AP mode 2628c2ecf20Sopenharmony_ci */ 2638c2ecf20Sopenharmony_ci if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 2648c2ecf20Sopenharmony_ci ch->flags |= IEEE80211_CHAN_RADAR | 2658c2ecf20Sopenharmony_ci IEEE80211_CHAN_NO_IBSS | 2668c2ecf20Sopenharmony_ci IEEE80211_CHAN_PASSIVE_SCAN; 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic void _rtl_reg_apply_world_flags(struct wiphy *wiphy, 2718c2ecf20Sopenharmony_ci enum nl80211_reg_initiator initiator, 2728c2ecf20Sopenharmony_ci struct rtl_regulatory *reg) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci _rtl_reg_apply_beaconing_flags(wiphy, initiator); 2758c2ecf20Sopenharmony_ci _rtl_reg_apply_active_scan_flags(wiphy, initiator); 2768c2ecf20Sopenharmony_ci return; 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic int _rtl_reg_notifier_apply(struct wiphy *wiphy, 2808c2ecf20Sopenharmony_ci struct regulatory_request *request, 2818c2ecf20Sopenharmony_ci struct rtl_regulatory *reg) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci /* We always apply this */ 2848c2ecf20Sopenharmony_ci _rtl_reg_apply_radar_flags(wiphy); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci switch (request->initiator) { 2878c2ecf20Sopenharmony_ci case NL80211_REGDOM_SET_BY_DRIVER: 2888c2ecf20Sopenharmony_ci case NL80211_REGDOM_SET_BY_CORE: 2898c2ecf20Sopenharmony_ci case NL80211_REGDOM_SET_BY_USER: 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2928c2ecf20Sopenharmony_ci _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); 2938c2ecf20Sopenharmony_ci break; 2948c2ecf20Sopenharmony_ci } 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci return 0; 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic const struct ieee80211_regdomain *_rtl_regdomain_select( 3008c2ecf20Sopenharmony_ci struct rtl_regulatory *reg) 3018c2ecf20Sopenharmony_ci{ 3028c2ecf20Sopenharmony_ci switch (reg->country_code) { 3038c2ecf20Sopenharmony_ci case COUNTRY_CODE_FCC: 3048c2ecf20Sopenharmony_ci return &rtl_regdom_no_midband; 3058c2ecf20Sopenharmony_ci case COUNTRY_CODE_IC: 3068c2ecf20Sopenharmony_ci return &rtl_regdom_11; 3078c2ecf20Sopenharmony_ci case COUNTRY_CODE_TELEC_NETGEAR: 3088c2ecf20Sopenharmony_ci return &rtl_regdom_60_64; 3098c2ecf20Sopenharmony_ci case COUNTRY_CODE_ETSI: 3108c2ecf20Sopenharmony_ci case COUNTRY_CODE_SPAIN: 3118c2ecf20Sopenharmony_ci case COUNTRY_CODE_FRANCE: 3128c2ecf20Sopenharmony_ci case COUNTRY_CODE_ISRAEL: 3138c2ecf20Sopenharmony_ci return &rtl_regdom_12_13; 3148c2ecf20Sopenharmony_ci case COUNTRY_CODE_MKK: 3158c2ecf20Sopenharmony_ci case COUNTRY_CODE_MKK1: 3168c2ecf20Sopenharmony_ci case COUNTRY_CODE_TELEC: 3178c2ecf20Sopenharmony_ci case COUNTRY_CODE_MIC: 3188c2ecf20Sopenharmony_ci return &rtl_regdom_14_60_64; 3198c2ecf20Sopenharmony_ci case COUNTRY_CODE_GLOBAL_DOMAIN: 3208c2ecf20Sopenharmony_ci return &rtl_regdom_14; 3218c2ecf20Sopenharmony_ci case COUNTRY_CODE_WORLD_WIDE_13: 3228c2ecf20Sopenharmony_ci case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: 3238c2ecf20Sopenharmony_ci return &rtl_regdom_12_13_5g_all; 3248c2ecf20Sopenharmony_ci default: 3258c2ecf20Sopenharmony_ci return &rtl_regdom_no_midband; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, 3308c2ecf20Sopenharmony_ci struct wiphy *wiphy, 3318c2ecf20Sopenharmony_ci void (*reg_notifier)(struct wiphy *wiphy, 3328c2ecf20Sopenharmony_ci struct regulatory_request * 3338c2ecf20Sopenharmony_ci request)) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci const struct ieee80211_regdomain *regd; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci wiphy->reg_notifier = reg_notifier; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 3408c2ecf20Sopenharmony_ci wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; 3418c2ecf20Sopenharmony_ci wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; 3428c2ecf20Sopenharmony_ci regd = _rtl_regdomain_select(reg); 3438c2ecf20Sopenharmony_ci wiphy_apply_custom_regulatory(wiphy, regd); 3448c2ecf20Sopenharmony_ci _rtl_reg_apply_radar_flags(wiphy); 3458c2ecf20Sopenharmony_ci _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); 3468c2ecf20Sopenharmony_ci return 0; 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cistatic struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci int i; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(all_countries); i++) { 3548c2ecf20Sopenharmony_ci if (all_countries[i].countrycode == countrycode) 3558c2ecf20Sopenharmony_ci return &all_countries[i]; 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci return NULL; 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistatic u8 channel_plan_to_country_code(u8 channelplan) 3618c2ecf20Sopenharmony_ci{ 3628c2ecf20Sopenharmony_ci switch (channelplan) { 3638c2ecf20Sopenharmony_ci case 0x20: 3648c2ecf20Sopenharmony_ci case 0x21: 3658c2ecf20Sopenharmony_ci return COUNTRY_CODE_WORLD_WIDE_13; 3668c2ecf20Sopenharmony_ci case 0x22: 3678c2ecf20Sopenharmony_ci return COUNTRY_CODE_IC; 3688c2ecf20Sopenharmony_ci case 0x25: 3698c2ecf20Sopenharmony_ci return COUNTRY_CODE_ETSI; 3708c2ecf20Sopenharmony_ci case 0x32: 3718c2ecf20Sopenharmony_ci return COUNTRY_CODE_TELEC_NETGEAR; 3728c2ecf20Sopenharmony_ci case 0x41: 3738c2ecf20Sopenharmony_ci return COUNTRY_CODE_GLOBAL_DOMAIN; 3748c2ecf20Sopenharmony_ci case 0x7f: 3758c2ecf20Sopenharmony_ci return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL; 3768c2ecf20Sopenharmony_ci default: 3778c2ecf20Sopenharmony_ci return COUNTRY_CODE_MAX; /*Error*/ 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ciint rtl_regd_init(struct ieee80211_hw *hw, 3828c2ecf20Sopenharmony_ci void (*reg_notifier)(struct wiphy *wiphy, 3838c2ecf20Sopenharmony_ci struct regulatory_request *request)) 3848c2ecf20Sopenharmony_ci{ 3858c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3868c2ecf20Sopenharmony_ci struct wiphy *wiphy = hw->wiphy; 3878c2ecf20Sopenharmony_ci struct country_code_to_enum_rd *country = NULL; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci if (!wiphy) 3908c2ecf20Sopenharmony_ci return -EINVAL; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci /* init country_code from efuse channel plan */ 3938c2ecf20Sopenharmony_ci rtlpriv->regd.country_code = 3948c2ecf20Sopenharmony_ci channel_plan_to_country_code(rtlpriv->efuse.channel_plan); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, 3978c2ecf20Sopenharmony_ci "rtl: EEPROM regdomain: 0x%0x country code: %d\n", 3988c2ecf20Sopenharmony_ci rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { 4018c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, 4028c2ecf20Sopenharmony_ci "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci country = _rtl_regd_find_country(rtlpriv->regd.country_code); 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci if (country) { 4108c2ecf20Sopenharmony_ci rtlpriv->regd.alpha2[0] = country->iso_name[0]; 4118c2ecf20Sopenharmony_ci rtlpriv->regd.alpha2[1] = country->iso_name[1]; 4128c2ecf20Sopenharmony_ci } else { 4138c2ecf20Sopenharmony_ci rtlpriv->regd.alpha2[0] = '0'; 4148c2ecf20Sopenharmony_ci rtlpriv->regd.alpha2[1] = '0'; 4158c2ecf20Sopenharmony_ci } 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_REGD, DBG_TRACE, 4188c2ecf20Sopenharmony_ci "rtl: Country alpha2 being used: %c%c\n", 4198c2ecf20Sopenharmony_ci rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci return 0; 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_civoid rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 4298c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); 4348c2ecf20Sopenharmony_ci} 435