add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8723bs / os_dep / linux / wifi_regd.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  Realtek Corporation.
4  *
5  *****************************************************************************/
6
7 #include <drv_types.h>
8
9 #ifdef CONFIG_IOCTL_CFG80211
10
11 #include <rtw_wifi_regd.h>
12
13 static struct country_code_to_enum_rd allCountries[] = {
14         {COUNTRY_CODE_USER, "RD"},
15 };
16
17 /* 
18  * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags)
19  */
20
21 /*
22  *Only these channels all allow active
23  *scan on all world regulatory domains
24  */
25
26 /* 2G chan 01 - chan 11 */
27 #define RTW_2GHZ_CH01_11        \
28         REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
29
30 /*
31  *We enable active scan on these a case
32  *by case basis by regulatory domain
33  */
34
35 /* 2G chan 12 - chan 13, PASSIV SCAN */
36 #define RTW_2GHZ_CH12_13        \
37         REG_RULE(2467-10, 2472+10, 40, 0, 20,   \
38         NL80211_RRF_PASSIVE_SCAN)
39
40 /* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */
41 #define RTW_2GHZ_CH14   \
42         REG_RULE(2484-10, 2484+10, 40, 0, 20,   \
43         NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
44
45 /* 5G chan 36 - chan 64 */
46 #define RTW_5GHZ_5150_5350      \
47         REG_RULE(5150-10, 5350+10, 40, 0, 30,   \
48         NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
49
50 /* 5G chan 100 - chan 165 */
51 #define RTW_5GHZ_5470_5850      \
52         REG_RULE(5470-10, 5850+10, 40, 0, 30, \
53         NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
54
55 /* 5G chan 149 - chan 165 */
56 #define RTW_5GHZ_5725_5850      \
57         REG_RULE(5725-10, 5850+10, 40, 0, 30, \
58         NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
59
60 /* 5G chan 36 - chan 165 */
61 #define RTW_5GHZ_5150_5850      \
62         REG_RULE(5150-10, 5850+10, 40, 0, 30,   \
63         NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
64
65 static const struct ieee80211_regdomain rtw_regdom_rd = {
66         .n_reg_rules = 3,
67         .alpha2 = "99",
68         .reg_rules = {
69                       RTW_2GHZ_CH01_11,
70                       RTW_2GHZ_CH12_13,
71                       RTW_5GHZ_5150_5850,
72                       }
73 };
74
75 static const struct ieee80211_regdomain rtw_regdom_11 = {
76         .n_reg_rules = 1,
77         .alpha2 = "99",
78         .reg_rules = {
79                       RTW_2GHZ_CH01_11,
80                       }
81 };
82
83 static const struct ieee80211_regdomain rtw_regdom_12_13 = {
84         .n_reg_rules = 2,
85         .alpha2 = "99",
86         .reg_rules = {
87                       RTW_2GHZ_CH01_11,
88                       RTW_2GHZ_CH12_13,
89                       }
90 };
91
92 static const struct ieee80211_regdomain rtw_regdom_no_midband = {
93         .n_reg_rules = 3,
94         .alpha2 = "99",
95         .reg_rules = {
96                       RTW_2GHZ_CH01_11,
97                       RTW_5GHZ_5150_5350,
98                       RTW_5GHZ_5725_5850,
99                       }
100 };
101
102 static const struct ieee80211_regdomain rtw_regdom_60_64 = {
103         .n_reg_rules = 3,
104         .alpha2 = "99",
105         .reg_rules = {
106                       RTW_2GHZ_CH01_11,
107                       RTW_2GHZ_CH12_13,
108                       RTW_5GHZ_5725_5850,
109                       }
110 };
111
112 static const struct ieee80211_regdomain rtw_regdom_14_60_64 = {
113         .n_reg_rules = 4,
114         .alpha2 = "99",
115         .reg_rules = {
116                       RTW_2GHZ_CH01_11,
117                       RTW_2GHZ_CH12_13,
118                       RTW_2GHZ_CH14,
119                       RTW_5GHZ_5725_5850,
120                       }
121 };
122
123 static const struct ieee80211_regdomain rtw_regdom_14 = {
124         .n_reg_rules = 3,
125         .alpha2 = "99",
126         .reg_rules = {
127                       RTW_2GHZ_CH01_11,
128                       RTW_2GHZ_CH12_13,
129                       RTW_2GHZ_CH14,
130                       }
131 };
132
133 #if 0
134 static struct rtw_regulatory *rtw_regd;
135 #endif
136
137 static bool _rtw_is_radar_freq(u16 center_freq)
138 {
139         return (center_freq >= 5260 && center_freq <= 5700);
140 }
141
142 #if 0 // not_yet
143 static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy,
144                                            enum nl80211_reg_initiator initiator)
145 {
146         enum ieee80211_band band;
147         struct ieee80211_supported_band *sband;
148         const struct ieee80211_reg_rule *reg_rule;
149         struct ieee80211_channel *ch;
150         unsigned int i;
151         u32 bandwidth = 0;
152         int r;
153
154         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
155
156                 if (!wiphy->bands[band])
157                         continue;
158
159                 sband = wiphy->bands[band];
160
161                 for (i = 0; i < sband->n_channels; i++) {
162                         ch = &sband->channels[i];
163                         if (_rtw_is_radar_freq(ch->center_freq) ||
164                             (ch->flags & IEEE80211_CHAN_RADAR))
165                                 continue;
166                         if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
167                                 r = freq_reg_info(wiphy, ch->center_freq,
168                                                   bandwidth, &reg_rule);
169                                 if (r)
170                                         continue;
171
172                                 /*
173                                  *If 11d had a rule for this channel ensure
174                                  *we enable adhoc/beaconing if it allows us to
175                                  *use it. Note that we would have disabled it
176                                  *by applying our static world regdomain by
177                                  *default during init, prior to calling our
178                                  *regulatory_hint().
179                                  */
180
181                                 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
182                                         ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
183                                 if (!
184                                     (reg_rule->flags &
185                                      NL80211_RRF_PASSIVE_SCAN))
186                                         ch->flags &=
187                                             ~IEEE80211_CHAN_PASSIVE_SCAN;
188                         } else {
189                                 if (ch->beacon_found)
190                                         ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
191                                                        IEEE80211_CHAN_PASSIVE_SCAN);
192                         }
193                 }
194         }
195 }
196
197 /* Allows active scan scan on Ch 12 and 13 */
198 static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy,
199                                              enum nl80211_reg_initiator
200                                              initiator)
201 {
202         struct ieee80211_supported_band *sband;
203         struct ieee80211_channel *ch;
204         const struct ieee80211_reg_rule *reg_rule;
205         u32 bandwidth = 0;
206         int r;
207
208         if (!wiphy->bands[IEEE80211_BAND_2GHZ])
209                 return;
210         sband = wiphy->bands[IEEE80211_BAND_2GHZ];
211
212         /*
213          * If no country IE has been received always enable active scan
214          * on these channels. This is only done for specific regulatory SKUs
215          */
216         if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
217                 ch = &sband->channels[11];      /* CH 12 */
218                 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
219                         ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
220                 ch = &sband->channels[12];      /* CH 13 */
221                 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
222                         ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
223                 return;
224         }
225
226         /*
227          * If a country IE has been received check its rule for this
228          * channel first before enabling active scan. The passive scan
229          * would have been enforced by the initial processing of our
230          * custom regulatory domain.
231          */
232
233         ch = &sband->channels[11];      /* CH 12 */
234         r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
235         if (!r) {
236                 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
237                         if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
238                                 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
239         }
240
241         ch = &sband->channels[12];      /* CH 13 */
242         r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
243         if (!r) {
244                 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
245                         if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
246                                 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
247         }
248 }
249 #endif
250
251 /*
252  * Always apply Radar/DFS rules on
253  * freq range 5260 MHz - 5700 MHz
254  */
255 static void _rtw_reg_apply_radar_flags(struct wiphy *wiphy)
256 {
257         struct ieee80211_supported_band *sband;
258         struct ieee80211_channel *ch;
259         unsigned int i;
260
261         if (!wiphy->bands[IEEE80211_BAND_5GHZ])
262                 return;
263
264         sband = wiphy->bands[IEEE80211_BAND_5GHZ];
265
266         for (i = 0; i < sband->n_channels; i++) {
267                 ch = &sband->channels[i];
268                 if (!_rtw_is_radar_freq(ch->center_freq))
269                         continue;
270 #ifdef CONFIG_DFS
271                 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
272                         ch->flags |= IEEE80211_CHAN_RADAR |
273                             IEEE80211_CHAN_NO_IBSS;
274 #endif
275
276 #if 0
277                 /*
278                  * We always enable radar detection/DFS on this
279                  * frequency range. Additionally we also apply on
280                  * this frequency range:
281                  * - If STA mode does not yet have DFS supports disable
282                  *  active scanning
283                  * - If adhoc mode does not support DFS yet then disable
284                  *  adhoc in the frequency.
285                  * - If AP mode does not yet support radar detection/DFS
286                  *  do not allow AP mode
287                  */
288                 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
289                         ch->flags |= IEEE80211_CHAN_RADAR |
290                             IEEE80211_CHAN_NO_IBSS |
291                             IEEE80211_CHAN_PASSIVE_SCAN;
292 #endif
293         }
294 }
295
296 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
297 {
298         /* see 802.11 17.3.8.3.2 and Annex J
299          * there are overlapping channel numbers in 5GHz and 2GHz bands */
300
301         if (band == IEEE80211_BAND_5GHZ) {
302                 if (chan >= 182 && chan <= 196)
303                         return 4000 + chan * 5;
304                 else
305                         return 5000 + chan * 5;
306         } else {                /* IEEE80211_BAND_2GHZ */
307                 if (chan == 14)
308                         return 2484;
309                 else if (chan < 14)
310                         return 2407 + chan * 5;
311                 else
312                         return 0;       /* not supported */
313         }
314 }
315
316 static void _rtw_reg_apply_flags(struct wiphy *wiphy)
317 {
318 #if 1                           // by channel plan
319         _adapter *padapter = wiphy_to_adapter(wiphy);
320         u8 channel_plan = padapter->mlmepriv.ChannelPlan;
321         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
322         RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set;
323         u8 max_chan_nums = pmlmeext->max_chan_nums;
324
325         struct ieee80211_supported_band *sband;
326         struct ieee80211_channel *ch;
327         unsigned int i, j;
328         u16 channel;
329         u32 freq;
330
331         // all channels disable
332         for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
333                 sband = wiphy->bands[i];
334
335                 if (sband) {
336                         for (j = 0; j < sband->n_channels; j++) {
337                                 ch = &sband->channels[j];
338
339                                 if (ch)
340                                         ch->flags = IEEE80211_CHAN_DISABLED;
341                         }
342                 }
343         }
344
345         // channels apply by channel plans.
346         for (i = 0; i < max_chan_nums; i++) {
347                 channel = channel_set[i].ChannelNum;
348                 if (channel <= 14)
349                         freq =
350                             rtw_ieee80211_channel_to_frequency(channel,
351                                                                IEEE80211_BAND_2GHZ);
352                 else
353                         freq =
354                             rtw_ieee80211_channel_to_frequency(channel,
355                                                                IEEE80211_BAND_5GHZ);
356
357                 ch = ieee80211_get_channel(wiphy, freq);
358                 if (ch) {
359                         if (channel_set[i].ScanType == SCAN_PASSIVE)
360                                 ch->flags = IEEE80211_CHAN_PASSIVE_SCAN;
361                         else
362                                 ch->flags = 0;
363                 }
364         }
365
366 #else
367         struct ieee80211_supported_band *sband;
368         struct ieee80211_channel *ch;
369         unsigned int i, j;
370         u16 channels[37] =
371             { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56,
372                 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
373                 149, 153,
374                 157, 161, 165
375         };
376         u16 channel;
377         u32 freq;
378
379         for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
380                 sband = wiphy->bands[i];
381
382                 if (sband)
383                         for (j = 0; j < sband->n_channels; j++) {
384                                 ch = &sband->channels[j];
385
386                                 if (ch)
387                                         ch->flags = IEEE80211_CHAN_DISABLED;
388                         }
389         }
390
391         for (i = 0; i < 37; i++) {
392                 channel = channels[i];
393                 if (channel <= 14)
394                         freq =
395                             rtw_ieee80211_channel_to_frequency(channel,
396                                                                IEEE80211_BAND_2GHZ);
397                 else
398                         freq =
399                             rtw_ieee80211_channel_to_frequency(channel,
400                                                                IEEE80211_BAND_5GHZ);
401
402                 ch = ieee80211_get_channel(wiphy, freq);
403                 if (ch) {
404                         if (channel <= 11)
405                                 ch->flags = 0;
406                         else
407                                 ch->flags = 0;  //IEEE80211_CHAN_PASSIVE_SCAN;
408                 }
409                 //printk("%s: freq %d(%d) flag 0x%02X \n", __func__, freq, channel, ch->flags);
410         }
411 #endif
412 }
413
414 static void _rtw_reg_apply_world_flags(struct wiphy *wiphy,
415                                        enum nl80211_reg_initiator initiator,
416                                        struct rtw_regulatory *reg)
417 {
418         //_rtw_reg_apply_beaconing_flags(wiphy, initiator);
419         //_rtw_reg_apply_active_scan_flags(wiphy, initiator);
420         return;
421 }
422
423 static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
424                                    struct regulatory_request *request,
425                                    struct rtw_regulatory *reg)
426 {
427
428         /* Hard code flags */
429         _rtw_reg_apply_flags(wiphy);
430
431         /* We always apply this */
432         _rtw_reg_apply_radar_flags(wiphy);
433
434         switch (request->initiator) {
435         case NL80211_REGDOM_SET_BY_DRIVER:
436                 DBG_8192C("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER");
437                 _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
438                                            reg);
439                 break;
440         case NL80211_REGDOM_SET_BY_CORE:
441                 DBG_8192C("%s: %s\n", __func__,
442                           "NL80211_REGDOM_SET_BY_CORE to DRV");
443                 _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
444                                            reg);
445                 break;
446         case NL80211_REGDOM_SET_BY_USER:
447                 DBG_8192C("%s: %s\n", __func__,
448                           "NL80211_REGDOM_SET_BY_USER to DRV");
449                 _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
450                                            reg);
451                 break;
452         case NL80211_REGDOM_SET_BY_COUNTRY_IE:
453                 DBG_8192C("%s: %s\n", __func__,
454                           "NL80211_REGDOM_SET_BY_COUNTRY_IE");
455                 _rtw_reg_apply_world_flags(wiphy, request->initiator, reg);
456                 break;
457         }
458
459         return 0;
460 }
461
462 static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
463                                                                rtw_regulatory
464                                                                *reg)
465 {
466 #if 0
467         switch (reg->country_code) {
468         case COUNTRY_CODE_USER:
469         default:
470                 return &rtw_regdom_rd;
471         }
472 #else
473         return &rtw_regdom_rd;
474 #endif
475 }
476
477 static int _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
478                                 struct wiphy *wiphy,
479                                 int (*reg_notifier) (struct wiphy * wiphy,
480                                                      struct regulatory_request *
481                                                      request))
482 {
483         const struct ieee80211_regdomain *regd;
484
485         wiphy->reg_notifier = reg_notifier;
486
487         wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
488         wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
489         wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
490
491         regd = _rtw_regdomain_select(reg);
492         wiphy_apply_custom_regulatory(wiphy, regd);
493
494         /* Hard code flags */
495         _rtw_reg_apply_flags(wiphy);
496         _rtw_reg_apply_radar_flags(wiphy);
497         _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
498         return 0;
499 }
500
501 static struct country_code_to_enum_rd *_rtw_regd_find_country(u16 countrycode)
502 {
503         int i;
504
505         for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
506                 if (allCountries[i].countrycode == countrycode)
507                         return &allCountries[i];
508         }
509         return NULL;
510 }
511
512 int rtw_regd_init(_adapter * padapter,
513                   int (*reg_notifier) (struct wiphy * wiphy,
514                                        struct regulatory_request * request))
515 {
516         //struct registry_priv  *registrypriv = &padapter->registrypriv;
517         struct wiphy *wiphy = padapter->rtw_wdev->wiphy;
518
519 #if 0
520         if (rtw_regd == NULL) {
521                 rtw_regd = (struct rtw_regulatory *)
522                     rtw_malloc(sizeof(struct rtw_regulatory));
523
524                 rtw_regd->alpha2[0] = '9';
525                 rtw_regd->alpha2[1] = '9';
526
527                 rtw_regd->country_code = COUNTRY_CODE_USER;
528         }
529
530         DBG_8192C("%s: Country alpha2 being used: %c%c\n",
531                   __func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]);
532 #endif
533
534         _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
535
536         return 0;
537 }
538
539 int rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
540 {
541         struct rtw_regulatory *reg = NULL;
542
543         DBG_8192C("%s\n", __func__);
544
545         return _rtw_reg_notifier_apply(wiphy, request, reg);
546 }
547 #endif //CONFIG_IOCTL_CFG80211