1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2009-2010 Realtek Corporation.
5 *
6 *****************************************************************************/
7
8 #include <drv_types.h>
9
10 #include <rtw_wifi_regd.h>
11
12 /*
13 * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags)
14 */
15
16 /*
17 * Only these channels all allow active
18 * scan on all world regulatory domains
19 */
20
21 /* 2G chan 01 - chan 11 */
22 #define RTW_2GHZ_CH01_11 \
23 REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0)
24
25 /*
26 * We enable active scan on these a case
27 * by case basis by regulatory domain
28 */
29
30 /* 2G chan 12 - chan 13, PASSIV SCAN */
31 #define RTW_2GHZ_CH12_13 \
32 REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20, \
33 NL80211_RRF_PASSIVE_SCAN)
34
35 static const struct ieee80211_regdomain rtw_regdom_rd = {
36 .n_reg_rules = 2,
37 .alpha2 = "99",
38 .reg_rules = {
39 RTW_2GHZ_CH01_11,
40 RTW_2GHZ_CH12_13,
41 }
42 };
43
rtw_ieee80211_channel_to_frequency(int chan,int band)44 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
45 {
46 /* NL80211_BAND_2GHZ */
47 if (chan == 14)
48 return 2484;
49 else if (chan < 14)
50 return 2407 + chan * 5;
51 else
52 return 0; /* not supported */
53 }
54
_rtw_reg_apply_flags(struct wiphy * wiphy)55 static void _rtw_reg_apply_flags(struct wiphy *wiphy)
56 {
57 struct adapter *padapter = wiphy_to_adapter(wiphy);
58 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
59 struct rt_channel_info *channel_set = pmlmeext->channel_set;
60 u8 max_chan_nums = pmlmeext->max_chan_nums;
61
62 struct ieee80211_supported_band *sband;
63 struct ieee80211_channel *ch;
64 unsigned int i, j;
65 u16 channel;
66 u32 freq;
67
68 /* all channels disable */
69 for (i = 0; i < NUM_NL80211_BANDS; i++) {
70 sband = wiphy->bands[i];
71
72 if (sband) {
73 for (j = 0; j < sband->n_channels; j++) {
74 ch = &sband->channels[j];
75
76 if (ch)
77 ch->flags = IEEE80211_CHAN_DISABLED;
78 }
79 }
80 }
81
82 /* channels apply by channel plans. */
83 for (i = 0; i < max_chan_nums; i++) {
84 channel = channel_set[i].ChannelNum;
85 freq =
86 rtw_ieee80211_channel_to_frequency(channel,
87 NL80211_BAND_2GHZ);
88
89 ch = ieee80211_get_channel(wiphy, freq);
90 if (ch) {
91 if (channel_set[i].ScanType == SCAN_PASSIVE)
92 ch->flags = IEEE80211_CHAN_NO_IR;
93 else
94 ch->flags = 0;
95 }
96 }
97 }
98
_rtw_reg_notifier_apply(struct wiphy * wiphy,struct regulatory_request * request,struct rtw_regulatory * reg)99 static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
100 struct regulatory_request *request,
101 struct rtw_regulatory *reg)
102 {
103 /* Hard code flags */
104 _rtw_reg_apply_flags(wiphy);
105 return 0;
106 }
107
_rtw_regdomain_select(struct rtw_regulatory * reg)108 static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
109 rtw_regulatory
110 *reg)
111 {
112 return &rtw_regdom_rd;
113 }
114
_rtw_regd_init_wiphy(struct rtw_regulatory * reg,struct wiphy * wiphy,void (* reg_notifier)(struct wiphy * wiphy,struct regulatory_request * request))115 static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
116 struct wiphy *wiphy,
117 void (*reg_notifier)(struct wiphy *wiphy,
118 struct
119 regulatory_request *
120 request))
121 {
122 const struct ieee80211_regdomain *regd;
123
124 wiphy->reg_notifier = reg_notifier;
125
126 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
127 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
128 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
129
130 regd = _rtw_regdomain_select(reg);
131 wiphy_apply_custom_regulatory(wiphy, regd);
132
133 /* Hard code flags */
134 _rtw_reg_apply_flags(wiphy);
135 }
136
rtw_regd_init(struct wiphy * wiphy,void (* reg_notifier)(struct wiphy * wiphy,struct regulatory_request * request))137 void rtw_regd_init(struct wiphy *wiphy,
138 void (*reg_notifier)(struct wiphy *wiphy,
139 struct regulatory_request *request))
140 {
141 _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
142 }
143
rtw_reg_notifier(struct wiphy * wiphy,struct regulatory_request * request)144 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
145 {
146 struct rtw_regulatory *reg = NULL;
147
148 _rtw_reg_notifier_apply(wiphy, request, reg);
149 }
150