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