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