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