1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012 Realtek Corporation.*/
7 static struct country_code_to_enum_rd all_countries
[] = {
8 {COUNTRY_CODE_FCC
, "US"},
9 {COUNTRY_CODE_IC
, "US"},
10 {COUNTRY_CODE_ETSI
, "EC"},
11 {COUNTRY_CODE_SPAIN
, "EC"},
12 {COUNTRY_CODE_FRANCE
, "EC"},
13 {COUNTRY_CODE_MKK
, "JP"},
14 {COUNTRY_CODE_MKK1
, "JP"},
15 {COUNTRY_CODE_ISRAEL
, "EC"},
16 {COUNTRY_CODE_TELEC
, "JP"},
17 {COUNTRY_CODE_MIC
, "JP"},
18 {COUNTRY_CODE_GLOBAL_DOMAIN
, "JP"},
19 {COUNTRY_CODE_WORLD_WIDE_13
, "EC"},
20 {COUNTRY_CODE_TELEC_NETGEAR
, "EC"},
21 {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL
, "US"},
25 *Only these channels all allow active
26 *scan on all world regulatory domains
28 #define RTL819x_2GHZ_CH01_11 \
29 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
32 *We enable active scan on these a case
33 *by case basis by regulatory domain
35 #define RTL819x_2GHZ_CH12_13 \
36 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
37 NL80211_RRF_PASSIVE_SCAN)
39 #define RTL819x_2GHZ_CH14 \
40 REG_RULE(2484-10, 2484+10, 40, 0, 20, \
41 NL80211_RRF_PASSIVE_SCAN | \
44 /* 5G chan 36 - chan 64*/
45 #define RTL819x_5GHZ_5150_5350 \
46 REG_RULE(5150-10, 5350+10, 80, 0, 30, 0)
47 /* 5G chan 100 - chan 165*/
48 #define RTL819x_5GHZ_5470_5850 \
49 REG_RULE(5470-10, 5850+10, 80, 0, 30, 0)
50 /* 5G chan 149 - chan 165*/
51 #define RTL819x_5GHZ_5725_5850 \
52 REG_RULE(5725-10, 5850+10, 80, 0, 30, 0)
54 #define RTL819x_5GHZ_ALL \
55 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
57 static const struct ieee80211_regdomain rtl_regdom_11
= {
65 static const struct ieee80211_regdomain rtl_regdom_12_13
= {
74 static const struct ieee80211_regdomain rtl_regdom_no_midband
= {
79 RTL819x_5GHZ_5150_5350
,
80 RTL819x_5GHZ_5725_5850
,
84 static const struct ieee80211_regdomain rtl_regdom_60_64
= {
90 RTL819x_5GHZ_5725_5850
,
94 static const struct ieee80211_regdomain rtl_regdom_14_60_64
= {
101 RTL819x_5GHZ_5725_5850
,
105 static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all
= {
109 RTL819x_2GHZ_CH01_11
,
110 RTL819x_2GHZ_CH12_13
,
111 RTL819x_5GHZ_5150_5350
,
112 RTL819x_5GHZ_5470_5850
,
116 static const struct ieee80211_regdomain rtl_regdom_14
= {
120 RTL819x_2GHZ_CH01_11
,
121 RTL819x_2GHZ_CH12_13
,
126 static bool _rtl_is_radar_freq(u16 center_freq
)
128 return center_freq
>= 5260 && center_freq
<= 5700;
131 static void _rtl_reg_apply_beaconing_flags(struct wiphy
*wiphy
,
132 enum nl80211_reg_initiator initiator
)
134 enum nl80211_band band
;
135 struct ieee80211_supported_band
*sband
;
136 const struct ieee80211_reg_rule
*reg_rule
;
137 struct ieee80211_channel
*ch
;
140 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
142 if (!wiphy
->bands
[band
])
145 sband
= wiphy
->bands
[band
];
147 for (i
= 0; i
< sband
->n_channels
; i
++) {
148 ch
= &sband
->channels
[i
];
149 if (_rtl_is_radar_freq(ch
->center_freq
) ||
150 (ch
->flags
& IEEE80211_CHAN_RADAR
))
152 if (initiator
== NL80211_REGDOM_SET_BY_COUNTRY_IE
) {
153 reg_rule
= freq_reg_info(wiphy
,
155 if (IS_ERR(reg_rule
))
158 *If 11d had a rule for this channel ensure
159 *we enable adhoc/beaconing if it allows us to
160 *use it. Note that we would have disabled it
161 *by applying our static world regdomain by
162 *default during init, prior to calling our
166 if (!(reg_rule
->flags
& NL80211_RRF_NO_IBSS
))
167 ch
->flags
&= ~IEEE80211_CHAN_NO_IBSS
;
168 if (!(reg_rule
->flags
&
169 NL80211_RRF_PASSIVE_SCAN
))
171 ~IEEE80211_CHAN_PASSIVE_SCAN
;
173 if (ch
->beacon_found
)
174 ch
->flags
&= ~(IEEE80211_CHAN_NO_IBSS
|
175 IEEE80211_CHAN_PASSIVE_SCAN
);
181 /* Allows active scan scan on Ch 12 and 13 */
182 static void _rtl_reg_apply_active_scan_flags(struct wiphy
*wiphy
,
183 enum nl80211_reg_initiator
186 struct ieee80211_supported_band
*sband
;
187 struct ieee80211_channel
*ch
;
188 const struct ieee80211_reg_rule
*reg_rule
;
190 if (!wiphy
->bands
[NL80211_BAND_2GHZ
])
192 sband
= wiphy
->bands
[NL80211_BAND_2GHZ
];
195 *If no country IE has been received always enable active scan
196 *on these channels. This is only done for specific regulatory SKUs
198 if (initiator
!= NL80211_REGDOM_SET_BY_COUNTRY_IE
) {
199 ch
= &sband
->channels
[11]; /* CH 12 */
200 if (ch
->flags
& IEEE80211_CHAN_PASSIVE_SCAN
)
201 ch
->flags
&= ~IEEE80211_CHAN_PASSIVE_SCAN
;
202 ch
= &sband
->channels
[12]; /* CH 13 */
203 if (ch
->flags
& IEEE80211_CHAN_PASSIVE_SCAN
)
204 ch
->flags
&= ~IEEE80211_CHAN_PASSIVE_SCAN
;
209 *If a country IE has been recieved check its rule for this
210 *channel first before enabling active scan. The passive scan
211 *would have been enforced by the initial processing of our
212 *custom regulatory domain.
215 ch
= &sband
->channels
[11]; /* CH 12 */
216 reg_rule
= freq_reg_info(wiphy
, ch
->center_freq
);
217 if (!IS_ERR(reg_rule
)) {
218 if (!(reg_rule
->flags
& NL80211_RRF_PASSIVE_SCAN
))
219 if (ch
->flags
& IEEE80211_CHAN_PASSIVE_SCAN
)
220 ch
->flags
&= ~IEEE80211_CHAN_PASSIVE_SCAN
;
223 ch
= &sband
->channels
[12]; /* CH 13 */
224 reg_rule
= freq_reg_info(wiphy
, ch
->center_freq
);
225 if (!IS_ERR(reg_rule
)) {
226 if (!(reg_rule
->flags
& NL80211_RRF_PASSIVE_SCAN
))
227 if (ch
->flags
& IEEE80211_CHAN_PASSIVE_SCAN
)
228 ch
->flags
&= ~IEEE80211_CHAN_PASSIVE_SCAN
;
233 *Always apply Radar/DFS rules on
234 *freq range 5260 MHz - 5700 MHz
236 static void _rtl_reg_apply_radar_flags(struct wiphy
*wiphy
)
238 struct ieee80211_supported_band
*sband
;
239 struct ieee80211_channel
*ch
;
242 if (!wiphy
->bands
[NL80211_BAND_5GHZ
])
245 sband
= wiphy
->bands
[NL80211_BAND_5GHZ
];
247 for (i
= 0; i
< sband
->n_channels
; i
++) {
248 ch
= &sband
->channels
[i
];
249 if (!_rtl_is_radar_freq(ch
->center_freq
))
253 *We always enable radar detection/DFS on this
254 *frequency range. Additionally we also apply on
255 *this frequency range:
256 *- If STA mode does not yet have DFS supports disable
258 *- If adhoc mode does not support DFS yet then disable
259 * adhoc in the frequency.
260 *- If AP mode does not yet support radar detection/DFS
261 *do not allow AP mode
263 if (!(ch
->flags
& IEEE80211_CHAN_DISABLED
))
264 ch
->flags
|= IEEE80211_CHAN_RADAR
|
265 IEEE80211_CHAN_NO_IBSS
|
266 IEEE80211_CHAN_PASSIVE_SCAN
;
270 static void _rtl_reg_apply_world_flags(struct wiphy
*wiphy
,
271 enum nl80211_reg_initiator initiator
,
272 struct rtl_regulatory
*reg
)
274 _rtl_reg_apply_beaconing_flags(wiphy
, initiator
);
275 _rtl_reg_apply_active_scan_flags(wiphy
, initiator
);
279 static int _rtl_reg_notifier_apply(struct wiphy
*wiphy
,
280 struct regulatory_request
*request
,
281 struct rtl_regulatory
*reg
)
283 /* We always apply this */
284 _rtl_reg_apply_radar_flags(wiphy
);
286 switch (request
->initiator
) {
287 case NL80211_REGDOM_SET_BY_DRIVER
:
288 case NL80211_REGDOM_SET_BY_CORE
:
289 case NL80211_REGDOM_SET_BY_USER
:
291 case NL80211_REGDOM_SET_BY_COUNTRY_IE
:
292 _rtl_reg_apply_world_flags(wiphy
, request
->initiator
, reg
);
299 static const struct ieee80211_regdomain
*_rtl_regdomain_select(
300 struct rtl_regulatory
*reg
)
302 switch (reg
->country_code
) {
303 case COUNTRY_CODE_FCC
:
304 return &rtl_regdom_no_midband
;
305 case COUNTRY_CODE_IC
:
306 return &rtl_regdom_11
;
307 case COUNTRY_CODE_TELEC_NETGEAR
:
308 return &rtl_regdom_60_64
;
309 case COUNTRY_CODE_ETSI
:
310 case COUNTRY_CODE_SPAIN
:
311 case COUNTRY_CODE_FRANCE
:
312 case COUNTRY_CODE_ISRAEL
:
313 return &rtl_regdom_12_13
;
314 case COUNTRY_CODE_MKK
:
315 case COUNTRY_CODE_MKK1
:
316 case COUNTRY_CODE_TELEC
:
317 case COUNTRY_CODE_MIC
:
318 return &rtl_regdom_14_60_64
;
319 case COUNTRY_CODE_GLOBAL_DOMAIN
:
320 return &rtl_regdom_14
;
321 case COUNTRY_CODE_WORLD_WIDE_13
:
322 case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL
:
323 return &rtl_regdom_12_13_5g_all
;
325 return &rtl_regdom_no_midband
;
329 static int _rtl_regd_init_wiphy(struct rtl_regulatory
*reg
,
331 void (*reg_notifier
)(struct wiphy
*wiphy
,
332 struct regulatory_request
*
335 const struct ieee80211_regdomain
*regd
;
337 wiphy
->reg_notifier
= reg_notifier
;
339 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
340 wiphy
->regulatory_flags
&= ~REGULATORY_STRICT_REG
;
341 wiphy
->regulatory_flags
&= ~REGULATORY_DISABLE_BEACON_HINTS
;
342 regd
= _rtl_regdomain_select(reg
);
343 wiphy_apply_custom_regulatory(wiphy
, regd
);
344 _rtl_reg_apply_radar_flags(wiphy
);
345 _rtl_reg_apply_world_flags(wiphy
, NL80211_REGDOM_SET_BY_DRIVER
, reg
);
349 static struct country_code_to_enum_rd
*_rtl_regd_find_country(u16 countrycode
)
353 for (i
= 0; i
< ARRAY_SIZE(all_countries
); i
++) {
354 if (all_countries
[i
].countrycode
== countrycode
)
355 return &all_countries
[i
];
360 static u8
channel_plan_to_country_code(u8 channelplan
)
362 switch (channelplan
) {
365 return COUNTRY_CODE_WORLD_WIDE_13
;
367 return COUNTRY_CODE_IC
;
369 return COUNTRY_CODE_ETSI
;
371 return COUNTRY_CODE_TELEC_NETGEAR
;
373 return COUNTRY_CODE_GLOBAL_DOMAIN
;
375 return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL
;
377 return COUNTRY_CODE_MAX
; /*Error*/
381 int rtl_regd_init(struct ieee80211_hw
*hw
,
382 void (*reg_notifier
)(struct wiphy
*wiphy
,
383 struct regulatory_request
*request
))
385 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
386 struct wiphy
*wiphy
= hw
->wiphy
;
387 struct country_code_to_enum_rd
*country
= NULL
;
392 /* init country_code from efuse channel plan */
393 rtlpriv
->regd
.country_code
=
394 channel_plan_to_country_code(rtlpriv
->efuse
.channel_plan
);
396 rtl_dbg(rtlpriv
, COMP_REGD
, DBG_DMESG
,
397 "rtl: EEPROM regdomain: 0x%0x country code: %d\n",
398 rtlpriv
->efuse
.channel_plan
, rtlpriv
->regd
.country_code
);
400 if (rtlpriv
->regd
.country_code
>= COUNTRY_CODE_MAX
) {
401 rtl_dbg(rtlpriv
, COMP_REGD
, DBG_DMESG
,
402 "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n");
404 rtlpriv
->regd
.country_code
= COUNTRY_CODE_WORLD_WIDE_13
;
407 country
= _rtl_regd_find_country(rtlpriv
->regd
.country_code
);
410 rtlpriv
->regd
.alpha2
[0] = country
->iso_name
[0];
411 rtlpriv
->regd
.alpha2
[1] = country
->iso_name
[1];
413 rtlpriv
->regd
.alpha2
[0] = '0';
414 rtlpriv
->regd
.alpha2
[1] = '0';
417 rtl_dbg(rtlpriv
, COMP_REGD
, DBG_TRACE
,
418 "rtl: Country alpha2 being used: %c%c\n",
419 rtlpriv
->regd
.alpha2
[0], rtlpriv
->regd
.alpha2
[1]);
421 _rtl_regd_init_wiphy(&rtlpriv
->regd
, wiphy
, reg_notifier
);
426 void rtl_reg_notifier(struct wiphy
*wiphy
, struct regulatory_request
*request
)
428 struct ieee80211_hw
*hw
= wiphy_to_ieee80211_hw(wiphy
);
429 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
431 rtl_dbg(rtlpriv
, COMP_REGD
, DBG_LOUD
, "\n");
433 _rtl_reg_notifier_apply(wiphy
, request
, &rtlpriv
->regd
);