xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/os_dep/linux/wifi_regd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 
16 #include <drv_types.h>
17 
18 #ifdef CONFIG_IOCTL_CFG80211
rtw_regd_apply_flags(struct wiphy * wiphy)19 void rtw_regd_apply_flags(struct wiphy *wiphy)
20 {
21 	struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
22 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
23 	RT_CHANNEL_INFO *channel_set = rfctl->channel_set;
24 	u8 max_chan_nums = rfctl->max_chan_nums;
25 
26 	struct ieee80211_supported_band *sband;
27 	struct ieee80211_channel *ch;
28 	unsigned int i, j;
29 	u16 channel;
30 	u32 freq;
31 
32 	/* all channels disable */
33 	for (i = 0; i < NUM_NL80211_BANDS; i++) {
34 		sband = wiphy->bands[i];
35 		if (!sband)
36 			continue;
37 		for (j = 0; j < sband->n_channels; j++) {
38 			ch = &sband->channels[j];
39 			if (!ch)
40 				continue;
41 			ch->flags = IEEE80211_CHAN_DISABLED;
42 		}
43 	}
44 
45 	/* channels apply by channel plans. */
46 	for (i = 0; i < max_chan_nums; i++) {
47 		channel = channel_set[i].ChannelNum;
48 		freq = rtw_ch2freq(channel);
49 		ch = ieee80211_get_channel(wiphy, freq);
50 		if (!ch)
51 			continue;
52 
53 		/* enable */
54 		ch->flags = 0;
55 
56 		if (channel_set[i].dfs) {
57 			/*
58 			* before integrating with nl80211 flow
59 			* bypass IEEE80211_CHAN_RADAR when configured with radar detection
60 			* to prevent from hostapd blocking DFS channels
61 			*/
62 			if (rtw_rfctl_dfs_domain_unknown(rfctl))
63 				ch->flags |= IEEE80211_CHAN_RADAR;
64 		}
65 
66 		if (channel_set[i].ScanType == SCAN_PASSIVE) {
67 			#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
68 			ch->flags |= IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN;
69 			#else
70 			ch->flags |= IEEE80211_CHAN_NO_IR;
71 			#endif
72 		}
73 	}
74 }
75 
rtw_reg_notifier(struct wiphy * wiphy,struct regulatory_request * request)76 static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
77 {
78 	switch (request->initiator) {
79 	case NL80211_REGDOM_SET_BY_DRIVER:
80 		RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER");
81 		break;
82 	case NL80211_REGDOM_SET_BY_CORE:
83 		RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_CORE");
84 		break;
85 	case NL80211_REGDOM_SET_BY_USER:
86 		RTW_INFO("%s: %s alpha2:%c%c\n", __func__, "NL80211_REGDOM_SET_BY_USER"
87 			, request->alpha2[0], request->alpha2[1]);
88 		rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2);
89 		break;
90 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
91 		RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_COUNTRY_IE");
92 		break;
93 	}
94 
95 	rtw_regd_apply_flags(wiphy);
96 }
97 
98 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
rtw_reg_notifier_return(struct wiphy * wiphy,struct regulatory_request * request)99 static int rtw_reg_notifier_return(struct wiphy *wiphy, struct regulatory_request *request)
100 {
101 	rtw_reg_notifier(wiphy, request);
102 	return 0;
103 }
104 #endif
105 
rtw_regd_init(struct wiphy * wiphy)106 int rtw_regd_init(struct wiphy *wiphy)
107 {
108 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
109 	wiphy->reg_notifier = rtw_reg_notifier_return;
110 #else
111 	wiphy->reg_notifier = rtw_reg_notifier;
112 #endif
113 
114 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
115 	wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
116 	wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
117 	wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
118 #else
119 	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
120 	wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
121 	wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
122 #endif
123 
124 	rtw_regd_apply_flags(wiphy);
125 
126 	return 0;
127 }
128 #endif /* CONFIG_IOCTL_CFG80211 */
129