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 "oam_ext_if.h"
23 #include "mac_ie.h"
24 #include "frw_event.h"
25 #include "frw_timer.h"
26 #include "hmac_vap.h"
27 #include "hmac_mgmt_bss_comm.h"
28 #include "hmac_fsm.h"
29 #include "hmac_ext_if.h"
30 #include "hmac_chan_mgmt.h"
31 #include "hmac_edca_opt.h"
32 #include "hmac_p2p.h"
33 #include "hmac_mgmt_sta.h"
34 #include "hmac_mgmt_ap.h"
35 #include "wal_customize.h"
36
37 #ifdef __cplusplus
38 #if __cplusplus
39 extern "C" {
40 #endif
41 #endif
42
43 /* ****************************************************************************
44 2 全局变量定义
45 **************************************************************************** */
46 #define HMAC_NETDEVICE_WDT_TIMEOUT (5 * HZ)
47 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
48 static oal_net_device_ops_stru g_vap_net_dev_cfg_vap_ops = {};
49 #endif
50
51 #ifdef _PRE_WLAN_FEATURE_P2P
52 hi_void hmac_del_virtual_inf_worker(oal_work_stru *del_virtual_inf_work);
53 #endif
54
55 hi_u8 *g_puc_hmac_vap_res = HI_NULL;
56
57 /* ****************************************************************************
58 3 函数实现
59 **************************************************************************** */
60 /* ****************************************************************************
61 功能描述 : HMAC MAC VAP资源初始化,将vap资源按序号匹配,后续不允许更改
62 修改历史 :
63 1.日 期 : 2019年5月27日
64 作 者 : HiSilicon
65 修改内容 : 新生成函数
66 **************************************************************************** */
hmac_vap_res_init(hi_void)67 hi_u32 hmac_vap_res_init(hi_void)
68 {
69 hmac_vap_stru *hmac_vap = HI_NULL;
70 mac_vap_stru *mac_vap = HI_NULL;
71 hi_u8 index;
72 hi_u8 vap_res_num = oal_mem_get_vap_res_num();
73 hi_u32 vap_size = sizeof(hmac_vap_stru) * vap_res_num;
74
75 if (mac_vap_res_init(vap_res_num) != HI_SUCCESS) {
76 oam_error_log0(0, OAM_SF_ANY, "{hmac_vap_res_init::mac_vap_res_init failed.}");
77 return HI_ERR_CODE_ALLOC_MEM_FAIL;
78 }
79 /* 不为空,重复调用初始化函数,不允许,失败 */
80 if (g_puc_hmac_vap_res != HI_NULL) {
81 oam_error_log0(0, OAM_SF_ANY, "{hmac_vap_res_init::re-mem alloc vap res.}");
82 return HI_FAIL;
83 }
84 /* 动态申请用户资源池相关内存 */
85 g_puc_hmac_vap_res = (hi_u8 *)oal_memalloc(vap_size);
86 if (g_puc_hmac_vap_res == HI_NULL) {
87 oam_error_log0(0, OAM_SF_ANY, "{hmac_vap_res_init::mem alloc vap res null.}");
88 return HI_ERR_CODE_ALLOC_MEM_FAIL;
89 }
90 /* 安全编程规则6.6例外(3)从堆中分配内存后,赋予初值 */
91 memset_s(g_puc_hmac_vap_res, vap_size, 0, vap_size);
92
93 for (index = 0; index < vap_res_num; index++) {
94 hmac_vap = hmac_vap_get_vap_stru(index);
95 mac_vap = mac_vap_get_vap_stru(index);
96 if ((hmac_vap == HI_NULL) || (mac_vap == HI_NULL)) {
97 oam_error_log0(WLAN_CFG_VAP_ID, OAM_SF_ANY, "{hmac_vap_res_init:: null ptr.}");
98 return HI_FAIL;
99 }
100
101 hmac_vap->base_vap = mac_vap;
102 }
103 return HI_SUCCESS;
104 }
105
hmac_vap_res_exit(hi_void)106 hi_u32 hmac_vap_res_exit(hi_void)
107 {
108 mac_vap_res_exit();
109
110 if (g_puc_hmac_vap_res != HI_NULL) {
111 oal_free(g_puc_hmac_vap_res);
112 g_puc_hmac_vap_res = HI_NULL;
113 }
114
115 return HI_SUCCESS;
116 }
117 /* ****************************************************************************
118 功能描述 : 获取对应的hmac vap结构体
119 输入参数 : vap资源id
120 修改历史 :
121 1.日 期 : 2019年5月25日
122 作 者 : HiSilicon
123 修改内容 : 新生成函数
124 **************************************************************************** */
hmac_vap_get_vap_stru(hi_u8 idx)125 hmac_vap_stru *hmac_vap_get_vap_stru(hi_u8 idx)
126 {
127 hi_u8 vap_res_num = oal_mem_get_vap_res_num();
128 if (idx >= vap_res_num) {
129 oam_error_log1(0, OAM_SF_CFG, "{hmac_vap_get_vap_stru::vap id [%d] is illegal.}", idx);
130 return HI_NULL;
131 }
132 return (hmac_vap_stru *)(g_puc_hmac_vap_res + idx * sizeof(hmac_vap_stru));
133 }
134
hmac_vap_mesh_ap_sta_init(hmac_vap_stru * hmac_vap,const mac_cfg_add_vap_param_stru * param)135 hi_u32 hmac_vap_mesh_ap_sta_init(hmac_vap_stru *hmac_vap, const mac_cfg_add_vap_param_stru *param)
136 {
137 switch (param->vap_mode) {
138 #ifdef _PRE_WLAN_FEATURE_MESH
139 case WLAN_VAP_MODE_MESH:
140 #endif
141 case WLAN_VAP_MODE_BSS_AP:
142 /* 执行特性初始化vap的函数 */
143 hmac_vap->amsdu_active = HI_FALSE;
144
145 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
146 hmac_vap->us_edca_opt_time_ms = HMAC_EDCA_OPT_TIME_MS;
147 frw_timer_create_timer(&(hmac_vap->edca_opt_timer), hmac_edca_opt_timeout_fn,
148 hmac_vap->us_edca_opt_time_ms, hmac_vap, HI_TRUE);
149 hmac_vap->edca_opt_flag_ap = 1;
150 frw_timer_restart_timer(&(hmac_vap->edca_opt_timer), hmac_vap->us_edca_opt_time_ms, HI_TRUE);
151 #endif
152
153 #ifdef _PRE_WLAN_FEATURE_TX_CLASSIFY_LAN_TO_WLAN
154 hmac_vap->tx_traffic_classify_flag = HI_SWITCH_ON; /* AP模式默认业务识别功能开启 */
155 #endif
156 break;
157
158 case WLAN_VAP_MODE_BSS_STA:
159 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
160 hmac_vap->edca_opt_flag_sta = 0;
161 #endif
162
163 #ifdef _PRE_WLAN_FEATURE_TX_CLASSIFY_LAN_TO_WLAN
164 hmac_vap->tx_traffic_classify_flag = HI_SWITCH_ON; /* STA模式默认业务识别功能开启 */
165 #endif
166 break;
167
168 case WLAN_VAP_MODE_WDS:
169 break;
170
171 case WLAN_VAP_MODE_CONFIG:
172 return HI_SUCCESS; /* 配置VAP直接返回 */
173
174 default:
175 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_ANY, "{hmac_vap_init::mod Err=%d.}", param->vap_mode);
176 return HI_ERR_CODE_INVALID_CONFIG;
177 }
178
179 return HI_CONTINUE;
180 }
181
182 /* ****************************************************************************
183 功能描述 : 初始化要添加的hmac vap的一些特性信息
184 输入参数 : 指向要添加的vap的指针
185 返 回 值 : 成功或者失败原因
186 修改历史 :
187 1.日 期 : 2012年10月24日
188 作 者 : HiSilicon
189 修改内容 : 新生成函数
190 2.日 期 : 2019年5月20日
191 作 者 : HiSilicon
192 修改内容 : 调用初已进行MEMZERO,删除0初始化
193 **************************************************************************** */
hmac_vap_init(hmac_vap_stru * hmac_vap,hi_u8 vap_id,const mac_cfg_add_vap_param_stru * param)194 hi_u32 hmac_vap_init(hmac_vap_stru *hmac_vap, hi_u8 vap_id, const mac_cfg_add_vap_param_stru *param)
195 {
196 /* mac vap指针不清0需保持vap指针的匹配 */
197 mac_vap_stru *mac_vap = hmac_vap->base_vap;
198 if (memset_s(hmac_vap, sizeof(hmac_vap_stru), 0, sizeof(hmac_vap_stru)) != EOK) {
199 return HI_FAIL;
200 }
201 hmac_vap->base_vap = mac_vap;
202 /* 重新获取mac vap指针并判断匹配关系检查指针是否被改写 */
203 mac_vap = mac_vap_get_vap_stru(vap_id);
204 if ((mac_vap == HI_NULL) || (hmac_vap->base_vap != mac_vap)) {
205 oam_error_log1(vap_id, OAM_SF_ANY, "{hmac_vap_init::invalid mac vap(%x).}", (uintptr_t)mac_vap);
206 return HI_FAIL;
207 }
208
209 hi_u32 ret = mac_vap_init(hmac_vap->base_vap, vap_id, param);
210 if (oal_unlikely(ret != HI_SUCCESS)) {
211 oam_warning_log1(vap_id, OAM_SF_ANY, "{hmac_vap_init::mac_vap_init failed[%d].}", ret);
212 return ret;
213 }
214
215 /* 初始化预设参数 */
216 hmac_vap->preset_para.protocol = hmac_vap->base_vap->protocol;
217 hmac_vap->preset_para.en_bandwidth = hmac_vap->base_vap->channel.en_bandwidth;
218 hmac_vap->preset_para.band = hmac_vap->base_vap->channel.band;
219
220 /* 初始化配置私有结构体 */
221 hi_wait_queue_init_head(&(hmac_vap->mgmt_tx.wait_queue));
222
223 /* 1151默认不amsdu ampdu 联合聚合功能不开启 1102用于小包优化
224 * 因tplink/syslink下行冲包兼容性问题,先关闭02的ampdu+amsdu
225 */
226 hmac_vap->ampdu_tx_on_switch = HI_TRUE;
227
228 /* 初始化认证类型为OPEN */
229 hmac_vap->auth_mode = WLAN_WITP_AUTH_OPEN_SYSTEM;
230
231 hmac_vap_stru *hmac_vap_temp = hmac_vap_get_vap_stru(WLAN_CFG_VAP_ID);
232 if (hmac_vap_temp == HI_NULL) {
233 return HI_FAIL;
234 }
235 hmac_vap->max_ampdu_num = (vap_id == WLAN_CFG_VAP_ID) ? WLAN_AMPDU_TX_MAX_BUF_SIZE : hmac_vap_temp->max_ampdu_num;
236
237 hi_wait_queue_init_head(&hmac_vap->query_wait_q);
238
239 /* 根据配置VAP,将对应函数挂接在业务VAP,区分AP、STA和WDS模式 */
240 ret = hmac_vap_mesh_ap_sta_init(hmac_vap, param);
241 if (ret != HI_CONTINUE) {
242 return ret;
243 }
244
245 #ifdef _PRE_WLAN_FEATURE_SMP_SUPPORT
246 OAL_NETBUF_QUEUE_HEAD_INIT(&(hmac_vap->tx_queue_head[0]));
247 OAL_NETBUF_QUEUE_HEAD_INIT(&(hmac_vap->tx_queue_head[1]));
248 hmac_vap->in_queue_id = 0;
249 hmac_vap->out_queue_id = 1;
250
251 /* ul_tx_event_num初始值修改为1,防止hmac_tx_post_event可能连续抛两个以上事件 */
252 hi_atomic_set(&hmac_vap->tx_event_num, 1);
253
254 hmac_vap->tx_quata = 256; /* 将quata从1修改为256 */
255 #endif
256
257 /* 创建vap时 初始状态为init */
258 mac_vap_state_change(hmac_vap->base_vap, MAC_VAP_STATE_INIT);
259
260 #ifdef _PRE_WLAN_FEATURE_P2P
261 /* 初始化删除虚拟网络接口工作队列 */
262 OAL_INIT_WORK(&(hmac_vap->del_virtual_inf_worker), hmac_del_virtual_inf_worker);
263 hmac_vap->del_net_device = HI_NULL;
264 hmac_vap->p2p0_net_device = HI_NULL;
265 #endif
266
267 return HI_SUCCESS;
268 }
269
270 /* ****************************************************************************
271 函 数 名 : hmac_vap_get_net_device
272 功能描述 : 通过vap id获取 net_device
273 输入参数 : 无
274 输出参数 : 无
275 返 回 值 :
276 调用函数 :
277 被调函数 :
278
279 修改历史 :
280 1.日 期 : 2013年9月6日
281 作 者 : HiSilicon
282 修改内容 : 新生成函数
283
284 **************************************************************************** */
hmac_vap_get_net_device(hi_u8 vap_id)285 oal_net_device_stru *hmac_vap_get_net_device(hi_u8 vap_id)
286 {
287 hmac_vap_stru *hmac_vap = HI_NULL;
288
289 hmac_vap = hmac_vap_get_vap_stru(vap_id);
290 if (hmac_vap == HI_NULL) {
291 oam_error_log0(vap_id, OAM_SF_ANY, "{hmac_vap_get_net_device::pst_hmac_vap null.}");
292 return HI_NULL;
293 }
294
295 return (hmac_vap->net_device);
296 }
297
298 /* ****************************************************************************
299 函 数 名 : hmac_vap_creat_netdev
300 功能描述 : 获取hmac_vap结构体中的私有配置项
301 输入参数 : 无
302 输出参数 : 无
303 返 回 值 :
304 调用函数 :
305 被调函数 :
306
307 修改历史 :
308 1.日 期 : 2012年12月11日
309 作 者 : HiSilicon
310 修改内容 : 新生成函数
311
312 **************************************************************************** */
hmac_vap_creat_netdev(hmac_vap_stru * hmac_vap,hi_char * puc_netdev_name,const hi_s8 * mac_addr,hi_u8 mac_addr_len)313 hi_u32 hmac_vap_creat_netdev(hmac_vap_stru *hmac_vap, hi_char *puc_netdev_name, const hi_s8 *mac_addr,
314 hi_u8 mac_addr_len)
315 {
316 oal_net_device_stru *netdev = HI_NULL;
317 hi_u32 return_code;
318 mac_vap_stru *mac_vap = HI_NULL;
319
320 if (oal_unlikely((hmac_vap == HI_NULL) || (puc_netdev_name == HI_NULL))) {
321 oam_error_log2(0, OAM_SF_ASSOC, "{hmac_vap_creat_netdev::param null %p %p.}", (uintptr_t)hmac_vap,
322 (uintptr_t)puc_netdev_name);
323 return HI_ERR_CODE_PTR_NULL;
324 }
325
326 mac_vap = hmac_vap->base_vap;
327 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
328 netdev = NetDeviceInit(puc_netdev_name, strlen(puc_netdev_name), WIFI_LINK, LITE_OS);
329 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
330 netdev = NetDeviceInit(puc_netdev_name, strlen(puc_netdev_name), WIFI_LINK, FULL_OS);
331 #endif
332 if (oal_unlikely(netdev == HI_NULL)) {
333 oam_warning_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_vap_creat_netdev::pst_net_device null.}");
334
335 return HI_ERR_CODE_PTR_NULL;
336 }
337 netdev->funType.wlanType = PROTOCOL_80211_IFTYPE_STATION;
338
339 /* 如下对netdevice的赋值暂时按如下操作 */
340 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
341 oal_netdevice_ops(netdev) = &g_vap_net_dev_cfg_vap_ops;
342 #else
343 oal_netdevice_master(netdev) = HI_NULL;
344 oal_netdevice_ops(netdev) = HI_NULL;
345 #endif
346
347 oal_netdevice_watchdog_timeo(netdev) = HMAC_NETDEVICE_WDT_TIMEOUT;
348 oal_netdevice_specical_proc_priv(netdev) = HI_NULL;
349 if (memcpy_s(oal_netdevice_mac_addr(netdev), WLAN_MAC_ADDR_LEN, mac_addr, mac_addr_len) != EOK) {
350 oam_error_log0(0, OAM_SF_CFG, "hmac_vap_creat_netdev:: puc_mac_addr memcpy_s fail.");
351 oal_net_free_netdev(netdev);
352 return HI_FAIL;
353 }
354 oal_net_dev_priv(netdev) = mac_vap;
355
356 return_code = (hi_u32)oal_net_register_netdev(netdev, NL80211_IFTYPE_STATION);
357 if (oal_unlikely(return_code != HI_SUCCESS)) {
358 oam_warning_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_vap_creat_netdev::oal_net_register_netdev failed.}");
359 oal_net_free_netdev(netdev);
360 return return_code;
361 }
362 hmac_vap->net_device = netdev;
363 return HI_SUCCESS;
364 }
365
366 /* ****************************************************************************
367 函 数 名 : hmac_vap_destroy
368 功能描述 : 销毁hmac vap的处理函数
369 输入参数 : 指向要销毁的vap指针
370 输出参数 : 无
371 返 回 值 : 成功或者失败原因
372 调用函数 :
373 被调函数 :
374
375 修改历史 :
376 1.日 期 : 2013年5月30日
377 作 者 : HiSilicon
378 修改内容 : 新生成函数
379
380 **************************************************************************** */
hmac_vap_destroy(hmac_vap_stru * hmac_vap)381 hi_u32 hmac_vap_destroy(hmac_vap_stru *hmac_vap)
382 {
383 mac_cfg_down_vap_param_stru down_vap;
384 mac_cfg_del_vap_param_stru del_vap_param;
385 hi_u32 ret;
386
387 if (oal_unlikely(hmac_vap == HI_NULL)) {
388 oam_error_log0(0, OAM_SF_ANY, "{hmac_vap_destroy::pst_hmac_vap null.}");
389 return HI_ERR_CODE_PTR_NULL;
390 }
391
392 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
393 if (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_BSS_AP
394 #ifdef _PRE_WLAN_FEATURE_MESH
395 || (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_MESH)
396 #endif
397 ) {
398 hmac_vap->edca_opt_flag_ap = 0;
399 frw_timer_immediate_destroy_timer(&(hmac_vap->edca_opt_timer));
400 } else if (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) {
401 hmac_vap->edca_opt_flag_sta = 0;
402 }
403 #endif
404 /* 先down vap */
405 #ifdef _PRE_WLAN_FEATURE_P2P
406 down_vap.p2p_mode = hmac_vap->base_vap->p2p_mode;
407 #endif
408 down_vap.net_dev = hmac_vap->net_device;
409 ret = hmac_config_down_vap(hmac_vap->base_vap, sizeof(mac_cfg_down_vap_param_stru), (hi_u8 *)&down_vap);
410 if (ret != HI_SUCCESS) {
411 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_ANY, "{hmac_vap_destroy::hmac_config_down_vap failed[%d].}",
412 ret);
413 return ret;
414 }
415
416 /* 然后再delete vap */
417 del_vap_param.p2p_mode = hmac_vap->base_vap->p2p_mode;
418 del_vap_param.vap_mode = hmac_vap->base_vap->vap_mode;
419 ret = hmac_config_del_vap(hmac_vap->base_vap, sizeof(mac_cfg_del_vap_param_stru), (hi_u8 *)&del_vap_param);
420 if (ret != HI_SUCCESS) {
421 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_ANY, "{hmac_vap_destroy::hmac_config_del_vap failed[%d].}",
422 ret);
423 return ret;
424 }
425 return HI_SUCCESS;
426 }
427
hmac_vap_check_ht_capabilities_ap_capable(const hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const mac_user_ht_hdl_stru * ht_hdl,hi_bool prev_asoc_ht,hi_bool prev_asoc_non_ht)428 hi_void hmac_vap_check_ht_capabilities_ap_capable(const hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
429 const mac_user_ht_hdl_stru *ht_hdl, hi_bool prev_asoc_ht, hi_bool prev_asoc_non_ht)
430 {
431 mac_protection_stru *protection = &(hmac_vap->base_vap->protection);
432
433 if (ht_hdl->ht_capable == HI_FALSE) { /* STA不支持HT */
434 /* 如果STA之前没有与AP关联 */
435 if (hmac_user->base_user->user_asoc_state != MAC_USER_STATE_ASSOC) {
436 protection->sta_non_ht_num++;
437 } else if (prev_asoc_ht == HI_TRUE) { /* 如果STA之前已经作为HT站点与AP关联 */
438 protection->sta_non_ht_num++;
439
440 if ((ht_hdl->ht_capinfo.supported_channel_width == HI_FALSE) && (protection->sta_20_m_only_num != 0)) {
441 protection->sta_20_m_only_num--;
442 }
443
444 if ((ht_hdl->ht_capinfo.ht_green_field == HI_FALSE) && (protection->sta_non_gf_num != 0)) {
445 protection->sta_non_gf_num--;
446 }
447
448 if ((ht_hdl->ht_capinfo.lsig_txop_protection == HI_FALSE) && (protection->sta_no_lsig_txop_num != 0)) {
449 protection->sta_no_lsig_txop_num--;
450 }
451 } /* STA 之前已经作为非HT站点与AP关联 */
452 } else {
453 /* 如果STA之前已经以non-HT站点与AP关联, 则将uc_sta_non_ht_num减1 */
454 if ((prev_asoc_non_ht == HI_TRUE) && (protection->sta_non_ht_num != 0)) {
455 protection->sta_non_ht_num--;
456 }
457 }
458 }
459
460 /* ****************************************************************************
461
462 函 数 名 : hmac_vap_check_ht_capabilities_ap
463 功能描述 : 检查请求关联的STA的 HT Capabilities element
464 输入参数 : 无
465 输出参数 : 无
466 返 回 值 : hi_u32
467 调用函数 :
468 被调函数 :
469
470 修改历史 :
471 1.日 期 : 2013年7月8日
472 作 者 : HiSilicon
473 修改内容 : 新生成函数
474
475 **************************************************************************** */
hmac_vap_check_ht_capabilities_ap(const hmac_vap_stru * hmac_vap,hi_u8 * puc_payload,hi_u16 us_info_elem_offset,hi_u32 msg_len,hmac_user_stru * hmac_user)476 hi_u16 hmac_vap_check_ht_capabilities_ap(const hmac_vap_stru *hmac_vap, hi_u8 *puc_payload, hi_u16 us_info_elem_offset,
477 hi_u32 msg_len, hmac_user_stru *hmac_user)
478 {
479 hi_u16 us_index = us_info_elem_offset;
480 hi_bool prev_asoc_ht = HI_FALSE;
481 hi_bool prev_asoc_non_ht = HI_FALSE;
482 mac_user_ht_hdl_stru *ht_hdl = &(hmac_user->base_user->ht_hdl);
483 hi_u8 pcip_policy;
484
485 if (mac_mib_get_high_throughput_option_implemented(hmac_vap->base_vap) == HI_FALSE) {
486 return MAC_SUCCESSFUL_STATUSCODE;
487 }
488 /* 检查STA是否是作为一个HT capable STA与AP关联 */
489 if ((hmac_user->base_user->user_asoc_state == MAC_USER_STATE_ASSOC) && (ht_hdl->ht_capable == HI_TRUE)) {
490 mac_user_set_ht_capable(hmac_user->base_user, HI_FALSE);
491 prev_asoc_ht = HI_TRUE;
492 /* 检查STA是否是作为一个non HT capable STA与AP关联 */
493 } else if (hmac_user->base_user->user_asoc_state == MAC_USER_STATE_ASSOC && ht_hdl->ht_capable == HI_FALSE) {
494 prev_asoc_non_ht = HI_TRUE;
495 }
496
497 /* 在关联请求帧中搜索 HT Capabilities Element */
498 while (us_index < (msg_len - WLAN_HDR_FCS_LENGTH)) {
499 if (puc_payload[us_index] == MAC_EID_HT_CAP) {
500 /* 不允许HT STA 使用 TKIP/WEP 加密 */
501 if (mac_is_wep_enabled(hmac_vap->base_vap)) {
502 oam_warning_log1(0, OAM_SF_ANY, "{hmac_vap_check_ht_capabilities_ap::Rejecting a HT STA Cipher %d}",
503 hmac_user->base_user->key_info.cipher_type);
504 return MAC_MISMATCH_HTCAP;
505 }
506 pcip_policy = hmac_vap->base_vap->mib_info->wlan_mib_rsna_cfg.dot11_rsna_pairwise_cipher_requested;
507
508 if (pcip_policy == WLAN_80211_CIPHER_SUITE_TKIP) {
509 oam_warning_log2(hmac_vap->base_vap->vap_id, OAM_SF_ANY,
510 "{hmac_vap_check_ht_capabilities_ap::uc_pcip_policy=%d uc_grp_policy=%d}", pcip_policy,
511 hmac_vap->base_vap->mib_info->wlan_mib_rsna_cfg.dot11_rsna_group_cipher_requested);
512 break;
513 }
514
515 /* 搜索 HT Capabilities Element */
516 hmac_search_ht_cap_ie_ap(hmac_vap, hmac_user, puc_payload, us_index, prev_asoc_ht);
517
518 break;
519 }
520 /* 通过IE长度增加索引值 */
521 us_index += puc_payload[us_index + 1] + MAC_IE_HDR_LEN;
522 }
523
524 /* 走到这里,说明sta已经被统计到ht相关的统计量中 */
525 hmac_user->user_stats_flag.no_ht_stats_flag = HI_TRUE;
526 hmac_user->user_stats_flag.no_gf_stats_flag = HI_TRUE;
527 hmac_user->user_stats_flag.m_only_stats_flag = HI_TRUE;
528 hmac_user->user_stats_flag.no_lsig_txop_stats_flag = HI_TRUE;
529 hmac_user->user_stats_flag.no_40dsss_stats_flag = HI_TRUE;
530
531 hmac_vap_check_ht_capabilities_ap_capable(hmac_vap, hmac_user, ht_hdl, prev_asoc_ht, prev_asoc_non_ht);
532
533 return MAC_SUCCESSFUL_STATUSCODE;
534 }
535
536
hmac_parse_tx_beamforming(const hi_u8 * payload,hi_u16 offset,mac_user_ht_hdl_stru * ht_hdl,mac_user_stru * base_user)537 static inline hi_void hmac_parse_tx_beamforming(const hi_u8 *payload, hi_u16 offset, mac_user_ht_hdl_stru *ht_hdl,
538 mac_user_stru *base_user)
539 {
540 hi_u16 tmp_info_elem = hi_makeu16(payload[offset], payload[offset + 1]);
541
542 hi_u16 tmp_txbf_low = hi_makeu16(payload[offset + 2], payload[offset + 3]); /* 2/3 索引 */
543 hi_u32 tmp_txbf_elem = hi_makeu32(tmp_info_elem, tmp_txbf_low);
544
545 mac_ie_txbf_set_ht_hdl(ht_hdl, tmp_txbf_elem);
546 mac_user_set_ht_hdl(base_user, ht_hdl);
547 }
548
549 /* ****************************************************************************
550 函 数 名 : hmac_search_ht_cap_ie_ap
551 功能描述 : 在关联请求请求中搜索HT Cap IE
552 输入参数 : 无
553 输出参数 : 无
554 返 回 值 :
555 调用函数 :
556 被调函数 :
557
558 修改历史 :
559 1.日 期 : 2013年7月10日
560 作 者 : HiSilicon
561 修改内容 : 新生成函数
562
563 **************************************************************************** */
hmac_search_ht_cap_ie_ap(const hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hi_u8 * payload,hi_u16 current_offset,hi_bool prev_asoc_ht)564 hi_u32 hmac_search_ht_cap_ie_ap(const hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, hi_u8 *payload,
565 hi_u16 current_offset, hi_bool prev_asoc_ht)
566 {
567 mac_user_ht_hdl_stru ht_hdl_value;
568
569 hi_u8 *tmp_payload = payload;
570 mac_user_ht_hdl_stru *ht_hdl = &ht_hdl_value;
571 mac_vap_stru *mac_vap = hmac_vap->base_vap;
572 mac_user_stru *mac_user = hmac_user->base_user;
573 hi_u8 mcs_bmp_index;
574
575 mac_user_get_ht_hdl(hmac_user->base_user, ht_hdl);
576
577 /* 带有 HT Capability Element 的 STA,标示它具有HT capable. */
578 ht_hdl->ht_capable = 1;
579 current_offset += MAC_IE_HDR_LEN;
580
581 /* **************************************************************************
582 解析 HT Capabilities Info Field
583 ************************************************************************** */
584 hi_u16 tmp_info_elem = hi_makeu16(tmp_payload[current_offset], tmp_payload[current_offset + 1]);
585
586 /* 检查STA所支持的LDPC编码能力 B0,0:不支持,1:支持 */
587 ht_hdl->ht_capinfo.ldpc_coding_cap = (tmp_info_elem & BIT0);
588
589 /* 检查STA所支持的信道宽度 B1,0:仅20M运行,1:20M与40M运行 */
590 ht_hdl->ht_capinfo.supported_channel_width =
591 mac_ie_proc_ht_supported_channel_width(mac_user, mac_vap, ((tmp_info_elem & BIT1) >> 1), prev_asoc_ht);
592
593 /* 检查空间复用节能模式 B2~B3 */
594 ht_hdl->ht_capinfo.sm_power_save = mac_ie_proc_sm_power_save_field((tmp_info_elem & (BIT2 | BIT3)) >> 2);
595
596 /* 检查Greenfield 支持情况 B4, 0:不支持,1:支持 */
597 hi_u8 ht_green_field = (tmp_info_elem & BIT4) >> 4;
598 ht_hdl->ht_capinfo.ht_green_field = mac_ie_proc_ht_green_field(mac_user, mac_vap, ht_green_field, prev_asoc_ht);
599
600 /* 检查20MHz Short-GI B5, 0:不支持,1:支持,之后与AP取交集 */
601 ht_hdl->ht_capinfo.short_gi_20mhz = ((tmp_info_elem & BIT5) >> 5);
602 ht_hdl->ht_capinfo.short_gi_20mhz &=
603 (hi_u16)hmac_vap->base_vap->mib_info->phy_ht.dot11_short_gi_option_in_twenty_implemented;
604
605 /* 检查40MHz Short-GI B6, 0:不支持,1:支持,之后与AP取交集 */
606 ht_hdl->ht_capinfo.short_gi_40mhz = ((tmp_info_elem & BIT6) >> 6);
607 ht_hdl->ht_capinfo.short_gi_40mhz &= (hi_u16)mac_mib_get_shortgi_option_in_forty_implemented(hmac_vap->base_vap);
608
609 /* 检查支持接收STBC PPDU B8, 0:不支持,1:支持 */
610 ht_hdl->ht_capinfo.rx_stbc = ((tmp_info_elem & 0x0300) >> 8);
611
612 /* 检查最大A-MSDU长度 B11,0:3839字节, 1:7935字节 */
613 hmac_user->us_amsdu_maxsize =
614 (0 == (tmp_info_elem & BIT11)) ? WLAN_MIB_MAX_AMSDU_LENGTH_SHORT : WLAN_MIB_MAX_AMSDU_LENGTH_LONG;
615
616 /* 检查在40M上DSSS/CCK的支持情况 B12 */
617 /* 在非Beacon帧或probe rsp帧中时 */
618 /* 0: STA在40MHz上不使用DSSS/CCK, 1: STA在40MHz上使用DSSS/CCK */
619 ht_hdl->ht_capinfo.dsss_cck_mode_40mhz = ((tmp_info_elem & BIT12) >> 12); /* 右移12位 */
620
621 if ((ht_hdl->ht_capinfo.dsss_cck_mode_40mhz == 0) && (ht_hdl->ht_capinfo.supported_channel_width == 1)) {
622 hmac_vap->base_vap->protection.sta_no_40dsss_cck_num++;
623 }
624
625 /* 检查对L-SIG TXOP 保护的支持情况 B15, 0:不支持,1:支持 */
626 ht_hdl->ht_capinfo.lsig_txop_protection = mac_ie_proc_lsig_txop_protection_support(mac_user, mac_vap,
627 ((tmp_info_elem & BIT15) >> 15), prev_asoc_ht); /* 15: 右移15位 */
628
629 current_offset += MAC_HT_CAPINFO_LEN;
630
631 /* **************************************************************************
632 解析 A-MPDU Parameters Field
633 ************************************************************************** */
634 /* 提取 Maximum Rx A-MPDU factor (B1 - B0) */
635 ht_hdl->max_rx_ampdu_factor = (tmp_payload[current_offset] & 0x03);
636
637 /* 提取 the Minimum MPDU Start Spacing (B2 - B4) */
638 ht_hdl->min_mpdu_start_spacing = (tmp_payload[current_offset] >> 2) & 0x07;
639
640 current_offset += MAC_HT_AMPDU_PARAMS_LEN;
641
642 /* **************************************************************************
643 解析 Supported MCS Set Field
644 ************************************************************************** */
645 for (mcs_bmp_index = 0; mcs_bmp_index < WLAN_HT_MCS_BITMASK_LEN; mcs_bmp_index++) {
646 ht_hdl->rx_mcs_bitmask[mcs_bmp_index] = (*(hi_u8 *)(tmp_payload + current_offset + mcs_bmp_index)) &
647 (hmac_vap->base_vap->mib_info->supported_mcstx.auc_dot11_supported_mcs_tx_value[mcs_bmp_index]);
648 }
649
650 ht_hdl->rx_mcs_bitmask[WLAN_HT_MCS_BITMASK_LEN - 1] &= 0x1F;
651
652 current_offset += MAC_HT_SUP_MCS_SET_LEN;
653
654 /* **************************************************************************
655 解析 HT Extended Capabilities Info Field
656 ************************************************************************** */
657 tmp_info_elem = hi_makeu16(tmp_payload[current_offset], tmp_payload[current_offset + 1]);
658
659 /* 提取 HTC support Information */
660 ht_hdl->htc_support = ((tmp_info_elem & BIT10) != 0) ? 1 : ht_hdl->htc_support;
661
662 current_offset += MAC_HT_EXT_CAP_LEN;
663
664 /* **************************************************************************
665 解析 Tx Beamforming Field
666 ************************************************************************** */
667 hmac_parse_tx_beamforming(tmp_payload, current_offset, ht_hdl, hmac_user->base_user);
668 return HI_SUCCESS;
669 }
670
671 #ifdef _PRE_WLAN_FEATURE_OPMODE_NOTIFY
672 /* ****************************************************************************
673 函 数 名 : hmac_check_opmode_notify
674 功能描述 : 检查请求关联的STA的Operating Mode Notification
675 输入参数 : hmac_vap_stru *pst_hmac_vap --VAP指针
676 hi_u8 *puc_mac_hdr, --帧头指针
677 hi_u8 *puc_payload --payload指针
678 hi_u16 us_info_elem_offset--偏移长度
679 hi_u32 ul_msg_len----信息长度
680 hmac_user_stru *pst_hmac_user_sta --用户指针
681 输出参数 : 无
682 返 回 值 : hi_u16
683 调用函数 :
684 被调函数 :
685
686 修改历史 :
687 1.日 期 : 2014年6月10日
688 作 者 : HiSilicon
689 修改内容 : 新生成函数
690 **************************************************************************** */
hmac_check_opmode_notify(hmac_vap_stru * hmac_vap,hi_u8 * puc_mac_hdr,hi_u8 * puc_payload,hi_u16 us_info_elem_offset,hi_u32 msg_len,hmac_user_stru * hmac_user)691 hi_u32 hmac_check_opmode_notify(hmac_vap_stru *hmac_vap, hi_u8 *puc_mac_hdr, hi_u8 *puc_payload,
692 hi_u16 us_info_elem_offset, hi_u32 msg_len, hmac_user_stru *hmac_user)
693 {
694 hi_u8 *puc_opmode_notify_ie = HI_NULL;
695 mac_opmode_notify_stru *opmode_notify = HI_NULL;
696 hi_u8 mgmt_frm_type;
697 hi_u32 relt;
698
699 if ((hmac_vap == HI_NULL) || (puc_payload == HI_NULL) || (hmac_user == HI_NULL) || (puc_mac_hdr == HI_NULL)) {
700 oam_error_log4(0, OAM_SF_ANY,
701 "{hmac_check_opmode_notify::param null! hmac_vap=%p, puc_payload=%p, hmac_user=%p, puc_mac_hdr=%p.}",
702 (uintptr_t)hmac_vap, (uintptr_t)puc_payload, (uintptr_t)hmac_user, (uintptr_t)puc_mac_hdr);
703 return HI_ERR_CODE_PTR_NULL;
704 }
705
706 mac_vap_stru *mac_vap = hmac_vap->base_vap;
707 mac_user_stru *mac_user = hmac_user->base_user;
708
709 if ((HI_FALSE == mac_mib_get_VHTOptionImplemented(mac_vap)) ||
710 (HI_FALSE == mac_mib_get_operating_mode_notification_implemented(mac_vap))) {
711 return HI_SUCCESS;
712 }
713
714 if (msg_len > us_info_elem_offset) {
715 puc_opmode_notify_ie =
716 mac_find_ie(MAC_EID_OPMODE_NOTIFY, puc_payload + us_info_elem_offset, (msg_len - us_info_elem_offset));
717 if ((puc_opmode_notify_ie != HI_NULL) && (puc_opmode_notify_ie[1] >= MAC_OPMODE_NOTIFY_LEN)) {
718 mgmt_frm_type = mac_get_frame_sub_type(puc_mac_hdr);
719 opmode_notify = (mac_opmode_notify_stru *)(puc_opmode_notify_ie + MAC_IE_HDR_LEN);
720 relt = hmac_ie_proc_opmode_field(mac_vap, mac_user, opmode_notify, mgmt_frm_type);
721 if (oal_unlikely(relt != HI_SUCCESS)) {
722 oam_warning_log1(mac_user->vap_id, OAM_SF_CFG,
723 "{hmac_check_opmode_notify::hmac_ie_proc_opmode_field failed[%d].}", relt);
724 return relt;
725 }
726 /* opmode息同步dmac */
727 relt = hmac_config_update_opmode_event(mac_vap, mac_user, mgmt_frm_type);
728 if (oal_unlikely(relt != HI_SUCCESS)) {
729 oam_warning_log1(mac_user->vap_id, OAM_SF_CFG,
730 "{hmac_check_opmode_notify::hmac_config_update_opmode_event failed[%d].}", relt);
731 return relt;
732 }
733 }
734 }
735 return HI_SUCCESS;
736 }
737 #endif
738
739 #ifdef _PRE_WLAN_FEATURE_P2P
740 /* ****************************************************************************
741 函 数 名 : hmac_del_virtual_inf_worker
742 功能描述 : cfg80211 删除虚拟接口工作队列,防止去注册网络设备时程序挂死。
743 输入参数 : hi_work *pst_del_virtual_inf_work
744 输出参数 : 无
745 返 回 值 : hi_void
746 调用函数 :
747 被调函数 :
748
749 修改历史 :
750 1.日 期 : 2015年2月26日
751 作 者 : HiSilicon
752 修改内容 : 新生成函数
753
754 **************************************************************************** */
hmac_del_virtual_inf_worker(oal_work_stru * del_virtual_inf_work)755 hi_void hmac_del_virtual_inf_worker(oal_work_stru *del_virtual_inf_work)
756 {
757 oal_net_device_stru *netdev = HI_NULL;
758 hmac_vap_stru *hmac_vap = HI_NULL;
759 hmac_device_stru *hmac_dev = HI_NULL;
760
761 hmac_vap = oal_container_of(del_virtual_inf_work, hmac_vap_stru, del_virtual_inf_worker);
762 netdev = hmac_vap->del_net_device;
763
764 /* 不存在rtnl_lock锁问题 */
765 oal_net_unregister_netdev(netdev);
766 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
767 oal_net_free_netdev(netdev);
768 #endif
769 hmac_vap->del_net_device = HI_NULL;
770 hmac_dev = hmac_get_device_stru();
771 hmac_p2p_clr_status(&hmac_dev->p2p_intf_status, P2P_STATUS_IF_DELETING);
772
773 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_P2P,
774 "{hmac_del_virtual_inf_worker::end !pst_hmac_device->ul_p2p_intf_status[%x]}", hmac_dev->p2p_intf_status);
775 oal_smp_mb();
776 hi_wait_queue_wake_up_interrupt(&hmac_dev->netif_change_event);
777 }
778 #endif /* _PRE_WLAN_FEATURE_P2P */
779
780 /* ****************************************************************************
781 函 数 名 : hmac_handle_disconnect_rsp
782 功能描述 :
783 输入参数 : 无
784 输出参数 : 无
785 返 回 值 :
786 调用函数 :
787 被调函数 :
788
789 修改历史 :
790 1.日 期 : 2015年2月10日
791 作 者 : HiSilicon
792 修改内容 : 新生成函数
793
794 **************************************************************************** */
hmac_handle_disconnect_rsp(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,hmac_report_disasoc_reason_uint16 disasoc_reason)795 hi_void hmac_handle_disconnect_rsp(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
796 hmac_report_disasoc_reason_uint16 disasoc_reason)
797 {
798 /* 修改 state & 删除 user */
799 switch (hmac_vap->base_vap->vap_mode) {
800 case WLAN_VAP_MODE_BSS_STA: {
801 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
802
803 /* 上报内核sta已经和某个ap去关联 */
804 /* sta kick user dmac_reason_code = 5 */
805 hmac_sta_disassoc_rsp(hmac_vap, disasoc_reason, DMAC_DISASOC_MISC_KICKUSER);
806 } break;
807 #ifdef _PRE_WLAN_FEATURE_MESH
808 case WLAN_VAP_MODE_MESH:
809 #endif
810 case WLAN_VAP_MODE_BSS_AP: {
811 /* 抛事件上报内核,已经去关联某个STA */
812 hmac_handle_disconnect_rsp_ap(hmac_vap, hmac_user);
813 } break;
814
815 default:
816 break;
817 }
818 return;
819 }
820
821 /* ****************************************************************************
822 函 数 名 : hmac_tx_get_mac_vap
823 功能描述 : 获取VAP,并判断VAP状态
824 输入参数 : pst_event event结构体
825 输出参数 : pst_vap_stru VAP结构体
826 返 回 值 :
827 调用函数 : hmac_tx_wlan_to_wlan_ap
828 被调函数 :
829
830 修改历史 :
831 1.日 期 : 2012年11月14日
832 作 者 : HiSilicon
833 修改内容 : 新生成函数
834
835 **************************************************************************** */
hmac_tx_get_mac_vap(hi_u8 vap_id,mac_vap_stru ** mac_vap)836 hi_u32 hmac_tx_get_mac_vap(hi_u8 vap_id, mac_vap_stru **mac_vap)
837 {
838 mac_vap_stru *mac_vap_value = HI_NULL;
839
840 /* 获取vap结构信息 */
841 mac_vap_value = mac_vap_get_vap_stru(vap_id);
842 if (oal_unlikely(mac_vap_value == HI_NULL)) {
843 oam_error_log0(vap_id, OAM_SF_TX, "{hmac_tx_get_mac_vap::pst_vap null}");
844 return HI_ERR_CODE_PTR_NULL;
845 }
846
847 /* VAP模式判断 */
848 if ((mac_vap_value->vap_mode != WLAN_VAP_MODE_BSS_AP)
849 #ifdef _PRE_WLAN_FEATURE_MESH
850 && (mac_vap_value->vap_mode != WLAN_VAP_MODE_MESH)
851 #endif
852 ) {
853 oam_warning_log1(mac_vap_value->vap_id, OAM_SF_TX, "hmac_tx_get_mac_vap::vap_mode error[%d]",
854 mac_vap_value->vap_mode);
855 return HI_ERR_CODE_CONFIG_UNSUPPORT;
856 }
857
858 /* VAP状态判断 */
859 if (mac_vap_value->vap_state == MAC_VAP_STATE_UP || mac_vap_value->vap_state == MAC_VAP_STATE_PAUSE) {
860 *mac_vap = mac_vap_value;
861
862 return HI_SUCCESS;
863 }
864
865 oam_warning_log1(mac_vap_value->vap_id, OAM_SF_TX, "hmac_tx_get_mac_vap::vap_state[%d] error",
866 mac_vap_value->vap_state);
867
868 return HI_ERR_CODE_CONFIG_UNSUPPORT;
869 }
870
871 #ifdef __cplusplus
872 #if __cplusplus
873 }
874 #endif
875 #endif
876