• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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