xref: /linux/drivers/staging/rtl8723bs/os_dep/wifi_regd.c (revision 1641684528815bb7e85737d5d2bceb551c55d5a8)
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_reg_apply_flags(struct wiphy * wiphy)44 static void _rtw_reg_apply_flags(struct wiphy *wiphy)
45 {
46 	struct adapter *padapter = wiphy_to_adapter(wiphy);
47 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
48 	struct rt_channel_info *channel_set = pmlmeext->channel_set;
49 	u8 max_chan_nums = pmlmeext->max_chan_nums;
50 
51 	struct ieee80211_supported_band *sband;
52 	struct ieee80211_channel *ch;
53 	unsigned int i, j;
54 	u16 channel;
55 	u32 freq;
56 
57 	/* all channels disable */
58 	for (i = 0; i < NUM_NL80211_BANDS; i++) {
59 		sband = wiphy->bands[i];
60 
61 		if (sband) {
62 			for (j = 0; j < sband->n_channels; j++) {
63 				ch = &sband->channels[j];
64 
65 				if (ch)
66 					ch->flags = IEEE80211_CHAN_DISABLED;
67 			}
68 		}
69 	}
70 
71 	/* channels apply by channel plans. */
72 	for (i = 0; i < max_chan_nums; i++) {
73 		channel = channel_set[i].ChannelNum;
74 		freq = rtw_ieee80211_channel_to_frequency(channel);
75 		ch = ieee80211_get_channel(wiphy, freq);
76 		if (ch) {
77 			if (channel_set[i].ScanType == SCAN_PASSIVE)
78 				ch->flags = IEEE80211_CHAN_NO_IR;
79 			else
80 				ch->flags = 0;
81 		}
82 	}
83 }
84 
_rtw_reg_notifier_apply(struct wiphy * wiphy,struct regulatory_request * request,struct rtw_regulatory * reg)85 static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
86 				   struct regulatory_request *request,
87 				   struct rtw_regulatory *reg)
88 {
89 	/* Hard code flags */
90 	_rtw_reg_apply_flags(wiphy);
91 	return 0;
92 }
93 
_rtw_regdomain_select(struct rtw_regulatory * reg)94 static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
95 							       rtw_regulatory
96 							       *reg)
97 {
98 	return &rtw_regdom_rd;
99 }
100 
_rtw_regd_init_wiphy(struct rtw_regulatory * reg,struct wiphy * wiphy,void (* reg_notifier)(struct wiphy * wiphy,struct regulatory_request * request))101 static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
102 				 struct wiphy *wiphy,
103 				 void (*reg_notifier)(struct wiphy *wiphy,
104 						      struct
105 						      regulatory_request *
106 						      request))
107 {
108 	const struct ieee80211_regdomain *regd;
109 
110 	wiphy->reg_notifier = reg_notifier;
111 
112 	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
113 	wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
114 	wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
115 
116 	regd = _rtw_regdomain_select(reg);
117 	wiphy_apply_custom_regulatory(wiphy, regd);
118 
119 	/* Hard code flags */
120 	_rtw_reg_apply_flags(wiphy);
121 }
122 
rtw_regd_init(struct wiphy * wiphy,void (* reg_notifier)(struct wiphy * wiphy,struct regulatory_request * request))123 void rtw_regd_init(struct wiphy *wiphy,
124 		   void (*reg_notifier)(struct wiphy *wiphy,
125 					struct regulatory_request *request))
126 {
127 	_rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
128 }
129 
rtw_reg_notifier(struct wiphy * wiphy,struct regulatory_request * request)130 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
131 {
132 	struct rtw_regulatory *reg = NULL;
133 
134 	_rtw_reg_notifier_apply(wiphy, request, reg);
135 }
136