1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "oal_ext_if.h"
23 #include "wal_event_msg.h"
24 #include "wal_main.h"
25 #include "wal_regdb.h"
26 #include "wal_11d.h"
27 #include "wal_ioctl.h"
28 #include "wal_cfg80211.h"
29
30 #ifdef __cplusplus
31 #if __cplusplus
32 extern "C" {
33 #endif
34 #endif
35
36 /* ****************************************************************************
37 2 全局变量定义
38 **************************************************************************** */
39 const wal_dfs_domain_entry_stru g_ast_dfs_domain_table[] = {
40 {"AE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
41 {"AL", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
42 {"AM", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
43 {"AN", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
44 {"AR", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
45 {"AT", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
46 {"AU", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
47 {"AZ", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
48 {"BA", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
49 {"BE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
50 {"BG", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
51 {"BH", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
52 {"BL", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
53 {"BN", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
54 {"BO", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
55 {"BR", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
56 {"BY", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
57 {"BZ", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
58 {"CA", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
59 {"CH", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
60 {"CL", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
61 {"CN", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
62 {"CO", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
63 {"CR", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
64 {"CS", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
65 {"CY", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
66 {"CZ", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
67 {"DE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
68 {"DK", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
69 {"DO", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
70 {"DZ", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
71 {"EC", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
72 {"EE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
73 {"EG", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
74 {"ES", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
75 {"FI", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
76 {"FR", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
77 {"GB", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
78 {"GE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
79 {"GR", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
80 {"GT", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
81 {"HK", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
82 {"HN", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
83 {"HR", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
84 {"HU", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
85 {"ID", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
86 {"IE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
87 {"IL", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
88 {"IN", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
89 {"IQ", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
90 {"IR", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
91 {"IS", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
92 {"IT", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
93 {"JM", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
94 {"JO", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
95 {"JP", MAC_DFS_DOMAIN_MKK, {0, 0, 0}},
96 {"KP", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
97 {"KR", MAC_DFS_DOMAIN_KOREA, {0, 0, 0}},
98 {"KW", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
99 {"KZ", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
100 {"LB", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
101 {"LI", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
102 {"LK", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
103 {"LT", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
104 {"LU", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
105 {"LV", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
106 {"MA", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
107 {"MC", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
108 {"MK", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
109 {"MO", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
110 {"MT", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
111 {"MX", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
112 {"MY", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
113 {"NG", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
114 {"NL", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
115 {"NO", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
116 {"NP", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
117 {"NZ", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
118 {"OM", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
119 {"PA", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
120 {"PE", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
121 {"PG", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
122 {"PH", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
123 {"PK", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
124 {"PL", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
125 {"PR", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
126 {"PT", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
127 {"QA", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
128 {"RO", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
129 {"RU", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
130 {"SA", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
131 {"SE", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
132 {"SG", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
133 {"SI", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
134 {"SK", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
135 {"SV", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
136 {"SY", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
137 {"TH", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
138 {"TN", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
139 {"TR", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
140 {"TT", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
141 {"TW", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
142 {"UA", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
143 {"US", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
144 {"UY", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
145 {"UZ", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
146 {"VE", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
147 {"VN", MAC_DFS_DOMAIN_ETSI, {0, 0, 0}},
148 {"YE", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
149 {"ZA", MAC_DFS_DOMAIN_FCC, {0, 0, 0}},
150 {"ZW", MAC_DFS_DOMAIN_NULL, {0, 0, 0}},
151 };
152
153 /* ****************************************************************************
154 3 函数实现
155 **************************************************************************** */
156 /* ****************************************************************************
157 功能描述 : 获取一个管制类的起始频带
158 输入参数 : ul_start_freq: 起始频率
159 ul_end_freq : 结束频率
160 **************************************************************************** */
wal_regdomain_get_band(hi_u32 start_freq,hi_u32 end_freq)161 static inline hi_u8 wal_regdomain_get_band(hi_u32 start_freq, hi_u32 end_freq)
162 {
163 if (start_freq > 2400 && end_freq < 2500) { /* 2400 起始频率的最小值 2500 结束频率的最大值 */
164 return MAC_RC_START_FREQ_2;
165 }
166 return MAC_RC_START_FREQ_BUTT;
167 }
168
169 /* ****************************************************************************
170 功能描述 : 获取一个管制类的带宽
171 输入参数 : uc_bw: linux管制类中的带宽值
172 **************************************************************************** */
wal_regdomain_get_bw(hi_u8 bw)173 static inline hi_u8 wal_regdomain_get_bw(hi_u8 bw)
174 {
175 switch (bw) {
176 case 40: /* 40 带宽为40MHZ */
177 return MAC_CH_SPACING_40MHZ;
178 case 20: /* 20 带宽为20MHZ */
179 return MAC_CH_SPACING_20MHZ;
180 default:
181 return MAC_CH_SPACING_BUTT;
182 }
183 }
184
185 /* ****************************************************************************
186 功能描述 : 获取管制类信道位图,信道在2g频段上
187 输入参数 : ul_start_freq: 起始频率
188 ul_end_freq : 结束频率
189 **************************************************************************** */
wal_regdomain_get_channel_2g(hi_u32 start_freq,hi_u32 end_freq)190 static hi_u32 wal_regdomain_get_channel_2g(hi_u32 start_freq, hi_u32 end_freq)
191 {
192 hi_u32 freq;
193 hi_u32 i;
194 hi_u32 ch_bmap = 0;
195 mac_freq_channel_map_stru ast_freq_map_2g;
196
197 for (freq = start_freq + 10; freq <= (end_freq - 10); freq++) { /* 10 带宽 */
198 for (i = 0; i < MAC_CHANNEL_FREQ_2_BUTT; i++) {
199 ast_freq_map_2g = get_ast_freq_map_2g_elem(i);
200 if (freq == ast_freq_map_2g.us_freq) {
201 ch_bmap |= (1 << i);
202 }
203 }
204 }
205
206 return ch_bmap;
207 }
208
209 /* ****************************************************************************
210 功能描述 : 获取1个管制类的信道位图
211 输入参数 : uc_band : 频段
212 ul_start_freq: 起始频率
213 ul_end_freq : 中止频率
214 **************************************************************************** */
wal_regdomain_get_channel(hi_u8 band,hi_u32 start_freq,hi_u32 end_freq)215 static inline hi_u32 wal_regdomain_get_channel(hi_u8 band, hi_u32 start_freq, hi_u32 end_freq)
216 {
217 if (band == MAC_RC_START_FREQ_2) {
218 return wal_regdomain_get_channel_2g(start_freq, end_freq);
219 }
220 return 0;
221 }
222
223 /* ****************************************************************************
224 函 数 名 : wal_get_dfs_domain
225 功能描述 : 根据国家码,获取对应的雷达检测标准
226 输入参数 : pst_mac_regdom: 管制域指针
227 pc_country : 国家码
228 输出参数 : pst_mac_regdom: 管制域指针
229 返 回 值 : 无
230 调用函数 :
231 被调函数 :
232
233 修改历史 :
234 1.日 期 : 2014年10月31日
235 作 者 : HiSilicon
236 修改内容 : 新生成函数
237
238 **************************************************************************** */
wal_get_dfs_domain(mac_regdomain_info_stru * mac_regdom,const hi_char * pc_country)239 static inline hi_void wal_get_dfs_domain(mac_regdomain_info_stru *mac_regdom, const hi_char *pc_country)
240 {
241 hi_u32 u_idx;
242
243 for (u_idx = 0; u_idx < hi_array_size(g_ast_dfs_domain_table); u_idx++) {
244 if (0 == strcmp(g_ast_dfs_domain_table[u_idx].pc_country, pc_country)) {
245 mac_regdom->dfs_domain = g_ast_dfs_domain_table[u_idx].dfs_domain;
246 return;
247 }
248 }
249
250 mac_regdom->dfs_domain = MAC_DFS_DOMAIN_NULL;
251 }
252
253 /* ****************************************************************************
254 功能描述 : 填充管制下发的管制域信息
255 输入参数 : pst_regdom : 指向linux的管制域信息
256 pst_mac_regdom: 指向要下发的管制域信息
257 **************************************************************************** */
wal_regdomain_fill_info(const oal_ieee80211_regdomain_stru * regdom,mac_regdomain_info_stru * mac_regdom)258 static hi_u32 wal_regdomain_fill_info(const oal_ieee80211_regdomain_stru *regdom, mac_regdomain_info_stru *mac_regdom)
259 {
260 hi_u32 i;
261 hi_u32 start;
262 hi_u32 end;
263 hi_u8 band;
264 hi_u8 bw;
265
266 /* 复制国家字符串 */
267 mac_regdom->ac_country[0] = regdom->alpha2[0];
268 mac_regdom->ac_country[1] = regdom->alpha2[1];
269 mac_regdom->ac_country[2] = 0; /* 2 国家码的第3位 */
270 /* 初始化管制类数量为0 */
271 mac_regdom->regclass_num = 0;
272 /* 获取DFS认证标准类型 */
273 wal_get_dfs_domain(mac_regdom, regdom->alpha2);
274 /* 填充管制类信息 */
275 for (i = 0; i < regdom->n_reg_rules; i++) {
276 /* 填写管制类的频段(2.4G或5G) */
277 start = regdom->reg_rules[i].freq_range.start_freq_khz / 1000; /* 1000 频率单位转换 */
278 end = regdom->reg_rules[i].freq_range.end_freq_khz / 1000; /* 1000 频率单位转换 */
279 band = wal_regdomain_get_band(start, end);
280 mac_regdom->regclass_num++;
281 if (mac_regdom->regclass_num > WLAN_MAX_RC_NUM) {
282 oam_warning_log1(0, OAM_SF_CFG, "wal_regdomain_fill_info: regclass num[%d] overflow.",
283 mac_regdom->regclass_num);
284 return HI_FAIL;
285 }
286 mac_regdom->ast_regclass[i].start_freq = band;
287 /* 填写管制类允许的最大带宽 */
288 bw = (hi_u8)(regdom->reg_rules[i].freq_range.max_bandwidth_khz / 1000); /* 1000 频率单位转换 */
289 mac_regdom->ast_regclass[i].ch_spacing = wal_regdomain_get_bw(bw);
290 /* 填写管制类信道位图 */
291 mac_regdom->ast_regclass[i].channel_bmap = wal_regdomain_get_channel(band, start, end);
292 /* 标记管制类行为 */
293 mac_regdom->ast_regclass[i].behaviour_bmap = 0;
294 if (regdom->reg_rules[i].flags & NL80211_RRF_DFS) {
295 mac_regdom->ast_regclass[i].behaviour_bmap |= MAC_RC_DFS;
296 }
297 /* 填充覆盖类和最大发送功率 */
298 mac_regdom->ast_regclass[i].coverage_class = 0;
299 mac_regdom->ast_regclass[i].max_reg_tx_pwr =
300 (hi_u8)(regdom->reg_rules[i].power_rule.max_eirp / 100); /* 100 单位转换 */
301 mac_regdom->ast_regclass[i].max_tx_pwr =
302 (hi_u8)(regdom->reg_rules[i].power_rule.max_eirp / 100); /* 100 单位转换 */
303 }
304 return HI_SUCCESS;
305 }
306
307 /* ****************************************************************************
308 功能描述 : 下发配置管制域信息
309 输入参数 : pst_net_dev: net_device
310 pc_country : 要设置的国家字符串
311 **************************************************************************** */
wal_regdomain_update(oal_net_device_stru * netdev,const hi_char * pc_country,hi_u8 country_code_len)312 hi_u32 wal_regdomain_update(oal_net_device_stru *netdev, const hi_char *pc_country, hi_u8 country_code_len)
313 {
314 wal_msg_write_stru write_msg;
315
316 hi_unref_param(country_code_len);
317 if (!oal_is_alpha_upper(pc_country[0]) || !oal_is_alpha_upper(pc_country[1])) {
318 if ((pc_country[0] == '9') && (pc_country[1] == '9')) {
319 oam_info_log0(0, OAM_SF_ANY, "{wal_regdomain_update::set regdomain to 99!}");
320 } else {
321 oam_warning_log0(0, OAM_SF_ANY, "{wal_regdomain_update::country str is invalid!}");
322 return HI_FAIL;
323 }
324 }
325
326 const oal_ieee80211_regdomain_stru *regdom = wal_regdb_find_db(pc_country);
327 if (regdom == HI_NULL) {
328 oam_warning_log0(0, OAM_SF_ANY, "{wal_regdomain_update::no regdomain db was found!}");
329 return HI_ERR_CODE_PTR_NULL;
330 }
331
332 wal_set_cfg_regdb(regdom);
333
334 /* 申请内存存放管制域信息,将内存指针作为事件payload抛下去 */
335 /* 此处申请的内存在事件处理函数释放(hmac_config_set_country) */
336 hi_u16 us_size = (hi_u16)sizeof(mac_regdomain_info_stru);
337 mac_regdomain_info_stru *mac_regdom = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, us_size);
338 if (mac_regdom == HI_NULL) {
339 oam_error_log0(0, OAM_SF_ANY, "{wal_regdomain_update::alloc regdom mem fail, return null ptr!}");
340 return HI_FAIL;
341 }
342
343 if (wal_regdomain_fill_info(regdom, mac_regdom) != HI_SUCCESS) {
344 oal_mem_free(mac_regdom);
345 return HI_FAIL;
346 }
347
348 /* **************************************************************************
349 抛事件到wal层处理
350 ************************************************************************** */
351 wal_write_msg_hdr_init(&write_msg, WLAN_CFGID_COUNTRY, sizeof(mac_cfg_country_stru));
352
353 /* 填写WID对应的参数 */
354 mac_cfg_country_stru *param = (mac_cfg_country_stru *)(write_msg.auc_value);
355 param->mac_regdom = mac_regdom;
356
357 /* 发送消息 */
358 hi_u32 ret = wal_send_cfg_event(netdev, WAL_MSG_TYPE_WRITE,
359 WAL_MSG_WRITE_MSG_HDR_LENGTH + sizeof(mac_cfg_country_stru), (hi_u8 *)&write_msg, HI_FALSE, HI_NULL);
360 if (oal_unlikely(ret != HI_SUCCESS)) {
361 oam_warning_log1(0, OAM_SF_ANY, "{wal_regdomain_update::return err code %u!}", ret);
362 oal_mem_free(mac_regdom);
363 return ret;
364 }
365
366 return HI_SUCCESS;
367 }
368
369 #ifdef __cplusplus
370 #if __cplusplus
371 }
372 #endif
373 #endif
374