• 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 "wlan_mib.h"
23 #include "mac_frame.h"
24 #include "mac_ie.h"
25 #include "mac_regdomain.h"
26 #include "mac_user.h"
27 #include "mac_vap.h"
28 #include "mac_device.h"
29 #include "hmac_device.h"
30 #include "hmac_user.h"
31 #include "hmac_mgmt_sta.h"
32 #include "hmac_fsm.h"
33 #include "hmac_rx_data.h"
34 #include "hmac_chan_mgmt.h"
35 #include "hmac_mgmt_bss_comm.h"
36 #include "hmac_encap_frame_sta.h"
37 #include "hmac_sme_sta.h"
38 #include "hmac_scan.h"
39 #include "hmac_11i.h"
40 #include "hmac_config.h"
41 #include "hmac_ext_if.h"
42 #include "hmac_event.h"
43 #include "hmac_blockack.h"
44 #include "hcc_hmac_if.h"
45 #include "frw_timer.h"
46 #ifdef _PRE_WLAN_FEATURE_WAPI
47 #include "hmac_wapi.h"
48 #endif
49 #include "wal_customize.h"
50 
51 #ifdef __cplusplus
52 #if __cplusplus
53 extern "C" {
54 #endif
55 #endif
56 
57 /* ****************************************************************************
58   3 函数实现
59 **************************************************************************** */
60 /* ****************************************************************************
61  功能描述  : sta等待管理帧超时处理函数
62  修改历史      :
63   1.日    期   : 2013年7月8日
64     作    者   : HiSilicon
65     修改内容   : 新生成函数
66 **************************************************************************** */
hmac_mgmt_timeout_sta(hi_void * arg)67 static hi_u32 hmac_mgmt_timeout_sta(hi_void *arg)
68 {
69     hmac_vap_stru *hmac_vap = HI_NULL;
70     hmac_mgmt_timeout_param_stru *timeout_param = HI_NULL;
71 
72     timeout_param = (hmac_mgmt_timeout_param_stru *)arg;
73     hmac_vap = hmac_vap_get_vap_stru(timeout_param->vap_id);
74     if ((hmac_vap == HI_NULL) || (hmac_vap->base_vap == HI_NULL)) {
75         return HI_ERR_CODE_PTR_NULL;
76     }
77 
78     frw_timer_immediate_destroy_timer(&(hmac_vap->mgmt_timer));
79 
80     switch (hmac_vap->base_vap->vap_state) {
81         case MAC_VAP_STATE_STA_WAIT_AUTH_SEQ2:
82         case MAC_VAP_STATE_STA_WAIT_AUTH_SEQ4:
83             return hmac_sta_auth_timeout(hmac_vap);
84         case MAC_VAP_STATE_STA_WAIT_ASOC:
85             return hmac_sta_wait_asoc_timeout(hmac_vap);
86         default:
87             return HI_SUCCESS;
88     }
89 }
90 
91 /* ****************************************************************************
92  功能描述  : 在join之前更新协议相关的参数
93  修改历史      :
94   1.日    期   : 2013年10月23日
95     作    者   : HiSilicon
96     修改内容   : 新生成函数
97 **************************************************************************** */
hmac_update_join_req_params_prot_sta(hmac_vap_stru * hmac_vap,const hmac_join_req_stru * join_req)98 static hi_void hmac_update_join_req_params_prot_sta(hmac_vap_stru *hmac_vap, const hmac_join_req_stru *join_req)
99 {
100     if (hmac_vap->base_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type == WLAN_MIB_DESIRED_BSSTYPE_INFRA) {
101 #ifdef _PRE_WLAN_FEATURE_MESH
102         if (join_req->bss_dscr.is_hisi_mesh == HI_TRUE) {
103             hmac_vap->wmm_cap = HI_TRUE;
104         } else {
105             hmac_vap->wmm_cap = join_req->bss_dscr.wmm_cap;
106             mac_vap_set_uapsd_cap(hmac_vap->base_vap, join_req->bss_dscr.uapsd_cap);
107         }
108 #else
109         hmac_vap->wmm_cap = join_req->bss_dscr.wmm_cap;
110         mac_vap_set_uapsd_cap(hmac_vap->base_vap, join_req->bss_dscr.uapsd_cap);
111 #endif
112     }
113 }
114 
115 /* ****************************************************************************
116  功能描述  : 判断是否支持某种速率
117  修改历史      :
118   1.日    期   : 2016年3月31日
119     作    者   : HiSilicon
120     修改内容   : 新生成函数
121 **************************************************************************** */
hmac_is_rate_support(const hi_u8 * puc_rates,hi_u8 rate_num,hi_u8 rate)122 hi_u8 hmac_is_rate_support(const hi_u8 *puc_rates, hi_u8 rate_num, hi_u8 rate)
123 {
124     hi_u8 rate_is_supp = HI_FALSE;
125     hi_u8 loop;
126 
127     if (puc_rates == HI_NULL) {
128         oam_error_log0(0, OAM_SF_ANY, "{hmac_is_rate_support::puc_rates null}");
129         return HI_ERR_CODE_PTR_NULL;
130     }
131 
132     for (loop = 0; loop < rate_num; loop++) {
133         if ((puc_rates[loop] & 0x7F) == rate) {
134             rate_is_supp = HI_TRUE;
135             break;
136         }
137     }
138 
139     return rate_is_supp;
140 }
141 
142 /* ****************************************************************************
143  功能描述  : 是否支持11g速率
144  修改历史      :
145   1.日    期   : 2016年3月31日
146     作    者   : HiSilicon
147     修改内容   : 新生成函数
148 **************************************************************************** */
hmac_is_support_11grate(const hi_u8 * puc_rates,hi_u8 rate_num)149 hi_u8 hmac_is_support_11grate(const hi_u8 *puc_rates, hi_u8 rate_num)
150 {
151     if (puc_rates == HI_NULL) {
152         oam_error_log0(0, OAM_SF_ANY, "{hmac_is_rate_support::puc_rates null}");
153         return HI_ERR_CODE_PTR_NULL;
154     }
155 
156     if ((HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x0C)) ||
157         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x12)) ||
158         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x18)) ||
159         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x24)) ||
160         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x30)) ||
161         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x48)) ||
162         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x60)) ||
163         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x6C))) {
164         return HI_TRUE;
165     }
166 
167     return HI_FALSE;
168 }
169 
170 /* ****************************************************************************
171  功能描述  : 是否支持11b速率
172  修改历史      :
173   1.日    期   : 2016年3月31日
174     作    者   : HiSilicon
175     修改内容   : 新生成函数
176 **************************************************************************** */
hmac_is_support_11brate(const hi_u8 * puc_rates,hi_u8 rate_num)177 hi_u8 hmac_is_support_11brate(const hi_u8 *puc_rates, hi_u8 rate_num)
178 {
179     if (puc_rates == HI_NULL) {
180         oam_error_log0(0, OAM_SF_ANY, "{hmac_is_support_11brate::puc_rates null}");
181         return HI_ERR_CODE_PTR_NULL;
182     }
183 
184     if ((HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x02)) ||
185         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x04)) ||
186         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x0B)) ||
187         (HI_TRUE == hmac_is_rate_support(puc_rates, rate_num, 0x16))) {
188         return HI_TRUE;
189     }
190 
191     return HI_FALSE;
192 }
193 
194 /* ****************************************************************************
195  功能描述  : 获取用户的协议模式
196  修改历史      :
197   1.日    期   : 2014年8月27日
198     作    者   : HiSilicon
199     修改内容   : 新生成函数
200 **************************************************************************** */
hmac_sta_get_user_protocol(mac_bss_dscr_stru * bss_dscr,wlan_protocol_enum_uint8 * protocol_mode)201 hi_u32 hmac_sta_get_user_protocol(mac_bss_dscr_stru *bss_dscr, wlan_protocol_enum_uint8 *protocol_mode)
202 {
203     /* 入参保护 */
204     if (bss_dscr == HI_NULL || protocol_mode == HI_NULL) {
205         oam_error_log2(0, OAM_SF_SCAN, "{hmac_sta_get_user_protocol::param null,%p %p.}", (uintptr_t)bss_dscr,
206             (uintptr_t)protocol_mode);
207         return HI_ERR_CODE_PTR_NULL;
208     }
209 
210     if (bss_dscr->ht_capable == HI_TRUE) {
211         *protocol_mode = WLAN_HT_MODE;
212     } else {
213         if (hmac_is_support_11grate(bss_dscr->auc_supp_rates, bss_dscr->num_supp_rates) == HI_TRUE) {
214             *protocol_mode = WLAN_LEGACY_11G_MODE;
215             if (hmac_is_support_11brate(bss_dscr->auc_supp_rates, bss_dscr->num_supp_rates) == HI_TRUE) {
216                 *protocol_mode = WLAN_MIXED_ONE_11G_MODE;
217             }
218         } else if (hmac_is_support_11brate(bss_dscr->auc_supp_rates, bss_dscr->num_supp_rates) == HI_TRUE) {
219             *protocol_mode = WLAN_LEGACY_11B_MODE;
220         } else {
221             oam_warning_log0(0, OAM_SF_ANY, "{hmac_sta_get_user_protocol::get user protocol failed.}");
222             return HI_FAIL;
223         }
224     }
225 
226     return HI_SUCCESS;
227 }
228 
hmac_sta_need_update_protocol(wlan_protocol_enum_uint8 vap_protocol,wlan_protocol_enum_uint8 user_protocol)229 hi_u8 hmac_sta_need_update_protocol(wlan_protocol_enum_uint8 vap_protocol, wlan_protocol_enum_uint8 user_protocol)
230 {
231     if (((vap_protocol == WLAN_MIXED_ONE_11G_MODE) && (user_protocol == WLAN_LEGACY_11B_MODE)) ||
232         ((vap_protocol == WLAN_HT_MODE) &&
233         ((user_protocol == WLAN_LEGACY_11B_MODE) || (user_protocol == WLAN_MIXED_ONE_11G_MODE)))) {
234         return HI_TRUE;
235     }
236     return HI_FALSE;
237 }
238 
239 /* ****************************************************************************
240  功能描述  : 根据带宽获取转换到us的放大倍数(转换为移位数)
241  修改历史      :
242   1.日    期   : 2019年7月11日
243     作    者   : HiSilicon
244     修改内容   : 新生成函数
245 **************************************************************************** */
hmac_dbac_get_scale_by_bw(hi_u8 bandwidth)246 hi_u8 hmac_dbac_get_scale_by_bw(hi_u8 bandwidth)
247 {
248     hi_u8 scale = 0;
249 
250     if (bandwidth == WLAN_BAND_WIDTH_5M) {
251         scale = 2; /* 5M是4倍,对应位移数2 */
252     } else if (bandwidth == WLAN_BAND_WIDTH_10M) {
253         scale = 1; /* 10M是2倍,对应位移数1 */
254     } else {
255         scale = 0;
256     }
257     return scale;
258 }
259 
260 /* ****************************************************************************
261  功能描述  : 根据join_request帧更新sta关联的信道相关信息
262 **************************************************************************** */
hmac_sta_update_join_channel(mac_vap_stru * mac_vap,const hmac_join_req_stru * join_req)263 static hi_u32 hmac_sta_update_join_channel(mac_vap_stru *mac_vap, const hmac_join_req_stru *join_req)
264 {
265     mac_device_stru *mac_dev = HI_NULL;
266     hi_u8 bcn_scale;
267 
268     mac_dev = mac_res_get_dev();
269     /* 设置BSSID */
270     mac_vap_set_bssid(mac_vap, join_req->bss_dscr.auc_bssid, WLAN_MAC_ADDR_LEN);
271     /* 更新mib库对应的ssid */
272     if (memcpy_s(mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_desired_ssid, WLAN_SSID_MAX_LEN,
273         join_req->bss_dscr.ac_ssid, WLAN_SSID_MAX_LEN) != EOK) {
274         oam_error_log0(0, OAM_SF_CFG, "hmac_sta_update_join_channel:: ac_ssid memcpy_s fail.");
275         return HI_FAIL;
276     }
277     mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_desired_ssid[WLAN_SSID_MAX_LEN - 1] = '\0';
278 
279     /* 根据带宽转换beacon周期为单位TU */
280     bcn_scale = hmac_dbac_get_scale_by_bw(mac_vap->channel.en_bandwidth);
281     /* 更新mib库对应的dot11BeaconPeriod值 */
282     mac_vap->mib_info->wlan_mib_sta_config.dot11_beacon_period =
283         ((hi_u32)(join_req->bss_dscr.us_beacon_period)) << bcn_scale;
284     /* 更新mib库对应的ul_dot11CurrentChannel值 */
285     mac_vap_set_current_channel(mac_vap, join_req->bss_dscr.channel.band, join_req->bss_dscr.channel.chan_number);
286 
287     /* 更新频带、主20MHz信道号,与AP通信 DMAC切换信道时直接调用 */
288     if ((mac_vap->channel.en_bandwidth != WLAN_BAND_WIDTH_5M) &&
289         (mac_vap->channel.en_bandwidth != WLAN_BAND_WIDTH_10M)) {  /* 仅在非窄带时更新 */
290         mac_vap->channel.en_bandwidth =
291             hmac_sta_get_band(mac_dev->bandwidth_cap, join_req->bss_dscr.channel_bandwidth);
292     }
293     mac_vap->channel.chan_number = join_req->bss_dscr.channel.chan_number;
294     mac_vap->channel.band = join_req->bss_dscr.channel.band;
295 
296     return HI_SUCCESS;
297 }
298 
299 /* ****************************************************************************
300  功能描述  : 根据join_request帧更新sta关联的协议模式相关信息
301 **************************************************************************** */
hmac_sta_update_join_protocol(const hmac_vap_stru * hmac_vap,hmac_join_req_stru * join_req)302 static hi_u32 hmac_sta_update_join_protocol(const hmac_vap_stru *hmac_vap, hmac_join_req_stru *join_req)
303 {
304     mac_cfg_mode_param_stru cfg_mode = { 0 };
305     mac_vap_stru *mac_vap = hmac_vap->base_vap;
306 
307     /* Mesh beacon帧中不带速率集,无法获取对应协议模式,规格默认Mesh为11BGN,不会出现STA协议模式比关联AP高的情形 */
308     if (join_req->bss_dscr.is_hisi_mesh == HI_FALSE) {
309         if (hmac_sta_get_user_protocol(&join_req->bss_dscr, &cfg_mode.protocol) != HI_SUCCESS) {
310             oam_error_log0(0, OAM_SF_SCAN, "{hmac_sta_update_join_req_params::hmac_sta_get_user_protocol fail.}");
311             return HI_FAIL;
312         }
313         /* STA的协议模式比要关联的AP高,则更新mib库中对应的相关能力 */
314         if (hmac_sta_need_update_protocol(mac_vap->protocol, cfg_mode.protocol) == HI_TRUE) {
315             /* 关联前先将STA模式恢复成设置前,防止之前关联跟随AP时模式降低不恢复 */
316             mac_vap->protocol = hmac_vap->preset_para.protocol;
317             mac_vap->mib_info->wlan_mib_sta_config.dot11_high_throughput_option_implemented =
318                 join_req->bss_dscr.ht_capable;
319             mac_vap->mib_info->phy_ht.dot11_ldpc_coding_option_implemented = (join_req->bss_dscr.ht_ldpc &&
320                 mac_vap->mib_info->phy_ht.dot11_ldpc_coding_option_activated);
321             mac_vap->mib_info->phy_ht.dot11_tx_stbc_option_implemented = (join_req->bss_dscr.ht_stbc &&
322                 mac_vap->mib_info->phy_ht.dot11_tx_stbc_option_activated);
323 
324             /* 关联2G AP,且2ght40禁止位为1时,不学习AP的HT 40能力 */
325             mac_mib_set_forty_mhz_operation_implemented(mac_vap, HI_FALSE);
326             if (!(mac_vap->channel.band == WLAN_BAND_2G && mac_vap->cap_flag.disable_2ght40) &&
327                 (join_req->bss_dscr.bw_cap != WLAN_BW_CAP_20M)) {
328                 mac_mib_set_forty_mhz_operation_implemented(mac_vap, HI_TRUE);
329             }
330 
331             /* 根据要加入AP的协议模式更新STA侧速率集 */
332             cfg_mode.band = join_req->bss_dscr.channel.band;
333             cfg_mode.en_bandwidth = mac_vap->channel.en_bandwidth;
334             cfg_mode.channel_idx = join_req->bss_dscr.channel.chan_number;
335             if (hmac_config_sta_update_rates(mac_vap, &cfg_mode) != HI_SUCCESS) {
336                 oam_error_log0(0, OAM_SF_SCAN, "{hmac_sta_update_join_protocol::hmac_config_sta_update_rates fail.}");
337                 return HI_FAIL;
338             }
339         }
340     }
341 
342     /* wapi 需要降协议 */
343     if (join_req->bss_dscr.wapi) {
344         hmac_update_pcip_policy_prot_supplicant(mac_vap, WLAN_80211_CIPHER_SUITE_WAPI);
345         oam_warning_log0(0, OAM_SF_SCAN, "{hmac_sta_update_join_protocol::wapi prot fall!}");
346     }
347 
348     /* 更新mib库对应的加密相关值 */
349     if (hmac_update_current_join_req_parms_11i(mac_vap, &join_req->bss_dscr.bss_sec_info) != HI_SUCCESS) {
350         oam_error_log0(0, OAM_SF_SCAN, "{hmac_sta_update_join_protocol::update security parameter failed.}");
351         return HI_FAIL;
352     }
353 
354     cfg_mode.protocol = mac_vap->protocol;
355     cfg_mode.band = mac_vap->channel.band;
356     cfg_mode.en_bandwidth = mac_vap->channel.en_bandwidth;
357     cfg_mode.channel_idx = join_req->bss_dscr.channel.chan_number;
358 
359     return hmac_config_sta_update_rates(mac_vap, &cfg_mode);
360 }
361 
362 /* ****************************************************************************
363  功能描述  : 发送关联请求事件到dmac
364 **************************************************************************** */
hmac_sta_dispatch_join_req(const mac_vap_stru * mac_vap,const hmac_join_req_stru * join_req)365 static hi_u32 hmac_sta_dispatch_join_req(const mac_vap_stru *mac_vap, const hmac_join_req_stru *join_req)
366 {
367     frw_event_mem_stru *event_mem = HI_NULL;
368     frw_event_stru *event = HI_NULL;
369     dmac_ctx_join_req_set_reg_stru *reg_params = HI_NULL;
370 
371     /* 抛事件到DMAC, 申请事件内存 */
372     event_mem = frw_event_alloc(sizeof(dmac_ctx_join_req_set_reg_stru));
373     if (event_mem == HI_NULL) {
374         oam_error_log0(0, OAM_SF_SCAN, "{hmac_sta_update_join_req_params::event_mem null.}");
375         return HI_ERR_CODE_PTR_NULL;
376     }
377 
378     /* 填写事件 */
379     event = (frw_event_stru *)event_mem->puc_data;
380     frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_JOIN_SET_REG,
381         sizeof(dmac_ctx_join_req_set_reg_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
382 
383     reg_params = (dmac_ctx_join_req_set_reg_stru *)event->auc_event_data;
384     /* 设置需要写入寄存器的BSSID信息 */
385     if (memcpy_s(reg_params->auc_bssid, WLAN_MAC_ADDR_LEN, join_req->bss_dscr.auc_bssid, WLAN_MAC_ADDR_LEN) != EOK) {
386         frw_event_free(event_mem);
387         oam_error_log0(0, 0, "{alg_autorate_init_rate_policy::copy bssid failed!}");
388         return HI_FAIL;
389     }
390 
391     /* 填写信道相关信息 */
392     reg_params->current_channel.chan_number = mac_vap->channel.chan_number;
393     reg_params->current_channel.band = mac_vap->channel.band;
394     reg_params->current_channel.en_bandwidth = mac_vap->channel.en_bandwidth;
395     reg_params->current_channel.idx = mac_vap->channel.idx;
396 
397     /* 设置beaocn period信息 */
398     reg_params->us_beacon_period = (join_req->bss_dscr.us_beacon_period);
399     /* 同步FortyMHzOperationImplemented */
400     reg_params->dot11_forty_m_hz_operation_implemented = mac_mib_get_forty_mhz_operation_implemented(mac_vap);
401     /* 设置beacon filter关闭 */
402     reg_params->beacon_filter = HI_FALSE;
403     /* 设置no frame filter打开 */
404     reg_params->non_frame_filter = HI_TRUE;
405     /* 下发ssid */
406     if (memcpy_s(reg_params->auc_ssid, WLAN_SSID_MAX_LEN, join_req->bss_dscr.ac_ssid, WLAN_SSID_MAX_LEN) != EOK) {
407         frw_event_free(event_mem);
408         oam_error_log0(0, OAM_SF_CFG, "hmac_sta_update_join_req_params:: ac_ssid memcpy_s fail.");
409         return HI_FAIL;
410     }
411     reg_params->auc_ssid[WLAN_SSID_MAX_LEN - 1] = '\0';
412 
413     /* 分发事件 */
414     hcc_hmac_tx_control_event(event_mem, sizeof(dmac_ctx_join_req_set_reg_stru));
415     frw_event_free(event_mem);
416 
417     return HI_SUCCESS;
418 }
419 
420 /* ****************************************************************************
421  功能描述  : 根据join_request帧更新mib信息和填写相应寄存器
422  输入参数  : hmac_vap_stru      *pst_hmac_vap,
423              hmac_join_req_stru *pst_join_req
424  修改历史      :
425   1.日    期   : 2013年7月3日
426     作    者   : HiSilicon
427     修改内容   : 新生成函数
428 
429  2.日    期   : 2014年4月7日
430     作    者   : HiSilicon
431    修改内容   : 删除打印日志,整理错误码
432 **************************************************************************** */
hmac_sta_update_join_req_params(hmac_vap_stru * hmac_vap,hmac_join_req_stru * join_req)433 static hi_u32 hmac_sta_update_join_req_params(hmac_vap_stru *hmac_vap, hmac_join_req_stru *join_req)
434 {
435     mac_vap_stru *mac_vap = hmac_vap->base_vap;
436     hi_u32 ret;
437     mac_device_stru *mac_dev = HI_NULL;
438     wlan_mib_ieee802dot11_stru *mib_info = mac_vap->mib_info;
439 
440     if (mib_info == HI_NULL) {
441         return HI_ERR_CODE_PTR_NULL;
442     }
443     mac_dev = mac_res_get_dev();
444     /* 关联前根据sta是否支持wmm重新刷新mib值,防止之前关联不支持wmm的ap,mib恢复不过来 */
445     mib_info->wlan_mib_sta_config.dot11_qos_option_implemented = mac_dev->wmm;
446     /* 根据join_request帧更新sta关联的信道和带宽相关信息 */
447     if (hmac_sta_update_join_channel(mac_vap, join_req) != HI_SUCCESS) {
448         return HI_FAIL;
449     }
450     /* 根据join_request帧更新sta关联的协议模式相关信息 */
451     if (hmac_sta_update_join_protocol(hmac_vap, join_req) != HI_SUCCESS) {
452         return HI_FAIL;
453     }
454 
455     /* STA首先以20MHz运行,如果要切换到40 or 80MHz运行,需要满足一下条件: */
456     /* (1) 用户支持40 or 80MHz运行 */
457     /* (2) AP支持40 or 80MHz运行(HT Supported Channel Width Set = 1 && VHT Supported Channel Width Set = 0) */
458     /* (3) AP在40 or 80MHz运行(SCO = SCA or SCB && VHT Channel Width = 1) */
459     ret = mac_get_channel_idx_from_num(mac_vap->channel.band, mac_vap->channel.chan_number, &(mac_vap->channel.idx));
460     if (ret != HI_SUCCESS) {
461         oam_error_log2(mac_vap->vap_id, OAM_SF_SCAN,
462             "{hmac_sta_update_join_req_params::band and channel_num are not compatible.band[%d], channel_num[%d]}",
463             mac_vap->channel.band, mac_vap->channel.chan_number);
464         return ret;
465     }
466 
467     /* 更新协议相关信息,包括WMM P2P 11I 20/40M等 */
468     hmac_update_join_req_params_prot_sta(hmac_vap, join_req);
469     /* 入网优化,不同频段下的能力不一样 */
470     if (WLAN_BAND_2G == mac_vap->channel.band) {
471         mac_mib_set_short_preamble_option_implemented(mac_vap, WLAN_LEGACY_11B_MIB_SHORT_PREAMBLE);
472         mac_mib_set_spectrum_management_required(mac_vap, HI_FALSE);
473     } else {
474         mac_mib_set_short_preamble_option_implemented(mac_vap, WLAN_LEGACY_11B_MIB_LONG_PREAMBLE);
475         mac_mib_set_spectrum_management_required(mac_vap, HI_TRUE);
476     }
477 
478     if (0 == hmac_calc_up_vap_num(mac_dev)) {
479         mac_dev->max_channel = mac_vap->channel.chan_number;
480         mac_dev->max_band = mac_vap->channel.band;
481         mac_dev->max_bandwidth = mac_vap->channel.en_bandwidth;
482     }
483     /* 发送关联请求事件到dmac */
484     return hmac_sta_dispatch_join_req(mac_vap, join_req);
485 }
486 
487 /* ****************************************************************************
488  功能描述  : 处理SME发送过来的JOIN_REQ命令,启动JOIN流程,将STA状态设置为WAIT_JOIN
489  修改历史      :
490   1.日    期   : 2013年7月1日
491     作    者   : HiSilicon
492     修改内容   : 新生成函数
493   2.日    期   : 2015年4月7日
494     作    者   : HiSilicon
495     修改内容   : 删除等待beacon及tbtt中断的操作
496 **************************************************************************** */
hmac_sta_wait_join(hmac_vap_stru * hmac_vap,hmac_join_req_stru * join_req)497 hi_u32 hmac_sta_wait_join(hmac_vap_stru *hmac_vap, hmac_join_req_stru *join_req)
498 {
499 #ifdef _PRE_WLAN_FEATURE_P2P
500     /* 1102 P2PSTA共存 用于 更新参数失败的话需要返回而不是继续下发Join动作 */
501     if (hmac_p2p_check_can_enter_state(hmac_vap->base_vap, HMAC_FSM_INPUT_ASOC_REQ) != HI_SUCCESS) {
502         /* 不能进入监听状态,返回设备忙 */
503         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_join fail}\r\n");
504         return HI_ERR_CODE_CONFIG_BUSY;
505     }
506 #endif
507 
508     /* 更新JOIN REG params 到MIB及MAC寄存器 */
509     hi_u32 ret = hmac_sta_update_join_req_params(hmac_vap, join_req);
510     if (ret != HI_SUCCESS) {
511         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_join::params fail[%d]!}", ret);
512         return ret;
513     }
514     oam_info_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_join::chn=%d bcnPeriod=%d DTIMPeriod=%d.}",
515         join_req->bss_dscr.channel.chan_number, join_req->bss_dscr.us_beacon_period, join_req->bss_dscr.dtim_period);
516 
517     /* 非proxy sta模式时,需要将dtim参数配置到dmac */
518     /* 抛事件到DMAC, 申请事件内存 */
519     frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_ctx_set_dtim_tsf_reg_stru));
520     if (event_mem == HI_NULL) {
521         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_join::alloc null.}");
522         return HI_ERR_CODE_PTR_NULL;
523     }
524 
525     /* 填写事件 */
526     frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
527 
528     frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_JOIN_DTIM_TSF_REG,
529         sizeof(dmac_ctx_set_dtim_tsf_reg_stru), FRW_EVENT_PIPELINE_STAGE_1, hmac_vap->base_vap->vap_id);
530 
531     dmac_ctx_set_dtim_tsf_reg_stru *set_dtim_tsf_reg_params = (dmac_ctx_set_dtim_tsf_reg_stru *)event->auc_event_data;
532 
533     /* 将Ap bssid和tsf REG 设置值保存在事件payload中 */
534     set_dtim_tsf_reg_params->dtim_cnt = join_req->bss_dscr.dtim_cnt;
535     set_dtim_tsf_reg_params->dtim_period = join_req->bss_dscr.dtim_period;
536     set_dtim_tsf_reg_params->us_tsf_bit0 = BIT0;
537     if (memcpy_s(set_dtim_tsf_reg_params->auc_bssid, WLAN_MAC_ADDR_LEN, hmac_vap->base_vap->auc_bssid,
538         WLAN_MAC_ADDR_LEN) != EOK) {
539         frw_event_free(event_mem);
540         oam_error_log0(0, OAM_SF_CFG, "hmac_sta_wait_join:: auc_bssid memcpy_s fail.");
541         return HI_FAIL;
542     }
543 
544     /* 分发事件 */
545     hcc_hmac_tx_control_event(event_mem, sizeof(dmac_ctx_set_dtim_tsf_reg_stru));
546     frw_event_free(event_mem);
547 
548     hmac_mgmt_status_enum_uint8 join_result_code = HMAC_MGMT_SUCCESS;
549     /* 切换STA状态到JOIN_COMP */
550     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_JOIN_COMP);
551 
552     /* 发送JOIN成功消息给SME */
553     hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_JOIN_RSP, &join_result_code);
554 
555     oam_info_log4(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
556         "{hmac_sta_wait_join::Join AP[XX:XX:XX:%02X:%02X:%02X] HT=%d VHT=%d HI_SUCCESS.}",
557         join_req->bss_dscr.auc_bssid[3], join_req->bss_dscr.auc_bssid[4], /* 3 4 元素索引 */
558         join_req->bss_dscr.auc_bssid[5], join_req->bss_dscr.ht_capable);  /* 5 元素索引 */
559 
560     oam_info_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
561         "{hmac_sta_wait_join::Join AP channel=%d bandwidth=%d Beacon Period=%d HI_SUCCESS.}",
562         join_req->bss_dscr.channel.chan_number, hmac_vap->base_vap->channel.en_bandwidth,
563         join_req->bss_dscr.us_beacon_period);
564     return HI_SUCCESS;
565 }
566 
567 /* ****************************************************************************
568  功能描述  : 处理sme发来的auth req请求。将状态置为WAIT_AUTH_SEQ2 抛事件到dmac发送
569  修改历史      :
570   1.日    期   : 2013年6月25日
571     作    者   : HiSilicon
572     修改内容   : 新生成函数
573 **************************************************************************** */
hmac_sta_wait_auth(hmac_vap_stru * hmac_vap,hi_u16 auth_timeout)574 hi_u32 hmac_sta_wait_auth(hmac_vap_stru *hmac_vap, hi_u16 auth_timeout)
575 {
576     /* 申请认证帧空间 */
577     oal_netbuf_stru *auth_frame = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
578     if (auth_frame == HI_NULL) {
579         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::puc_auth_frame null.}");
580         return HI_ERR_CODE_PTR_NULL;
581     }
582     /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
583     memset_s(oal_netbuf_cb(auth_frame), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
584 
585     if (memset_s((hi_u8 *)oal_netbuf_header(auth_frame), MAC_80211_FRAME_LEN, 0, MAC_80211_FRAME_LEN) != EOK) {
586         oal_netbuf_free(auth_frame);
587         return HI_FAIL;
588     }
589 
590     /* 组认证请求帧 */
591     hi_u16 us_auth_len = hmac_mgmt_encap_auth_req(hmac_vap, (hi_u8 *)(oal_netbuf_header(auth_frame)));
592     if (us_auth_len == 0) {
593         /* 组帧失败 */
594         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta:hmac_mgmt_encap_auth_req fail}");
595 
596         oal_netbuf_free(auth_frame);
597         hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
598         /* 报系统错误,reset MAC 之类的 */
599         return HI_FAIL;
600     }
601 
602     oal_netbuf_put(auth_frame, us_auth_len);
603     hmac_user_stru *hmac_user_ap = (hmac_user_stru *)hmac_user_get_user_stru(hmac_vap->base_vap->assoc_vap_id);
604     if ((hmac_user_ap == HI_NULL) || (hmac_user_ap->base_user == HI_NULL)) {
605         oal_netbuf_free(auth_frame);
606         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::pst_hmac_user_ap null.}");
607         return HI_ERR_CODE_PTR_NULL;
608     }
609 
610     /* 为填写发送描述符准备参数 */
611     hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(auth_frame); /* 获取cb结构体 */
612     tx_ctl->us_mpdu_len = us_auth_len;                                        /* dmac发送需要的mpdu长度 */
613     tx_ctl->us_tx_user_idx = hmac_user_ap->base_user->us_assoc_id; /* 发送完成需要获取user结构体 */
614     tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
615     tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(auth_frame);
616     tx_ctl->mac_head_type = 1;
617 
618     /* 如果是WEP,需要将ap的mac地址写入lut */
619     hi_u32 ret = hmac_init_security(hmac_vap->base_vap, hmac_user_ap->base_user->user_mac_addr, WLAN_MAC_ADDR_LEN);
620     if (ret != HI_SUCCESS) {
621         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_auth::security failed[%d].}", ret);
622     }
623 
624     /* 抛事件让dmac将该帧发送 */
625     ret = hmac_tx_mgmt_send_event(hmac_vap->base_vap, auth_frame, us_auth_len);
626     if (ret != HI_SUCCESS) {
627         oal_netbuf_free(auth_frame);
628         oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_AUTH,
629             "{hmac_wait_auth_sta::hmac_tx_mgmt_send_event failed[%d].}", ret);
630         return ret;
631     }
632 
633     /* 更改状态 */
634     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_WAIT_AUTH_SEQ2);
635 
636     /* 启动认证超时定时器 */
637     hmac_vap->mgmt_timetout_param.state = MAC_VAP_STATE_STA_WAIT_AUTH_SEQ2;
638     hmac_vap->mgmt_timetout_param.user_index = (hi_u8)hmac_user_ap->base_user->us_assoc_id;
639     hmac_vap->mgmt_timetout_param.vap_id = hmac_vap->base_vap->vap_id;
640     frw_timer_create_timer(&hmac_vap->mgmt_timer, hmac_mgmt_timeout_sta, auth_timeout, &hmac_vap->mgmt_timetout_param,
641         HI_FALSE);
642 
643     return HI_SUCCESS;
644 }
645 
hmac_sta_shared_key_auth_proc(hmac_vap_stru * hmac_vap,hi_u8 * mac_hdr)646 hi_u32 hmac_sta_shared_key_auth_proc(hmac_vap_stru *hmac_vap, hi_u8 *mac_hdr)
647 {
648     oal_netbuf_stru *auth_frame = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
649     if (auth_frame == HI_NULL) {
650         /* 复位mac */
651         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::pst_auth_frame null.}");
652         return HI_ERR_CODE_PTR_NULL;
653     }
654 
655     /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化 */
656     memset_s(oal_netbuf_cb(auth_frame), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
657 
658     hi_u16 auth_frame_len = hmac_mgmt_encap_auth_req_seq3(hmac_vap, (hi_u8 *)oal_netbuf_header(auth_frame), mac_hdr);
659     if (auth_frame_len == 0) {
660         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::auth_frame_len is 0.}");
661         oal_netbuf_free(auth_frame);
662         return HI_FAIL;
663     }
664     oal_netbuf_put(auth_frame, auth_frame_len);
665 
666     hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru((hi_u16)hmac_vap->base_vap->assoc_vap_id);
667     if ((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL)) {
668         oal_netbuf_free(auth_frame);
669         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::pst_hmac_user_ap null.}");
670         return HI_ERR_CODE_PTR_NULL;
671     }
672 
673     /* 填写发送和发送完成需要的参数 */
674     hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(auth_frame);
675     tx_ctl->us_mpdu_len         = auth_frame_len;                    /* 发送需要帧长度 */
676     tx_ctl->us_tx_user_idx      = hmac_user->base_user->us_assoc_id; /* 发送完成要获取用户 */
677     tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
678     tx_ctl->frame_header        = (mac_ieee80211_frame_stru *)oal_netbuf_header(auth_frame);
679     tx_ctl->mac_head_type       = 1;
680 
681     /* 抛事件给dmac发送 */
682     hi_u32 ret = hmac_tx_mgmt_send_event(hmac_vap->base_vap, auth_frame, auth_frame_len);
683     if (ret != HI_SUCCESS) {
684         oal_netbuf_free(auth_frame);
685         oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_wait_auth_sta::send_event Err=%d}", ret);
686         return ret;
687     }
688 
689     frw_timer_immediate_destroy_timer(&hmac_vap->mgmt_timer);
690 
691     /* 更改状态为MAC_VAP_STATE_STA_WAIT_AUTH_SEQ4,并启动定时器 */
692     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_WAIT_AUTH_SEQ4);
693 
694     frw_timer_create_timer(&hmac_vap->mgmt_timer, hmac_mgmt_timeout_sta, hmac_vap->mgmt_timer.timeout,
695         &hmac_vap->mgmt_timetout_param, HI_FALSE);
696 
697     return HI_SUCCESS;
698 }
699 
700 /* ****************************************************************************
701  功能描述  : 处理接收到seq num 等于2 的认证帧
702  修改历史      :
703   1.日    期   : 2013年6月27日
704     作    者   : HiSilicon
705     修改内容   : 新生成函数
706 **************************************************************************** */
hmac_sta_wait_auth_seq2_rx(hmac_vap_stru * hmac_vap,const dmac_wlan_crx_event_stru * crx_event)707 hi_u32 hmac_sta_wait_auth_seq2_rx(hmac_vap_stru *hmac_vap, const dmac_wlan_crx_event_stru *crx_event)
708 {
709     hmac_auth_rsp_stru auth_rsp = { 0 };
710 
711     /* 每一个MPDU的控制信息 */
712     hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb((oal_netbuf_stru *)crx_event->netbuf);
713     hi_u8            *mac_hdr = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr;
714 
715     if ((mac_get_frame_sub_type(mac_hdr) != WLAN_FC0_SUBTYPE_AUTH) ||
716         (mac_get_auth_seq_num(mac_hdr) != WLAN_AUTH_TRASACTION_NUM_TWO)) {
717         return HI_SUCCESS;
718     }
719 
720     /* AUTH alg CHECK */
721     hi_u16 auth_alg = mac_get_auth_alg(mac_hdr);
722     if ((hmac_vap->auth_mode != auth_alg) && (hmac_vap->auth_mode != WLAN_WITP_AUTH_AUTOMATIC)) {
723         oam_warning_log2(hmac_vap->base_vap->vap_id, OAM_SF_AUTH,
724             "{hmac_sta_wait_auth_seq2_rx::rcv unexpected auth alg[%d/%d].}", auth_alg, hmac_vap->auth_mode);
725     }
726 
727     if (mac_get_auth_status(mac_hdr) != MAC_SUCCESSFUL_STATUSCODE) {
728         frw_timer_immediate_destroy_timer(&hmac_vap->mgmt_timer);
729 
730         auth_rsp.us_status_code = mac_get_auth_status(mac_hdr);
731 
732         /* 上报给SME认证成功 */
733         hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_AUTH_RSP, (hi_u8 *)&auth_rsp);
734         return HI_SUCCESS;
735     }
736 
737     if (auth_alg == WLAN_WITP_AUTH_OPEN_SYSTEM) {
738         frw_timer_immediate_destroy_timer(&hmac_vap->mgmt_timer);
739 
740         /* 将状态更改为AUTH_COMP */
741         hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_AUTH_COMP);
742         auth_rsp.us_status_code = HMAC_MGMT_SUCCESS;
743 
744         /* 上报给SME认证成功 */
745         hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_AUTH_RSP, (hi_u8 *)&auth_rsp);
746 
747         return HI_SUCCESS;
748     } else if (auth_alg == WLAN_WITP_AUTH_SHARED_KEY) {
749         /* 准备seq等于3的认证帧 */
750         hi_u32 ret = hmac_sta_shared_key_auth_proc(hmac_vap, mac_hdr);
751         return ret;
752     } else {
753         frw_timer_immediate_destroy_timer(&hmac_vap->mgmt_timer);
754 
755         /* 接收到AP 回复的auth response 中支持认证算法当前不支持的情况下,status code 却是SUCC,
756            认为认证成功,并且继续出发关联 */
757         oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_wait_auth_seq2_rx::auth_alg[%d]Err}",
758             auth_alg);
759 
760         /* 将状态更改为AUTH_COMP */
761         hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_AUTH_COMP);
762         auth_rsp.us_status_code = HMAC_MGMT_SUCCESS;
763 
764         /* 上报给SME认证成功 */
765         hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_AUTH_RSP, (hi_u8 *)&auth_rsp);
766 
767         return HI_SUCCESS;
768     }
769 }
770 
771 /* ****************************************************************************
772  功能描述  : 处理收到seq = 4 的认证帧
773  修改历史      :
774   1.日    期   : 2013年6月28日
775     作    者   : HiSilicon
776     修改内容   : 新生成函数
777 **************************************************************************** */
hmac_sta_wait_auth_seq4_rx(hmac_vap_stru * hmac_vap,const dmac_wlan_crx_event_stru * crx_event)778 hi_u32 hmac_sta_wait_auth_seq4_rx(hmac_vap_stru *hmac_vap, const dmac_wlan_crx_event_stru *crx_event)
779 {
780     hmac_rx_ctl_stru    *rx_ctrl = HI_NULL;
781     hi_u8               *puc_mac_hdr = HI_NULL;
782     hi_u16              us_auth_status;
783     hmac_auth_rsp_stru  auth_rsp = {{0}, 0};
784 
785     /* 每一个MPDU的控制信息 */
786     rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb((oal_netbuf_stru *)crx_event->netbuf);
787     puc_mac_hdr = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr;
788 
789     if (WLAN_FC0_SUBTYPE_AUTH == mac_get_frame_sub_type(puc_mac_hdr)) {
790         us_auth_status = mac_get_auth_status(puc_mac_hdr);
791         if ((WLAN_AUTH_TRASACTION_NUM_FOUR == mac_get_auth_seq_num(puc_mac_hdr)) &&
792             (us_auth_status == MAC_SUCCESSFUL_STATUSCODE)) {
793             /* 接收到seq = 4 且状态位为succ 取消定时器 */
794             frw_timer_immediate_destroy_timer(&hmac_vap->mgmt_timer);
795 
796             auth_rsp.us_status_code = HMAC_MGMT_SUCCESS;
797 
798             /* 更改sta状态为MAC_VAP_STATE_STA_AUTH_COMP */
799             hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_AUTH_COMP);
800             oam_info_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_wait_auth_seq4_rx::auth succ.}");
801             /* 将认证结果上报SME */
802             hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_AUTH_RSP, (hi_u8 *)&auth_rsp);
803         } else {
804             oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_AUTH,
805                 "{hmac_sta_wait_auth_seq4_rx::transaction num.status[%d]}", us_auth_status);
806             /* 等待定时器超时 */
807         }
808     }
809 
810     return HI_SUCCESS;
811 }
812 
hmac_sta_encap_asoc_req_frame(hmac_vap_stru * hmac_vap,oal_netbuf_stru * asoc_req_frame,hi_u32 * asoc_frame_len)813 static hi_u32 hmac_sta_encap_asoc_req_frame(hmac_vap_stru *hmac_vap, oal_netbuf_stru *asoc_req_frame,
814     hi_u32 *asoc_frame_len)
815 {
816     /* 组帧 (Re)Assoc_req_Frame */
817     hi_u32 asoc_frame_len_local = hmac_mgmt_encap_asoc_req_sta(hmac_vap, (hi_u8 *)(oal_netbuf_header(asoc_req_frame)));
818     if (asoc_frame_len_local == 0) {
819         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_asoc::get asoc_frame_len fail.}");
820         return HI_FAIL;
821     }
822     oal_netbuf_put(asoc_req_frame, asoc_frame_len_local);
823 
824     if (hmac_vap->puc_asoc_req_ie_buff != HI_NULL) {
825         oal_mem_free(hmac_vap->puc_asoc_req_ie_buff);
826         hmac_vap->puc_asoc_req_ie_buff = HI_NULL;
827     }
828 
829     if (oal_unlikely(asoc_frame_len_local < OAL_ASSOC_REQ_IE_OFFSET)) {
830         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
831             "{hmac_sta_wait_asoc::invalid ul_asoc_req_ie_len[%u].}", asoc_frame_len_local);
832         return HI_FAIL;
833     }
834     *asoc_frame_len = asoc_frame_len_local;
835 
836     return HI_SUCCESS;
837 }
838 
hmac_sta_fill_asoc_req_ie_buff(hmac_vap_stru * hmac_vap,const oal_netbuf_stru * asoc_req_frame,hi_u32 asoc_frame_len)839 static hi_u32 hmac_sta_fill_asoc_req_ie_buff(hmac_vap_stru *hmac_vap, const oal_netbuf_stru *asoc_req_frame,
840     hi_u32 asoc_frame_len)
841 {
842     /* Should we change the ie buff from local mem to netbuf ?  */
843     /* 此处申请的内存,只在上报给内核后释放 */
844     hmac_vap->us_asoc_req_ie_len = (hi_u16)((hmac_vap->reassoc_flag) ?
845         (asoc_frame_len - OAL_ASSOC_REQ_IE_OFFSET - OAL_MAC_ADDR_LEN) : (asoc_frame_len - OAL_ASSOC_REQ_IE_OFFSET));
846     hmac_vap->puc_asoc_req_ie_buff = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, hmac_vap->us_asoc_req_ie_len);
847     if (hmac_vap->puc_asoc_req_ie_buff == HI_NULL) {
848         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
849             "{hmac_sta_fill_asoc_req_ie_buff::alloc %u bytes failed}", hmac_vap->us_asoc_req_ie_len);
850         return HI_FAIL;
851     }
852 
853     if (hmac_vap->reassoc_flag) {
854         if (memcpy_s(hmac_vap->puc_asoc_req_ie_buff, hmac_vap->us_asoc_req_ie_len,
855             oal_netbuf_header(asoc_req_frame) + OAL_ASSOC_REQ_IE_OFFSET + OAL_MAC_ADDR_LEN,
856             hmac_vap->us_asoc_req_ie_len) != EOK) {
857             oal_mem_free(hmac_vap->puc_asoc_req_ie_buff);
858             hmac_vap->puc_asoc_req_ie_buff = HI_NULL;
859             oam_error_log0(0, OAM_SF_CFG, "hmac_sta_fill_asoc_req_ie_buff:: pst_asoc_req_frame memcpy_s fail.");
860             return HI_FAIL;
861         }
862     } else {
863         if (memcpy_s(hmac_vap->puc_asoc_req_ie_buff, hmac_vap->us_asoc_req_ie_len,
864             oal_netbuf_header(asoc_req_frame) + OAL_ASSOC_REQ_IE_OFFSET, hmac_vap->us_asoc_req_ie_len) != EOK) {
865             oal_mem_free(hmac_vap->puc_asoc_req_ie_buff);
866             hmac_vap->puc_asoc_req_ie_buff = HI_NULL;
867             oam_error_log0(0, OAM_SF_CFG, "hmac_sta_fill_asoc_req_ie_buff:: pst_asoc_req_frame memcpy_s fail.");
868             return HI_FAIL;
869         }
870     }
871 
872     return HI_SUCCESS;
873 }
874 
hmac_sta_fill_tx_ctl_stru(oal_netbuf_stru * asoc_req_frame,hi_u32 asoc_frame_len,const hmac_user_stru * hmac_user_ap)875 static hi_void hmac_sta_fill_tx_ctl_stru(oal_netbuf_stru *asoc_req_frame, hi_u32 asoc_frame_len,
876     const hmac_user_stru *hmac_user_ap)
877 {
878     hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(asoc_req_frame);
879 
880     tx_ctl->us_mpdu_len = (hi_u16)asoc_frame_len;
881     tx_ctl->us_tx_user_idx = hmac_user_ap->base_user->us_assoc_id;
882     tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
883     tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(asoc_req_frame);
884     tx_ctl->mac_head_type = 1;
885 }
886 /* ****************************************************************************
887  功能描述  : 在AUTH_COMP状态接收到SME发过来的ASOC_REQ请求,将STA状态设置为WAIT_ASOC,
888              抛事件给DMAC,发送Asoc_req_frame
889  修改历史      :
890   1.日    期   : 2013年6月27日
891     作    者   : HiSilicon
892     修改内容   : 新生成函数
893 **************************************************************************** */
hmac_sta_wait_asoc(hmac_vap_stru * hmac_vap,hi_u16 us_assoc_timeout)894 hi_u32 hmac_sta_wait_asoc(hmac_vap_stru *hmac_vap, hi_u16 us_assoc_timeout)
895 {
896     hi_u32 asoc_frame_len = 0;
897     oal_netbuf_stru *asoc_req_frame = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
898 
899     if (asoc_req_frame == HI_NULL) {
900         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_asoc::pst_asoc_req_frame null.}");
901         return HI_ERR_CODE_PTR_NULL;
902     }
903     /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
904     memset_s(oal_netbuf_cb(asoc_req_frame), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
905 
906     /* 将mac header清零 */
907     if (memset_s((hi_u8 *)oal_netbuf_header(asoc_req_frame), MAC_80211_FRAME_LEN, 0, MAC_80211_FRAME_LEN) != EOK) {
908         oal_netbuf_free(asoc_req_frame);
909         return HI_FAIL;
910     }
911 
912     /* 组帧 (Re)Assoc_req_Frame */
913     if (hmac_sta_encap_asoc_req_frame(hmac_vap, asoc_req_frame, &asoc_frame_len) != HI_SUCCESS) {
914         oal_netbuf_free(asoc_req_frame);
915         return HI_FAIL;
916     }
917 
918     /* 申请hmac_vap->puc_asoc_req_ie_buff 内存,只在上报给内核后释放 */
919     if (hmac_sta_fill_asoc_req_ie_buff(hmac_vap, asoc_req_frame, asoc_frame_len) != HI_SUCCESS) {
920         oal_netbuf_free(asoc_req_frame);
921         return HI_FAIL;
922     }
923 
924     hmac_user_stru *hmac_user_ap = (hmac_user_stru *)hmac_user_get_user_stru(hmac_vap->base_vap->assoc_vap_id);
925     if ((hmac_user_ap == HI_NULL) || (hmac_user_ap->base_user == HI_NULL)) {
926         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "{hmac_sta_wait_asoc::pst_hmac_user_ap null.}");
927         oal_netbuf_free(asoc_req_frame);
928         oal_mem_free(hmac_vap->puc_asoc_req_ie_buff);
929         hmac_vap->puc_asoc_req_ie_buff = HI_NULL;
930         return HI_ERR_CODE_PTR_NULL;
931     }
932     /* 填充tx_ctl 信息 */
933     hmac_sta_fill_tx_ctl_stru(asoc_req_frame, asoc_frame_len, hmac_user_ap);
934 
935     /* 抛事件让DMAC将该帧发送 */
936     hi_u32 ret = hmac_tx_mgmt_send_event(hmac_vap->base_vap, asoc_req_frame, (hi_u16)asoc_frame_len);
937     if (ret != HI_SUCCESS) {
938         oal_netbuf_free(asoc_req_frame);
939         oal_mem_free(hmac_vap->puc_asoc_req_ie_buff);
940         hmac_vap->puc_asoc_req_ie_buff = HI_NULL;
941 
942         oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
943             "{hmac_sta_wait_asoc::hmac_tx_mgmt_send_event failed[%d].}", ret);
944         return ret;
945     }
946 
947     /* 更改状态 */
948     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_WAIT_ASOC);
949 
950     /* 启动关联超时定时器, 为对端ap分配一个定时器,如果超时ap没回asoc rsp则启动超时处理 */
951     hmac_vap->mgmt_timetout_param.state = MAC_VAP_STATE_STA_WAIT_ASOC;
952     hmac_vap->mgmt_timetout_param.user_index = (hi_u8)hmac_user_ap->base_user->us_assoc_id;
953     hmac_vap->mgmt_timetout_param.vap_id = hmac_vap->base_vap->vap_id;
954 
955     frw_timer_create_timer(&(hmac_vap->mgmt_timer), hmac_mgmt_timeout_sta, us_assoc_timeout,
956         &(hmac_vap->mgmt_timetout_param), HI_FALSE);
957 
958     return HI_SUCCESS;
959 }
960 
961 /* ****************************************************************************
962  功能描述  : 当与STA关联的AP不是QoS的时候,STA默认采用VO策略发送数据
963  修改历史      :
964   1.日    期   : 2013年10月26日
965     作    者   : HiSilicon
966     修改内容   : 新生成函数
967 **************************************************************************** */
hmac_sta_up_update_edca_params_machw(const hmac_vap_stru * hmac_vap,mac_wmm_set_param_type_enum_uint8 type)968 hi_u32 hmac_sta_up_update_edca_params_machw(const hmac_vap_stru *hmac_vap, mac_wmm_set_param_type_enum_uint8 type)
969 {
970     frw_event_mem_stru *event_mem = HI_NULL;
971     frw_event_stru *event = HI_NULL;
972     dmac_ctx_sta_asoc_set_edca_reg_stru asoc_set_edca_reg_param = { 0 };
973 
974     /* 抛事件到dmac写寄存器 */
975     /* 申请事件内存 */
976     event_mem = frw_event_alloc(sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru));
977     if (event_mem == HI_NULL) {
978         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
979             "{hmac_sta_up_update_edca_params_machw::event_mem alloc null, size[%d].}",
980             sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru));
981         return HI_ERR_CODE_PTR_NULL;
982     }
983 
984     asoc_set_edca_reg_param.vap_id = hmac_vap->base_vap->vap_id;
985     asoc_set_edca_reg_param.set_param_type = type;
986 
987     /* 填写事件 */
988     event = (frw_event_stru *)event_mem->puc_data;
989     frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_STA_SET_EDCA_REG,
990         sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru), FRW_EVENT_PIPELINE_STAGE_1, hmac_vap->base_vap->vap_id);
991 
992 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
993     if (type != MAC_WMM_SET_PARAM_TYPE_DEFAULT) {
994         if (memcpy_s((hi_u8 *)&asoc_set_edca_reg_param.ast_wlan_mib_qap_edac,
995             (sizeof(wlan_mib_dot11_qapedca_entry_stru) * WLAN_WME_AC_BUTT),
996             (hi_u8 *)&hmac_vap->base_vap->mib_info->wlan_mib_qap_edac,
997             (sizeof(wlan_mib_dot11_qapedca_entry_stru) * WLAN_WME_AC_BUTT)) != EOK) {
998             frw_event_free(event_mem);
999             oam_error_log0(0, OAM_SF_CFG, "hmac_sta_up_update_edca_params_machw:: st_wlan_mib_qap_edac memcpy_s fail.");
1000             return HI_FAIL;
1001         }
1002     }
1003 #endif
1004 
1005     /* 拷贝参数 */
1006     if (memcpy_s(frw_get_event_payload(event_mem), sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru),
1007         (hi_u8 *)&asoc_set_edca_reg_param, sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru)) != EOK) {
1008         frw_event_free(event_mem);
1009         oam_error_log0(0, 0, "hmac_sta_up_update_edca_params_machw:: st_asoc_set_edca_reg_param memcpy_s fail.");
1010         return HI_FAIL;
1011     }
1012 
1013     /* 分发事件 */
1014     hcc_hmac_tx_control_event(event_mem, sizeof(dmac_ctx_sta_asoc_set_edca_reg_stru));
1015     frw_event_free(event_mem);
1016 
1017     return HI_SUCCESS;
1018 }
1019 
1020 /* ****************************************************************************
1021  功能描述  : STA更新每一个AC的参数
1022  输入参数  : pst_hmac_sta:处于sta模式的vap
1023              puc_payload :帧体
1024  修改历史      :
1025   1.日    期   : 2013年10月24日
1026     作    者   : HiSilicon
1027     修改内容   : 新生成函数
1028 **************************************************************************** */
hmac_sta_up_update_edca_params_mib(const hmac_vap_stru * hmac_vap,const hi_u8 * puc_payload)1029 static hi_void hmac_sta_up_update_edca_params_mib(const hmac_vap_stru *hmac_vap, const hi_u8 *puc_payload)
1030 {
1031     hi_u8 aifsn;
1032     hi_u8 aci;
1033     hi_u8 ecwmin;
1034     hi_u8 ecwmax;
1035     hi_u16 us_txop_limit;
1036     hi_u8 acm;
1037     /*        AC Parameters Record Format         */
1038     /* ------------------------------------------ */
1039     /* |     1     |       1       |      2     | */
1040     /* ------------------------------------------ */
1041     /* | ACI/AIFSN | ECWmin/ECWmax | TXOP Limit | */
1042     /* ------------------------------------------ */
1043     /* ************ ACI/AIFSN Field ************** */
1044     /*     ---------------------------------- */
1045     /* bit |   4   |  1  |  2  |    1     |   */
1046     /*     ---------------------------------- */
1047     /*     | AIFSN | ACM | ACI | Reserved |   */
1048     /*     ---------------------------------- */
1049     aifsn = puc_payload[0] & MAC_WMM_QOS_PARAM_AIFSN_MASK;
1050     acm = (puc_payload[0] & BIT4) ? HI_TRUE : HI_FALSE;
1051     aci = (puc_payload[0] >> MAC_WMM_QOS_PARAM_ACI_BIT_OFFSET) & MAC_WMM_QOS_PARAM_ACI_MASK;
1052 
1053     /* ECWmin/ECWmax Field */
1054     /*     ------------------- */
1055     /* bit |   4    |   4    | */
1056     /*     ------------------- */
1057     /*     | ECWmin | ECWmax | */
1058     /*     ------------------- */
1059     ecwmin = (puc_payload[1] & MAC_WMM_QOS_PARAM_ECWMIN_MASK);
1060     ecwmax = ((puc_payload[1] & MAC_WMM_QOS_PARAM_ECWMAX_MASK) >> MAC_WMM_QOS_PARAM_ECWMAX_BIT_OFFSET);
1061 
1062     /* 在mib库中和寄存器里保存的TXOP值都是以us为单位的,但是传输的时候是以32us为
1063        单位进行传输的,因此在解析的时候需要将解析到的值乘以32
1064      */
1065     us_txop_limit = puc_payload[2] | /* 2 元素索引 */
1066         ((puc_payload[3] & MAC_WMM_QOS_PARAM_TXOPLIMIT_MASK) << MAC_WMM_QOS_PARAM_BIT_NUMS_OF_ONE_BYTE); /* 3元素索引 */
1067     us_txop_limit = (hi_u16)(us_txop_limit << MAC_WMM_QOS_PARAM_TXOPLIMIT_SAVE_TO_TRANS_TIMES);
1068 
1069     /* 更新相应的MIB库信息 */
1070     if (aci < WLAN_WME_AC_BUTT) {
1071         hmac_vap->base_vap->mib_info->wlan_mib_qap_edac[aci].dot11_qapedca_table_c_wmin = ecwmin;
1072         hmac_vap->base_vap->mib_info->wlan_mib_qap_edac[aci].dot11_qapedca_table_c_wmax = ecwmax;
1073         hmac_vap->base_vap->mib_info->wlan_mib_qap_edac[aci].dot11_qapedca_table_aifsn = aifsn;
1074         hmac_vap->base_vap->mib_info->wlan_mib_qap_edac[aci].dot11_qapedca_table_txop_limit = us_txop_limit;
1075         hmac_vap->base_vap->mib_info->wlan_mib_qap_edac[aci].dot11_qapedca_table_mandatory = acm;
1076     }
1077 }
1078 
1079 /* ****************************************************************************
1080  功能描述  : STA接收到beacon帧或者关联响应帧更新自身的EDCA参数,涉及到mib值
1081              和寄存器
1082  输入参数  : puc_payload :帧体
1083              ul_msg_len  :帧长度
1084              us_info_elem_offset :当前指向的帧体位置
1085              pst_hmac_sta        :指向hmac_vap的指针,vap是sta模式
1086              uc_frame_sub_type   :帧的次类型
1087  修改历史      :
1088   1.日    期   : 2013年10月24日
1089     作    者   : HiSilicon
1090     修改内容   : 新生成函数
1091 **************************************************************************** */
hmac_sta_up_update_edca_params(const hmac_edca_params_info_stru * edca_params_info,const hmac_vap_stru * hmac_vap,hi_u8 frame_sub_type,const hmac_user_stru * hmac_user)1092 hi_void hmac_sta_up_update_edca_params(const hmac_edca_params_info_stru *edca_params_info,
1093     const hmac_vap_stru *hmac_vap, hi_u8 frame_sub_type, const hmac_user_stru *hmac_user)
1094 {
1095     hi_u8 param_set_cnt, edca_param_set, apsd, ac_num_loop;
1096     hi_u16 us_msg_offset = edca_params_info->us_info_elem_offset; /* 检查帧中是否有WMM信息元素 */
1097     mac_device_stru *mac_dev = (mac_device_stru *)mac_res_get_dev();
1098 
1099     /* *********************** WMM Parameter Element ************************** */
1100     /* ------------------------------------------------------------------------------ */
1101     /* | EID | LEN | OUI |OUI Type |OUI Subtype |Version |QoS Info |Resd |AC Params | */
1102     /* ------------------------------------------------------------------------------ */
1103     /* |  1  |  1  |  3  |    1    |     1      |    1   |    1    |  1  |    16    | */
1104     /* ------------------------------------------------------------------------------ */
1105     /* ****************** QoS Info field when sent from WMM AP **************** */
1106     /*        --------------------------------------------                    */
1107     /*          | Parameter Set Count | Reserved | U-APSD |                   */
1108     /*          --------------------------------------------                  */
1109     /*   bit    |        0~3          |   4~6    |   7    |                   */
1110     /*          --------------------------------------------                  */
1111     /* ************************************************************************ */
1112     while (us_msg_offset < edca_params_info->us_msg_len) {
1113         /* 判断当前的ie是否是wmm ie,如果不是,继续检查下一个ie,如果是,更新WMM参数 */
1114         if (HI_TRUE == mac_is_wmm_ie(&(edca_params_info->puc_payload[us_msg_offset]))) {
1115             /* 解析wmm ie是否携带EDCA参数 */
1116             edca_param_set = edca_params_info->puc_payload[us_msg_offset + MAC_OUISUBTYPE_WMM_PARAM_OFFSET];
1117 
1118             us_msg_offset += HMAC_WMM_QOS_PARAMS_HDR_LEN;
1119             param_set_cnt = edca_params_info->puc_payload[us_msg_offset] & 0x0F;
1120 
1121             /* 如果收到的是beacon帧,并且param_set_count没有改变,说明AP的WMM参数没有变
1122                则STA也不用做任何改变,直接返回即可.
1123              */
1124             if ((frame_sub_type == WLAN_FC0_SUBTYPE_BEACON) &&
1125                 (param_set_cnt == hmac_vap->base_vap->wmm_params_update_count)) {
1126                 return;
1127             }
1128 
1129             mac_dev->wmm = HI_TRUE;
1130 
1131             if (frame_sub_type == WLAN_FC0_SUBTYPE_BEACON) {
1132                 /* 保存QoS Info */
1133                 mac_vap_set_wmm_params_update_count(hmac_vap->base_vap, param_set_cnt);
1134             }
1135 
1136             apsd = (edca_params_info->puc_payload[us_msg_offset] & BIT7) ? HI_TRUE : HI_FALSE;
1137             mac_user_set_apsd(hmac_user->base_user, apsd);
1138 
1139             us_msg_offset += HMAC_WMM_QOSINFO_AND_RESV_LEN;
1140 
1141             /* wmm ie中不携带edca参数 直接返回 */
1142             if (edca_param_set != MAC_OUISUBTYPE_WMM_PARAM) {
1143                 return;
1144             }
1145 
1146             /* 针对每一个AC,更新EDCA参数 */
1147             for (ac_num_loop = 0; ac_num_loop < WLAN_WME_AC_BUTT; ac_num_loop++) {
1148                 hmac_sta_up_update_edca_params_mib(hmac_vap, &(edca_params_info->puc_payload[us_msg_offset]));
1149                 us_msg_offset += HMAC_WMM_AC_PARAMS_RECORD_LEN;
1150             }
1151             /* 更新EDCA相关的MAC寄存器 */
1152             hmac_sta_up_update_edca_params_machw(hmac_vap, MAC_WMM_SET_PARAM_TYPE_UPDATE_EDCA);
1153             return;
1154         }
1155 
1156         us_msg_offset += (edca_params_info->puc_payload[us_msg_offset + 1] + MAC_IE_HDR_LEN);
1157     }
1158 
1159     if (frame_sub_type == WLAN_FC0_SUBTYPE_ASSOC_RSP) {
1160         /* 当与STA关联的AP不是QoS的,STA会去使能EDCA寄存器,并默认利用VO级别发送数据 */
1161         hi_u32 ret = hmac_sta_up_update_edca_params_machw(hmac_vap, MAC_WMM_SET_PARAM_TYPE_DEFAULT);
1162         if (ret != HI_SUCCESS) {
1163             oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1164                 "{hmac_sta_up_update_edca_params::hmac_sta_up_update_edca_params_machw failed[%d].}", ret);
1165         }
1166     }
1167 }
1168 
1169 /* ****************************************************************************
1170  功能描述  : 在beacon HT IE状态变化下更新mac user info到device
1171  修改历史      :
1172   1.日    期   : 2015年03月24日
1173     作    者   : HiSilicon
1174     修改内容   : 新生成函数
1175 **************************************************************************** */
hmac_sta_update_mac_user_info(const hmac_user_stru * hmac_user_ap,hi_u8 user_idx)1176 hi_void hmac_sta_update_mac_user_info(const hmac_user_stru *hmac_user_ap, hi_u8 user_idx)
1177 {
1178     mac_vap_stru *mac_vap = HI_NULL;
1179     mac_user_stru *mac_user_ap = HI_NULL;
1180     hi_u32 ret;
1181 
1182     if (hmac_user_ap == HI_NULL) {
1183         oam_error_log0(0, OAM_SF_RX, "{hmac_sta_update_mac_user_info::param null.}");
1184         return;
1185     }
1186 
1187     mac_vap = mac_vap_get_vap_stru(hmac_user_ap->base_user->vap_id);
1188     if (oal_unlikely(mac_vap == HI_NULL)) {
1189         oam_error_log1(0, OAM_SF_RX, "{hmac_sta_update_mac_user_info::get mac_vap [vap_id:%d] null.}",
1190             hmac_user_ap->base_user->vap_id);
1191         return;
1192     }
1193 
1194     mac_user_ap = hmac_user_ap->base_user;
1195     oam_warning_log3(mac_vap->vap_id, OAM_SF_RX,
1196         "{hmac_sta_update_mac_user_info::user_idx:%d,en_avail_bandwidth:%d,en_cur_bandwidth:%d}", user_idx,
1197         mac_user_ap->avail_bandwidth, mac_user_ap->cur_bandwidth);
1198 
1199     ret = hmac_config_user_info_syn(mac_vap, mac_user_ap);
1200     if (ret != HI_SUCCESS) {
1201         oam_error_log1(mac_vap->vap_id, OAM_SF_RX,
1202             "{hmac_sta_update_mac_user_info::hmac_config_user_info_syn failed[%d].}", ret);
1203     }
1204 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1205     ret = hmac_config_user_rate_info_syn(mac_vap, mac_user_ap);
1206     if (ret != HI_SUCCESS) {
1207         oam_error_log1(mac_vap->vap_id, OAM_SF_RX, "{hmac_sta_wait_asoc_rx::hmac_syn_rate_info failed[%d].}", ret);
1208     }
1209 #endif
1210     return;
1211 }
1212 
1213 /* ****************************************************************************
1214  功能描述  : 在已保存的probe rsp中寻找指定IE,一般用于在asoc rsp中寻找IE失败时
1215              再在probe rsp做进一步查找
1216  输入参数  : pst_mac_vap : mac vap结构体
1217              uc_eid: 要查找的EID
1218  输出参数  : puc_payload: probe rsp帧体,以帧内第一个IE开头
1219              us_index:目标IE在payload中的相对位置
1220  修改历史      :
1221   1.日    期   : 2016年5月24日
1222     作    者   : HiSilicon
1223     修改内容   : 新生成函数
1224 **************************************************************************** */
hmac_sta_find_ie_in_probe_rsp(const mac_vap_stru * mac_vap,hi_u8 eid,hi_u16 * pus_index)1225 hi_u8 *hmac_sta_find_ie_in_probe_rsp(const mac_vap_stru *mac_vap, hi_u8 eid, hi_u16 *pus_index)
1226 {
1227     hmac_scanned_bss_info *scanned_bss_info = HI_NULL;
1228     hmac_bss_mgmt_stru *bss_mgmt = HI_NULL;
1229     hmac_device_stru *hmac_dev = HI_NULL;
1230     mac_bss_dscr_stru *bss_dscr = HI_NULL;
1231     hi_u8 *puc_ie = HI_NULL;
1232     hi_u8 *puc_payload = HI_NULL;
1233     hi_u8 us_offset;
1234 
1235     if (mac_vap == HI_NULL) {
1236         oam_warning_log0(0, OAM_SF_SCAN, "{find ie fail, pst_mac_vap is null.}");
1237         return HI_NULL;
1238     }
1239 
1240     /* 获取hmac device 结构 */
1241     hmac_dev = hmac_get_device_stru();
1242     /* 获取管理扫描的bss结果的结构体 */
1243     bss_mgmt = &(hmac_dev->scan_mgmt.scan_record_mgmt.bss_mgmt);
1244 
1245     oal_spin_lock(&(bss_mgmt->st_lock));
1246 
1247     scanned_bss_info = hmac_scan_find_scanned_bss_by_bssid(bss_mgmt, mac_vap->auc_bssid);
1248     if (scanned_bss_info == HI_NULL) {
1249         oam_warning_log3(mac_vap->vap_id, OAM_SF_CFG, "{find the bss failed by bssid:XX:XX:XX:%02X:%02X:%02X}",
1250             mac_vap->auc_bssid[3], mac_vap->auc_bssid[4], mac_vap->auc_bssid[5]); /* 3 4 5 元素索引 */
1251 
1252         /* 解锁 */
1253         oal_spin_unlock(&(bss_mgmt->st_lock));
1254         return HI_NULL;
1255     }
1256 
1257     bss_dscr = &(scanned_bss_info->bss_dscr_info);
1258     /* 解锁 */
1259     oal_spin_unlock(&(bss_mgmt->st_lock));
1260 
1261     /* 以IE开头的payload,返回供调用者使用 */
1262     us_offset = MAC_80211_FRAME_LEN + MAC_TIME_STAMP_LEN + MAC_BEACON_INTERVAL_LEN + MAC_CAP_INFO_LEN;
1263 
1264     /* 可变数组用法,lin_t e416告警屏蔽 */
1265     puc_payload = (hi_u8 *)(bss_dscr->auc_mgmt_buff + us_offset);
1266     if (bss_dscr->mgmt_len < us_offset) {
1267         return HI_NULL;
1268     }
1269 
1270     puc_ie = mac_find_ie(eid, puc_payload, (bss_dscr->mgmt_len - us_offset));
1271     if (puc_ie == HI_NULL) {
1272         return HI_NULL;
1273     }
1274 
1275     /* IE长度初步校验 */
1276     if (*(puc_ie + 1) == 0) {
1277         oam_warning_log1(0, OAM_SF_ANY, "{IE[%d] len in probe rsp is 0, find ie fail.}", eid);
1278         return HI_NULL;
1279     }
1280 
1281     *pus_index = (hi_u16)(puc_ie - puc_payload);
1282 
1283     oam_warning_log1(0, OAM_SF_ANY, "{found ie[%d] in probe rsp.}", eid);
1284 
1285     return puc_payload;
1286 }
1287 
1288 /* ****************************************************************************
1289  功能描述  : 在STA为WAIT_ASOC状态时,解析ht cap IE,分别在asoc rsp和probe rsp
1290              中查找
1291  修改历史      :
1292   1.日    期   : 2016年5月24日
1293     作    者   : HiSilicon
1294     修改内容   : 新生成函数
1295 **************************************************************************** */
hmac_sta_check_ht_cap_ie(const mac_vap_stru * mac_sta,hi_u8 * puc_payload,mac_user_stru * mac_user_ap,hi_u16 * pus_amsdu_maxsize,hi_u16 us_payload_len)1296 hi_void hmac_sta_check_ht_cap_ie(const mac_vap_stru *mac_sta, hi_u8 *puc_payload, mac_user_stru *mac_user_ap,
1297     hi_u16 *pus_amsdu_maxsize, hi_u16 us_payload_len)
1298 {
1299     hi_u8 *puc_ie = HI_NULL;
1300     hi_u8 *puc_payload_for_ht_cap_chk = HI_NULL;
1301     hi_u16 us_ht_cap_index;
1302     hi_u16 us_ht_cap_info = 0;
1303 
1304     if ((mac_sta == HI_NULL) || (puc_payload == HI_NULL) || (mac_user_ap == HI_NULL)) {
1305         return;
1306     }
1307 
1308     puc_ie = mac_find_ie(MAC_EID_HT_CAP, puc_payload, us_payload_len);
1309     if (puc_ie == HI_NULL || puc_ie[1] < MAC_HT_CAP_LEN) {
1310         puc_payload_for_ht_cap_chk = hmac_sta_find_ie_in_probe_rsp(mac_sta, MAC_EID_HT_CAP, &us_ht_cap_index);
1311         if (puc_payload_for_ht_cap_chk == HI_NULL) {
1312             oam_warning_log0(0, OAM_SF_ANY, "{hmac_sta_check_ht_cap_ie::puc_payload_for_ht_cap_chk is null.}");
1313             return;
1314         }
1315 
1316         if (puc_payload_for_ht_cap_chk[us_ht_cap_index + 1] < MAC_HT_CAP_LEN) {
1317             oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_check_ht_cap_ie::invalid ht cap len[%d].}",
1318                 puc_payload_for_ht_cap_chk[us_ht_cap_index + 1]);
1319             return;
1320         }
1321     } else {
1322         if (puc_ie < puc_payload) {
1323             return;
1324         }
1325         us_ht_cap_index = (hi_u16)(puc_ie - puc_payload);
1326         puc_payload_for_ht_cap_chk = puc_payload;
1327     }
1328 
1329     mac_user_set_ht_capable(mac_user_ap, HI_TRUE);
1330     /* 根据协议值设置特性,必须在hmac_amsdu_init_user后面调用 */
1331     mac_ie_proc_ht_sta(mac_sta, puc_payload_for_ht_cap_chk, &us_ht_cap_index, mac_user_ap, &us_ht_cap_info,
1332         pus_amsdu_maxsize);
1333 
1334     if ((mac_user_ap->ht_hdl.rx_mcs_bitmask[3] == 0) && (mac_user_ap->ht_hdl.rx_mcs_bitmask[2] == 0) &&
1335         (mac_user_ap->ht_hdl.rx_mcs_bitmask[1] == 0) && (mac_user_ap->ht_hdl.rx_mcs_bitmask[0]) == 0) {
1336         oam_warning_log0(0, OAM_SF_ANY,
1337             "{hmac_sta_check_ht_cap_ie::AP support ht capability but support none space_stream.}");
1338         /* 对端ht能力置为不支持 */
1339         mac_user_set_ht_capable(mac_user_ap, HI_FALSE);
1340     }
1341 }
1342 
1343 /* ****************************************************************************
1344  功能描述  : 在STA为WAIT_ASOC状态时,解析ext cap IE,分别在asoc rsp和probe rsp
1345              中查找
1346  修改历史      :
1347   1.日    期   : 2016年5月24日
1348     作    者   : HiSilicon
1349     修改内容   : 新生成函数
1350 **************************************************************************** */
hmac_sta_check_ext_cap_ie(const mac_vap_stru * mac_sta,hi_u8 * puc_payload,hi_u16 us_rx_len)1351 hi_void hmac_sta_check_ext_cap_ie(const mac_vap_stru *mac_sta, hi_u8 *puc_payload, hi_u16 us_rx_len)
1352 {
1353     hi_u8 *puc_ie = HI_NULL;
1354     hi_u8 *puc_payload_proc = HI_NULL;
1355     hi_u16 us_index;
1356 
1357     puc_ie = mac_find_ie(MAC_EID_EXT_CAPS, puc_payload, us_rx_len);
1358     if (puc_ie == HI_NULL || puc_ie[1] < MAC_XCAPS_LEN) {
1359         puc_payload_proc = hmac_sta_find_ie_in_probe_rsp(mac_sta, MAC_EID_EXT_CAPS, &us_index);
1360         if (puc_payload_proc == HI_NULL) {
1361             return;
1362         }
1363 
1364         if (puc_payload_proc[us_index + 1] < MAC_XCAPS_LEN) {
1365             oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_check_ext_cap_ie::invalid ext cap len[%d].}",
1366                 puc_payload_proc[us_index + 1]);
1367             return;
1368         }
1369     } else {
1370         if (puc_ie < puc_payload) {
1371             return;
1372         }
1373 
1374         us_index = (hi_u16)(puc_ie - puc_payload);
1375     }
1376 }
1377 
1378 /* ****************************************************************************
1379  功能描述  : 在STA为WAIT_ASOC状态时,解析OBSS IE,分别在asoc rsp和probe rsp
1380              中查找
1381  修改历史      :
1382   1.日    期   : 2016年5月24日
1383     作    者   : HiSilicon
1384     修改内容   : 新生成函数
1385 **************************************************************************** */
hmac_sta_check_obss_scan_ie(const mac_vap_stru * mac_sta,hi_u8 * puc_payload,hi_u16 us_rx_len)1386 hi_void hmac_sta_check_obss_scan_ie(const mac_vap_stru *mac_sta, hi_u8 *puc_payload, hi_u16 us_rx_len)
1387 {
1388     hi_u8 *puc_ie = HI_NULL;
1389     hi_u8 *puc_payload_proc = HI_NULL;
1390     hi_u16 us_index;
1391     hi_u32 ret;
1392 
1393     puc_ie = mac_find_ie(MAC_EID_OBSS_SCAN, puc_payload, us_rx_len);
1394     if (puc_ie == HI_NULL || puc_ie[1] < MAC_OBSS_SCAN_IE_LEN) {
1395         puc_payload_proc = hmac_sta_find_ie_in_probe_rsp(mac_sta, MAC_EID_OBSS_SCAN, &us_index);
1396         if (puc_payload_proc == HI_NULL) {
1397             return;
1398         }
1399 
1400         if (puc_payload_proc[us_index + 1] < MAC_OBSS_SCAN_IE_LEN) {
1401             oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_check_obss_scan_ie::invalid obss scan len[%d].}",
1402                 puc_payload_proc[us_index + 1]);
1403             return;
1404         }
1405     } else {
1406         puc_payload_proc = puc_payload;
1407         if (puc_ie < puc_payload) {
1408             return;
1409         }
1410 
1411         us_index = (hi_u16)(puc_ie - puc_payload);
1412     }
1413 
1414     /* 处理 obss scan IE */
1415     ret = hmac_ie_proc_obss_scan_ie(mac_sta, &puc_payload_proc[us_index]);
1416     if (ret != HI_SUCCESS) {
1417         oam_warning_log0(0, OAM_SF_ANY, "hmac_ie_proc_obss_scan_ie return NON SUCCESS. ");
1418     }
1419 }
1420 
1421 /* ****************************************************************************
1422  功能描述  : 在STA为WAIT_ASOC状态时,解析ht opern IE,分别在asoc rsp和probe rsp
1423              中查找
1424  修改历史      :
1425   1.日    期   : 2016年5月24日
1426     作    者   : HiSilicon
1427     修改内容   : 新生成函数
1428 **************************************************************************** */
hmac_sta_check_ht_opern_ie(mac_vap_stru * mac_sta,mac_user_stru * mac_user_ap,hi_u8 * puc_payload,hi_u16 us_rx_len)1429 hi_u32 hmac_sta_check_ht_opern_ie(mac_vap_stru *mac_sta, mac_user_stru *mac_user_ap, hi_u8 *puc_payload,
1430     hi_u16 us_rx_len)
1431 {
1432     hi_u8 *puc_ie = HI_NULL;
1433     hi_u8 *puc_payload_proc = HI_NULL;
1434     hi_u16 us_index;
1435     hi_u32 change = MAC_NO_CHANGE;
1436 
1437     puc_ie = mac_find_ie(MAC_EID_HT_OPERATION, puc_payload, us_rx_len);
1438     if (puc_ie == HI_NULL || puc_ie[1] < MAC_HT_OPERN_LEN) {
1439         puc_payload_proc = hmac_sta_find_ie_in_probe_rsp(mac_sta, MAC_EID_HT_OPERATION, &us_index);
1440         if (puc_payload_proc == HI_NULL) {
1441             return change;
1442         }
1443 
1444         if (puc_payload_proc[us_index + 1] < MAC_HT_OPERN_LEN) {
1445             oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_check_ht_opern_ie::invalid ht cap len[%d].}",
1446                 puc_payload_proc[us_index + 1]);
1447             return change;
1448         }
1449     } else {
1450         puc_payload_proc = puc_payload;
1451         if (puc_ie < puc_payload) {
1452             return change;
1453         }
1454 
1455         us_index = (hi_u16)(puc_ie - puc_payload);
1456     }
1457     change |= mac_proc_ht_opern_ie(mac_sta, &puc_payload_proc[us_index], mac_user_ap);
1458 
1459     return change;
1460 }
1461 
1462 /* ****************************************************************************
1463  功能描述  : 在STA为WAIT_ASOC状态时,解析asoc rsp 或者reasoc rsp frame,更新相关参数
1464  修改历史      :
1465   1.日    期   : 2013年7月10日
1466     作    者   : HiSilicon
1467     修改内容   : 新生成函数
1468 **************************************************************************** */
hmac_ie_check_ht_sta(mac_vap_stru * mac_sta,const hmac_check_ht_sta_info_stru * check_ht_sta_info,mac_user_stru * mac_user_ap,hi_u16 * pus_amsdu_maxsize)1469 hi_u32 hmac_ie_check_ht_sta(mac_vap_stru *mac_sta, const hmac_check_ht_sta_info_stru *check_ht_sta_info,
1470     mac_user_stru *mac_user_ap, hi_u16 *pus_amsdu_maxsize)
1471 {
1472     hi_u32 change = MAC_NO_CHANGE;
1473     hi_u8 *puc_ie_payload_start = HI_NULL;
1474     hi_u16 us_ie_payload_len;
1475 
1476     if ((mac_sta == HI_NULL) || (check_ht_sta_info->puc_payload == HI_NULL) || (mac_user_ap == HI_NULL)) {
1477         return change;
1478     }
1479 
1480     /* 初始化HT cap为FALSE,入网时会把本地能力跟随AP能力 */
1481     mac_user_set_ht_capable(mac_user_ap, HI_FALSE);
1482 
1483     /* 至少支持11n才进行后续的处理 */
1484     if (mac_mib_get_high_throughput_option_implemented(mac_sta) == HI_FALSE) {
1485         return change;
1486     }
1487 
1488     puc_ie_payload_start = check_ht_sta_info->puc_payload + check_ht_sta_info->us_offset;
1489     if (check_ht_sta_info->us_rx_len <= check_ht_sta_info->us_offset) {
1490         oam_warning_log2(0, OAM_SF_ANY, "{hmac_ie_check_ht_sta::rx_len[%d] less offset[%d].}",
1491             check_ht_sta_info->us_rx_len, check_ht_sta_info->us_offset);
1492         return change;
1493     }
1494     us_ie_payload_len = check_ht_sta_info->us_rx_len - check_ht_sta_info->us_offset;
1495 
1496     hmac_sta_check_ht_cap_ie(mac_sta, puc_ie_payload_start, mac_user_ap, pus_amsdu_maxsize, us_ie_payload_len);
1497 
1498     hmac_sta_check_ext_cap_ie(mac_sta, puc_ie_payload_start, us_ie_payload_len);
1499 
1500     change = hmac_sta_check_ht_opern_ie(mac_sta, mac_user_ap, puc_ie_payload_start, us_ie_payload_len);
1501 
1502     return change;
1503 }
1504 
1505 /* ****************************************************************************
1506  功能描述  : 处理Overlapping BSS Scan Parameters IE,并更新STA相应MIB项
1507  输入参数  : pst_mac_vap: MAC VAP结构体指针
1508              puc_payload: 指向Overlapping BSS Scan Parameters IE的指针
1509  调用函数  : HI_SUCCESS或其它错误码
1510  修改历史      :
1511   1.日    期   : 2014年2月28日
1512     作    者   : HiSilicon
1513     修改内容   : 新生成函数
1514 **************************************************************************** */
hmac_ie_proc_obss_scan_ie(const mac_vap_stru * mac_vap,const hi_u8 * puc_payload)1515 hi_u32 hmac_ie_proc_obss_scan_ie(const mac_vap_stru *mac_vap, const hi_u8 *puc_payload)
1516 {
1517     hi_u16 us_trigger_scan_interval;
1518 
1519 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1520     wlan_mib_dot11_operation_entry_stru old_mib;
1521 #endif
1522     if (oal_unlikely((mac_vap == HI_NULL) || (puc_payload == HI_NULL))) {
1523         oam_error_log0(0, OAM_SF_SCAN, "{hmac_ie_proc_obss_scan_ie::param null.}");
1524         return HI_ERR_CODE_PTR_NULL;
1525     }
1526 
1527     /* *******************Overlapping BSS Scan Parameters element******************
1528      |ElementID |Length |OBSS    |OBSS   |BSS Channel   |OBSS Scan  |OBSS Scan   |
1529      |          |       |Scan    |Scan   |Width Trigger |Passive    |Active Total|
1530      |          |       |Passive |Active |Scan Interval |Total Per  |Per         |
1531      |          |       |Dwell   |Dwell  |              |Channel    |Channel     |
1532      ----------------------------------------------------------------------------
1533      |1         |1      |2       |2      |2             |2          |2           |
1534      ----------------------------------------------------------------------------
1535      |BSS Width   |OBSS Scan|
1536      |Channel     |Activity |
1537      |Transition  |Threshold|
1538      |Delay Factor|         |
1539      ------------------------
1540      |2           |2        |
1541     ************************************************************************** */
1542     if (puc_payload[1] < MAC_OBSS_SCAN_IE_LEN) {
1543         oam_warning_log1(0, OAM_SF_SCAN, "{mac_ie_proc_obss_scan_ie::invalid obss scan ie len[%d].}", puc_payload[1]);
1544         return HI_FAIL;
1545     }
1546 
1547     us_trigger_scan_interval = hi_makeu16(puc_payload[6], puc_payload[7]); /* 6 7 元素索引 */
1548     if (us_trigger_scan_interval == 0) {
1549         return HI_ERR_CODE_INVALID_CONFIG;
1550     }
1551 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1552     if (memset_s(&old_mib, sizeof(wlan_mib_dot11_operation_entry_stru), 0,
1553         sizeof(wlan_mib_dot11_operation_entry_stru)) != EOK) {
1554         return HI_FAIL;
1555     }
1556     if (memcpy_s(&old_mib, sizeof(old_mib), &mac_vap->mib_info->wlan_mib_operation, sizeof(old_mib)) != EOK) {
1557         oam_error_log0(0, OAM_SF_CFG, "hmac_ie_proc_obss_scan_ie:: hmac_ie_proc_obss_scan_ie memcpy_s fail.");
1558         return HI_FAIL;
1559     }
1560 #endif
1561     mac_mib_set_obssscan_passive_dwell(mac_vap, hi_makeu16(puc_payload[2], puc_payload[3])); /* 数组2,3,8 */
1562     mac_mib_set_obssscan_active_dwell(mac_vap, hi_makeu16(puc_payload[4], puc_payload[5]));  /* 数组4,5,8 */
1563     /* obss扫描周期最小300秒,最大600S, 初始化默认为300秒 */
1564     mac_mib_set_bsswidth_trigger_scan_interval(mac_vap,
1565         oal_min(oal_max(us_trigger_scan_interval, 300), 600)); /* min:max 300:600 */
1566     mac_mib_set_obssscan_passive_total_per_channel(mac_vap, hi_makeu16(puc_payload[8], puc_payload[9])); /* 8 9索引 */
1567     mac_mib_set_obssscan_active_total_per_channel(mac_vap,
1568         hi_makeu16(puc_payload[10], puc_payload[11])); /* 10 11索引 */
1569     mac_mib_set_bsswidth_channel_transition_delay_factor(mac_vap,
1570         hi_makeu16(puc_payload[12], puc_payload[13])); /* 12 13元素索引 */
1571     mac_mib_set_obssscan_activity_threshold(mac_vap, hi_makeu16(puc_payload[14], puc_payload[15])); /* 14 15索引 */
1572 
1573     if (0 != memcmp(&old_mib, &mac_vap->mib_info->wlan_mib_operation, sizeof(old_mib))) {
1574         oam_info_log0(mac_vap->vap_id, OAM_SF_2040, "hmac_ie_proc_obss_scan_ie::sync obss mib to dmac");
1575         hmac_config_set_obss_scan_param(mac_vap);
1576     }
1577 
1578     return HI_SUCCESS;
1579 }
1580 
1581 /* ****************************************************************************
1582  功能描述  : 解析帧中legacy 速率集,更新到user的结构体速率变量成员中
1583  修改历史      :
1584   1.日    期   : 2013年11月27日
1585     作    者   : HiSilicon
1586     修改内容   : 新生成函数
1587 **************************************************************************** */
hmac_ie_proc_assoc_user_legacy_rate(hi_u8 * puc_payload,hi_u16 us_offset,hi_u16 us_rx_len,hmac_user_stru * hmac_user)1588 static hi_u32 hmac_ie_proc_assoc_user_legacy_rate(hi_u8 *puc_payload, hi_u16 us_offset, hi_u16 us_rx_len,
1589     hmac_user_stru *hmac_user)
1590 {
1591     hi_u8 *puc_ie = HI_NULL;
1592     hi_u8 num_rates = 0;
1593     hi_u8 num_ex_rates = 0;
1594 
1595     if (us_rx_len > us_offset) {
1596         puc_ie = mac_find_ie(MAC_EID_RATES, puc_payload + us_offset, us_rx_len - us_offset);
1597         if (puc_ie != HI_NULL) {
1598             num_rates = puc_ie[1];
1599 
1600             if (num_rates > WLAN_MAX_SUPP_RATES || num_rates < MAC_MIN_XRATE_LEN) {
1601                 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ie_proc_assoc_user_legacy_rate:: invalid rates:%d}", num_rates);
1602                 return HI_FAIL;
1603             }
1604             if (memcpy_s(hmac_user->op_rates.auc_rs_rates, num_rates, puc_ie + MAC_IE_HDR_LEN, num_rates) != EOK) {
1605                 oam_error_log0(0, OAM_SF_CFG, "hmac_ie_proc_assoc_user_legacy_rate:: puc_ie memcpy_s fail.");
1606                 return HI_FAIL;
1607             }
1608         }
1609         puc_ie = mac_find_ie(MAC_EID_XRATES, puc_payload + us_offset, us_rx_len - us_offset);
1610         if (puc_ie != HI_NULL) {
1611             num_ex_rates = puc_ie[1];
1612 
1613             if (num_ex_rates < MAC_MIN_XRATE_LEN) {
1614                 oam_warning_log1(0, OAM_SF_ANY, "{hmac_ie_proc_assoc_user_legacy_rate:: invalid xrates:%d}",
1615                     num_ex_rates);
1616                 return HI_FAIL;
1617             }
1618 
1619             if (num_rates + num_ex_rates > WLAN_MAX_SUPP_RATES) { /* 超出支持速率个数 */
1620                 num_ex_rates = WLAN_MAX_SUPP_RATES - num_rates;
1621             }
1622 
1623             if (memcpy_s(&(hmac_user->op_rates.auc_rs_rates[num_rates]), WLAN_MAX_SUPP_RATES, puc_ie + MAC_IE_HDR_LEN,
1624                 num_ex_rates) != EOK) {
1625                 oam_error_log0(0, OAM_SF_CFG, "hmac_ie_proc_assoc_user_legacy_rate:: puc_ie memcpy_s fail.");
1626                 return HI_FAIL;
1627             }
1628         }
1629     }
1630 
1631     hmac_user->op_rates.rs_nrates = num_rates + num_ex_rates;
1632 
1633     return HI_SUCCESS;
1634 }
1635 
hmac_sta_wait_asoc_rx_handle_for_pmf(hmac_vap_stru * hmac_vap,mac_status_code_enum_uint16 asoc_status)1636 hi_void hmac_sta_wait_asoc_rx_handle_for_pmf(hmac_vap_stru *hmac_vap, mac_status_code_enum_uint16 asoc_status)
1637 {
1638     mac_vap_stru *mac_vap = hmac_vap->base_vap;
1639     hmac_vap->pre_assoc_status = asoc_status;
1640 
1641     if (asoc_status == MAC_REJECT_TEMP) {
1642         mac_vap->mib_info->wlan_mib_sta_config.dot11_association_response_time_out = WLAN_ASSOC_REJECT_TIMEOUT;
1643     } else {
1644         mac_vap->mib_info->wlan_mib_sta_config.dot11_association_response_time_out = WLAN_ASSOC_TIMEOUT;
1645     }
1646 }
1647 
hmac_sta_check_protocol_bandwidth(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user_ap,hmac_asoc_rsp_stru asoc_rsp)1648 hi_u32 hmac_sta_check_protocol_bandwidth(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user_ap,
1649     hmac_asoc_rsp_stru asoc_rsp)
1650 {
1651     wlan_bw_cap_enum_uint8 bwcap;
1652     wlan_bw_cap_enum_uint8 bandwidth_cap;
1653     mac_vap_stru *mac_vap = hmac_vap->base_vap;
1654 
1655     /* 获取用户的协议模式 */
1656     hmac_set_user_protocol_mode(mac_vap, hmac_user_ap);
1657     /* 将协议模式更新到STA */
1658     hi_u8 avail_mode = hmac_get_auc_avail_protocol_mode(mac_vap->protocol, hmac_user_ap->base_user->protocol_mode);
1659     /* STA和AP的协议模式不兼容,STA直接去关联 */
1660     if (avail_mode == WLAN_PROTOCOL_BUTT) {
1661         oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1662             "{hmac_sta_check_protocol_bandwidth::no valid protocol:vap mode=%d, user mode=%d,user avail mode=%d.}",
1663             mac_vap->protocol, hmac_user_ap->base_user->protocol_mode, hmac_user_ap->base_user->avail_protocol_mode);
1664 
1665         asoc_rsp.result_code = HMAC_MGMT_REFUSED;
1666         asoc_rsp.status_code = MAC_UNSUP_RATE;
1667 
1668         /* 将重连次数直接置为max,不进行再次关联 */
1669         hmac_vap->asoc_cnt = MAX_ASOC_CNT;
1670 
1671         /* 发送关联结果给SME */
1672         hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_ASOC_RSP, (hi_u8 *)&asoc_rsp);
1673 
1674         return HI_FAIL;
1675     }
1676     /* 获取用户与VAP协议模式交集 */
1677     hmac_user_ap->base_user->avail_protocol_mode =
1678         hmac_get_auc_avail_protocol_mode(mac_vap->protocol, hmac_user_ap->base_user->protocol_mode);
1679     hmac_user_ap->base_user->cur_protocol_mode = hmac_user_ap->base_user->avail_protocol_mode;
1680     oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1681         "{hmac_sta_check_protocol_bandwidth::user avail_protocol:%d,user cur_protocol:%d,vap protocol:%d}",
1682         hmac_user_ap->base_user->avail_protocol_mode, hmac_user_ap->base_user->cur_protocol_mode, mac_vap->protocol);
1683     /* 获取用户和VAP 可支持的11a/b/g 速率交集 */
1684     hmac_vap_set_user_avail_rates(hmac_vap->base_vap, hmac_user_ap);
1685 
1686     /* 获取用户与VAP带宽能力交集 */
1687     /* 获取用户的带宽能力 */
1688     mac_user_get_ap_opern_bandwidth(hmac_user_ap->base_user, &bandwidth_cap);
1689 
1690     mac_vap_get_bandwidth_cap(mac_vap, &bwcap);
1691     bwcap = oal_min(bwcap, bandwidth_cap);
1692     mac_user_set_bandwidth_info(hmac_user_ap->base_user, bwcap, bwcap);
1693 
1694     oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1695         "{hmac_sta_check_protocol_bandwidth::mac user[%d] en_bandwidth_cap:%d,en_avail_bandwidth:%d}",
1696         hmac_user_ap->base_user->us_assoc_id, bandwidth_cap, hmac_user_ap->base_user->avail_bandwidth);
1697     return HI_SUCCESS;
1698 }
1699 
hmac_sta_wait_asoc_rx_complete_handle(hmac_vap_stru * hmac_vap,hi_u8 user_idx,const hmac_user_stru * hmac_user_ap,hmac_asoc_rsp_stru asoc_rsp,const hmac_rx_ctl_stru * rx_ctrl)1700 hi_void hmac_sta_wait_asoc_rx_complete_handle(hmac_vap_stru *hmac_vap, hi_u8 user_idx,
1701     const hmac_user_stru *hmac_user_ap, hmac_asoc_rsp_stru asoc_rsp, const hmac_rx_ctl_stru *rx_ctrl)
1702 {
1703     hi_u32 rslt;
1704     mac_vap_stru *mac_vap = hmac_vap->base_vap;
1705     mac_user_stru *mac_user_ap = hmac_user_ap->base_user;
1706 
1707     hi_u8 *puc_mac_hdr = (hi_u8 *)(rx_ctrl->pul_mac_hdr_start_addr);
1708     hi_u16 us_msg_len = rx_ctrl->us_frame_len - rx_ctrl->mac_header_len;
1709 
1710     /* STA切换到UP状态 */
1711     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_UP);
1712     /* 将用户(AP)在本地的状态信息设置为已关联状态 */
1713     mac_user_set_asoc_state(hmac_user_ap->base_user, MAC_USER_STATE_ASSOC);
1714 
1715     /* dmac offload架构下,同步STA USR信息到dmac */
1716     rslt = hmac_config_user_cap_syn(hmac_vap->base_vap, mac_user_ap);
1717     if (rslt != HI_SUCCESS) {
1718         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1719             "{hmac_sta_wait_asoc_rx_complete_handle::hmac_config_usr_cap_syn failed[%d].}", rslt);
1720     }
1721 
1722     rslt = hmac_config_user_info_syn(hmac_vap->base_vap, mac_user_ap);
1723     if (rslt != HI_SUCCESS) {
1724         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1725             "{hmac_sta_wait_asoc_rx_complete_handle::hmac_syn_vap_state failed[%d].}", rslt);
1726     }
1727 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1728     rslt = hmac_config_user_rate_info_syn(hmac_vap->base_vap, mac_user_ap);
1729     if (rslt != HI_SUCCESS) {
1730         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1731             "{hmac_sta_wait_asoc_rx_complete_handle::hmac_syn_rate_info failed[%d].}", rslt);
1732     }
1733 #endif
1734 
1735     /* user已经关联上,抛事件给DMAC,在DMAC层挂用户算法钩子 */
1736     hmac_user_add_notify_alg(hmac_vap->base_vap, user_idx);
1737 
1738     /* 准备消息,上报给APP */
1739     asoc_rsp.result_code = HMAC_MGMT_SUCCESS;
1740     asoc_rsp.status_code = MAC_SUCCESSFUL_STATUSCODE;
1741 
1742     /* 记录关联响应帧的部分内容,用于上报给内核 */
1743     asoc_rsp.asoc_rsp_ie_len = us_msg_len - OAL_ASSOC_RSP_FIXED_OFFSET; /* 除去MAC帧头24字节和FIXED部分6字节 */
1744     asoc_rsp.puc_asoc_rsp_ie_buff = puc_mac_hdr + OAL_ASSOC_RSP_IE_OFFSET;
1745 
1746     /* 获取AP的mac地址 */
1747     mac_get_bssid(puc_mac_hdr, asoc_rsp.auc_addr_ap, WLAN_MAC_ADDR_LEN);
1748 
1749     /* 获取关联请求帧信息 */
1750     asoc_rsp.puc_asoc_req_ie_buff = hmac_vap->puc_asoc_req_ie_buff;
1751     asoc_rsp.asoc_req_ie_len = hmac_vap->us_asoc_req_ie_len;
1752 
1753     /* 获取信道中心频率 */
1754     hi_u16 us_freq = (hi_u16)oal_ieee80211_channel_to_frequency(mac_vap->channel.chan_number, mac_vap->channel.band);
1755     asoc_rsp.us_freq = us_freq;
1756 
1757     hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_ASOC_RSP, (hi_u8 *)(&asoc_rsp));
1758 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1759     /* 上报给Lwip */
1760     hmac_report_assoc_state_sta(hmac_vap, asoc_rsp.auc_addr_ap, HI_TRUE);
1761 #endif
1762 #if (_PRE_MULTI_CORE_MODE == _PRE_MULTI_CORE_MODE_OFFLOAD_DMAC)
1763     /* dmac offload架构下,同步STA USR信息到dmac */
1764     rslt = hmac_config_sta_vap_info_syn(hmac_vap->base_vap);
1765     if (rslt != HI_SUCCESS) {
1766         oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1767             "{hmac_sta_wait_asoc_rx::hmac_syn_vap_state failed[%d].}", rslt);
1768     }
1769 #endif
1770 }
1771 
hmac_sta_wait_asoc_rx_complete_update_param(const hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user_ap,const hmac_rx_ctl_stru * rx_ctrl,hi_u16 us_offset)1772 hi_void hmac_sta_wait_asoc_rx_complete_update_param(const hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user_ap,
1773     const hmac_rx_ctl_stru *rx_ctrl, hi_u16 us_offset)
1774 {
1775     hi_u8 *puc_mac_hdr = (hi_u8 *)(rx_ctrl->pul_mac_hdr_start_addr);
1776     hi_u8 *puc_payload = (hi_u8 *)(puc_mac_hdr) + rx_ctrl->mac_header_len;
1777     hi_u16 us_msg_len = rx_ctrl->us_frame_len - rx_ctrl->mac_header_len;
1778     hi_u8 frame_sub_type = mac_get_frame_sub_type(puc_mac_hdr);
1779     mac_vap_stru *mac_vap = hmac_vap->base_vap;
1780     hmac_edca_params_info_stru edca_params_info;
1781     hmac_check_ht_sta_info_stru check_ht_sta_info;
1782     /* sta更新自身的edca parameters */
1783     edca_params_info.puc_payload = puc_payload;
1784     edca_params_info.us_msg_len = us_msg_len;
1785     edca_params_info.us_info_elem_offset = us_offset;
1786     hmac_sta_up_update_edca_params(&edca_params_info, hmac_vap, frame_sub_type, hmac_user_ap);
1787 
1788     /* 更新关联用户的 QoS protocol table */
1789     hmac_mgmt_update_assoc_user_qos(puc_payload, us_msg_len, us_offset, hmac_user_ap);
1790 
1791     /* 更新关联用户的legacy速率集合 */
1792     hi_u32 rslt = hmac_ie_proc_assoc_user_legacy_rate(puc_payload, us_offset, us_msg_len, hmac_user_ap);
1793     if (rslt != HI_SUCCESS) {
1794         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC, "hmac_ie_proc_assoc_user_legacy_rate fail");
1795     }
1796 
1797     /* 更新 HT 参数  */
1798     check_ht_sta_info.puc_payload = puc_payload;
1799     check_ht_sta_info.us_offset = us_offset;
1800     check_ht_sta_info.us_rx_len = us_msg_len;
1801     hi_u32 change = hmac_ie_check_ht_sta(hmac_vap->base_vap, &check_ht_sta_info, hmac_user_ap->base_user,
1802         &hmac_user_ap->us_amsdu_maxsize);
1803     if (MAC_BW_CHANGE & change) {
1804         oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_ASSOC,
1805             "{hmac_sta_wait_asoc_rx::change BW. ul_change[0x%x], uc_channel[%d], en_bandwidth[%d].}", change,
1806             mac_vap->channel.chan_number, mac_vap->channel.en_bandwidth);
1807         hmac_chan_sync(mac_vap, mac_vap->channel.chan_number, mac_vap->channel.en_bandwidth, HI_TRUE);
1808     }
1809 }
1810 
1811 /* ****************************************************************************
1812  功能描述  : 在WAIT_ASOC状态下接收到Asoc_rsp_frame的处理函数
1813  修改历史      :
1814   1.日    期   : 2013年6月28日
1815     作    者   : HiSilicon
1816     修改内容   : 新生成函数
1817 **************************************************************************** */
1818 /* 规则5.1 避免函数过长,函数不超过50行(非空非注释),申请例外: 功能内聚,建议屏蔽 */
hmac_sta_wait_asoc_rx(hmac_vap_stru * hmac_vap,const dmac_wlan_crx_event_stru * crx_event)1819 hi_u32 hmac_sta_wait_asoc_rx(hmac_vap_stru *hmac_vap, const dmac_wlan_crx_event_stru *crx_event)
1820 {
1821     hmac_asoc_rsp_stru          asoc_rsp;
1822     hi_u8                       sa_mac_addr[WLAN_MAC_ADDR_LEN] = { 0 };
1823     hi_u8                       user_idx = 0;
1824     mac_vap_stru *mac_vap = hmac_vap->base_vap;
1825     hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb((oal_netbuf_stru *)crx_event->netbuf);
1826     hi_u8 *puc_mac_hdr = (hi_u8 *)(rx_ctrl->pul_mac_hdr_start_addr);
1827     hi_u8 *puc_payload = (hi_u8 *)(puc_mac_hdr) + rx_ctrl->mac_header_len;
1828     hi_u16 us_msg_len = rx_ctrl->us_frame_len - rx_ctrl->mac_header_len; /* 消息总长度,不包括FCS */
1829 
1830     hi_u16 us_offset = 0;
1831     hi_u8 frame_sub_type = mac_get_frame_sub_type(puc_mac_hdr);
1832 
1833     if (memset_s(&asoc_rsp, sizeof(hmac_asoc_rsp_stru), 0, sizeof(hmac_asoc_rsp_stru)) != EOK) {
1834         return HI_FAIL;
1835     }
1836 
1837     /* 设置初始关联状态为成功 */
1838     asoc_rsp.result_code = HMAC_MGMT_SUCCESS;
1839     switch (frame_sub_type) {
1840         case WLAN_FC0_SUBTYPE_ASSOC_RSP:
1841         case WLAN_FC0_SUBTYPE_REASSOC_RSP:
1842             break;
1843         default:
1844             /* do nothing,wait for time out */
1845             return HI_SUCCESS;
1846     }
1847 
1848     us_offset += MAC_CAP_INFO_LEN;
1849 
1850     mac_status_code_enum_uint16 asoc_status = mac_get_asoc_status(puc_payload);
1851 
1852     us_offset += MAC_STATUS_CODE_LEN;
1853 
1854 #ifdef _PRE_WLAN_FEATURE_PMF
1855     hmac_sta_wait_asoc_rx_handle_for_pmf(hmac_vap, asoc_status);
1856 #endif
1857 
1858     if ((asoc_status != MAC_SUCCESSFUL_STATUSCODE) || (us_msg_len < OAL_ASSOC_RSP_FIXED_OFFSET)) {
1859         oam_warning_log2(0, 0, "{hmac_sta_wait_asoc_rx fail:: asoc_status[%d], msg_len[%d].}", asoc_status, us_msg_len);
1860         return HI_FAIL;
1861     }
1862 
1863     /* 获取SA 地址 */
1864     mac_get_address2(puc_mac_hdr, WLAN_MAC_ADDR_LEN, sa_mac_addr, WLAN_MAC_ADDR_LEN);
1865 
1866     /* 根据SA 地地找到对应AP USER结构 */
1867     hi_u32 rslt = mac_vap_find_user_by_macaddr(hmac_vap->base_vap, sa_mac_addr, WLAN_MAC_ADDR_LEN, &user_idx);
1868     if (rslt != HI_SUCCESS) {
1869         oam_warning_log1(0, 0, "{hmac_sta_wait_asoc_rx:: mac_vap_find_user_by_macaddr failed[%d].}", rslt);
1870 
1871         return rslt;
1872     }
1873 
1874     /* 获取STA关联的AP的用户指针 */
1875     hmac_user_stru *hmac_user_ap = (hmac_user_stru *)hmac_user_get_user_stru(user_idx);
1876     if ((hmac_user_ap == HI_NULL) || (hmac_user_ap->base_user == HI_NULL)) {
1877         return HI_FAIL;
1878     }
1879 
1880     /* 取消定时器 */
1881     frw_timer_immediate_destroy_timer(&(hmac_vap->mgmt_timer));
1882 
1883     /* 更新关联ID */
1884     hi_u16 us_aid = mac_get_asoc_id(puc_payload);
1885     if ((us_aid > 0) && (us_aid <= 2007)) { /* id小于2007 */
1886         mac_vap_set_aid(hmac_vap->base_vap, us_aid);
1887     } else {
1888         oam_warning_log1(0, 0, "{hmac_sta_wait_asoc_rx::invalid us_sta_aid[%d].}", us_aid);
1889     }
1890     us_offset += MAC_AID_LEN;
1891 
1892     /* 初始化安全端口过滤参数 */
1893 #if defined(_PRE_WLAN_FEATURE_WPA) || defined(_PRE_WLAN_FEATURE_WPA2)
1894     rslt = hmac_init_user_security_port(hmac_vap->base_vap, hmac_user_ap->base_user);
1895     if (rslt != HI_SUCCESS) {
1896         oam_error_log1(0, 0, "{hmac_sta_wait_asoc_rx::hmac_init_user_security_port failed[%d].}", rslt);
1897     }
1898 #endif
1899 
1900 #ifdef _PRE_WLAN_FEATURE_PMF
1901     /* STA模式下的pmf能力来源于WPA_supplicant,只有启动pmf和不启动pmf两种类型 */
1902     mac_user_set_pmf_active(hmac_user_ap->base_user, mac_vap->user_pmf_cap);
1903 #endif
1904 
1905     hmac_sta_wait_asoc_rx_complete_update_param(hmac_vap, hmac_user_ap, rx_ctrl, us_offset);
1906 
1907     rslt = hmac_sta_check_protocol_bandwidth(hmac_vap, hmac_user_ap, asoc_rsp);
1908     if (rslt != HI_SUCCESS) {
1909         return HI_SUCCESS;
1910     }
1911 
1912     /* 获取用户与VAP空间流交集 */
1913     rslt = hmac_user_set_avail_num_space_stream(hmac_user_ap->base_user, WLAN_SINGLE_NSS);
1914     if (rslt != HI_SUCCESS) {
1915         oam_warning_log1(0, 0, "{hmac_sta_wait_asoc_rx::mac_user_set_avail_num_space_stream failed[%d].}", rslt);
1916     }
1917 #ifdef _PRE_WLAN_FEATURE_OPMODE_NOTIFY
1918 
1919     /* 处理Operating Mode Notification 信息元素 */
1920     rslt = hmac_check_opmode_notify(hmac_vap, puc_mac_hdr, puc_payload, us_offset, us_msg_len, hmac_user_ap);
1921     if (rslt != HI_SUCCESS) {
1922         oam_warning_log1(0, 0, "{hmac_sta_wait_asoc_rx::hmac_check_opmode_notify failed[%d].}", rslt);
1923     }
1924 #endif
1925 
1926     hmac_sta_wait_asoc_rx_complete_handle(hmac_vap, user_idx, hmac_user_ap, asoc_rsp, rx_ctrl);
1927 
1928     return HI_SUCCESS;
1929 }
1930 
1931 /* ****************************************************************************
1932  功能描述  : 认证超时处理
1933  修改历史      :
1934   1.日    期   : 2013年7月1日
1935     作    者   : HiSilicon
1936     修改内容   : 新生成函数
1937 **************************************************************************** */
hmac_sta_auth_timeout(hmac_vap_stru * hmac_vap)1938 hi_u32 hmac_sta_auth_timeout(hmac_vap_stru *hmac_vap)
1939 {
1940     hmac_auth_rsp_stru auth_rsp = { { 0, }, 0 };
1941 
1942     /* and send it to the host.                                          */
1943     auth_rsp.us_status_code = HMAC_MGMT_TIMEOUT;
1944 
1945     /* Send the response to host now. */
1946     hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_AUTH_RSP, (hi_u8 *)&auth_rsp);
1947 
1948     return HI_SUCCESS;
1949 }
1950 
1951 /* ****************************************************************************
1952  功能描述  : 根据初始化的dev带宽能力和bss的带宽能力决定当前需要使用的带宽
1953  输入参数  :    en_dev_cap, en_bss_cap
1954  返 回 值  : hi_u32
1955  修改历史      :
1956   1.日    期   : 2015年2月5日
1957     作    者   : HiSilicon
1958     修改内容   : 新生成函数
1959 **************************************************************************** */
hmac_sta_get_band(wlan_bw_cap_enum_uint8 dev_cap,wlan_channel_bandwidth_enum_uint8 bss_cap)1960 wlan_channel_bandwidth_enum_uint8 hmac_sta_get_band(wlan_bw_cap_enum_uint8 dev_cap,
1961     wlan_channel_bandwidth_enum_uint8 bss_cap)
1962 {
1963     wlan_channel_bandwidth_enum_uint8 band;
1964 
1965     band = WLAN_BAND_WIDTH_20M;
1966 
1967     if ((dev_cap == WLAN_BW_CAP_80M) && (bss_cap >= WLAN_BAND_WIDTH_80PLUSPLUS)) {
1968         /* 如果AP和STAUT都支持80M,则设置为AP一样 */
1969         band = bss_cap;
1970         return band;
1971     }
1972 
1973     switch (bss_cap) {
1974         case WLAN_BAND_WIDTH_40PLUS:
1975         case WLAN_BAND_WIDTH_80PLUSPLUS:
1976         case WLAN_BAND_WIDTH_80PLUSMINUS:
1977             if (WLAN_BW_CAP_40M <= dev_cap) {
1978                 band = WLAN_BAND_WIDTH_40PLUS;
1979             }
1980             break;
1981 
1982         case WLAN_BAND_WIDTH_40MINUS:
1983         case WLAN_BAND_WIDTH_80MINUSPLUS:
1984         case WLAN_BAND_WIDTH_80MINUSMINUS:
1985             if (WLAN_BW_CAP_40M <= dev_cap) {
1986                 band = WLAN_BAND_WIDTH_40MINUS;
1987             }
1988             break;
1989 
1990         default:
1991             band = WLAN_BAND_WIDTH_20M;
1992             break;
1993     }
1994 
1995     return band;
1996 }
1997 
1998 /* ****************************************************************************
1999  功能描述  : 关联超时处理函数
2000  输入参数  : hmac_vap_stru *pst_hmac_sta, hi_void *p_param
2001  修改历史      :
2002   1.日    期   : 2013年7月5日
2003     作    者   : HiSilicon
2004     修改内容   : 新生成函数
2005 **************************************************************************** */
hmac_sta_wait_asoc_timeout(hmac_vap_stru * hmac_vap)2006 hi_u32 hmac_sta_wait_asoc_timeout(hmac_vap_stru *hmac_vap)
2007 {
2008     hmac_asoc_rsp_stru asoc_rsp = { 0 };
2009 
2010     /* 填写关联结果 */
2011     asoc_rsp.result_code = HMAC_MGMT_TIMEOUT;
2012 
2013     /* 关联超时失败,原因码上报wpa_supplicant */
2014 #ifdef _PRE_WLAN_FEATURE_PMF
2015     if (hmac_vap->pre_assoc_status == MAC_REJECT_TEMP) {
2016         asoc_rsp.status_code = MAC_REJECT_TEMP;
2017     } else {
2018         asoc_rsp.status_code = MAC_AUTH_TIMEOUT;
2019     }
2020 #else
2021     asoc_rsp.status_code = MAC_AUTH_TIMEOUT;
2022 #endif
2023     /* 发送关联结果给SME */
2024     hmac_send_rsp_to_sme_sta(hmac_vap, HMAC_SME_ASOC_RSP, (hi_u8 *)&asoc_rsp);
2025 
2026     return HI_SUCCESS;
2027 }
2028 
2029 /* ****************************************************************************
2030  功能描述  : 上报内核sta已经和某个ap去关联
2031  修改历史      :
2032   1.日    期   : 2013年9月9日
2033     作    者   : HiSilicon
2034     修改内容   : 新生成函数
2035 **************************************************************************** */
hmac_sta_disassoc_rsp(const hmac_vap_stru * hmac_vap,hi_u16 us_disasoc_reason_code,hi_u16 us_dmac_reason_code)2036 hi_void hmac_sta_disassoc_rsp(const hmac_vap_stru *hmac_vap, hi_u16 us_disasoc_reason_code, hi_u16 us_dmac_reason_code)
2037 {
2038     hi_u32 reason_code = ((us_disasoc_reason_code & 0x0000ffff) |
2039         ((us_dmac_reason_code << 16) & 0xffff0000)); /* 16 移位bit数,高2字节和低2字节错开 */
2040     hmac_send_event_to_host(hmac_vap->base_vap, (const hi_u8 *)(&reason_code), sizeof(hi_u32),
2041         HMAC_HOST_CTX_EVENT_SUB_TYPE_DISASOC_COMP_STA);
2042 
2043     const hi_u8 *bcast_mac_addr = mac_get_mac_bcast_addr();
2044     /* 上报给Lwip */
2045     hmac_report_assoc_state_sta(hmac_vap, (hi_u8 *)bcast_mac_addr, HI_FALSE);
2046     return;
2047 }
2048 
2049 /* ****************************************************************************
2050 功能描述  : 处理接收去认证帧
2051 修改历史      :
2052 1.日    期   : 2013年7月1日
2053     作    者   : HiSilicon
2054 修改内容   : 新生成函数
2055 **************************************************************************** */
hmac_sta_rx_deauth_req(hmac_vap_stru * hmac_vap,hi_u8 * mac_hdr,hi_u8 protected)2056 static hi_u32 hmac_sta_rx_deauth_req(hmac_vap_stru *hmac_vap, hi_u8 *mac_hdr, hi_u8 protected)
2057 {
2058     hi_u8  auc_bssid[WLAN_MAC_ADDR_LEN] = {0}; /* 元素个数为6 */
2059     hi_u8 user_idx = 0xff;
2060     hi_u8 *da_mac_addr = HI_NULL;
2061     hi_u8 *sa_mac_addr = HI_NULL;
2062 
2063     /* 增加接收到去认证帧或者去关联帧时的维测信息 */
2064     mac_rx_get_sa((mac_ieee80211_frame_stru *)mac_hdr, &sa_mac_addr);
2065     oam_warning_log4(hmac_vap->base_vap->vap_id, OAM_SF_AUTH,
2066         "{hmac_sta_rx_deauth_req::Because of err_code[%d], received deauth/disassoc frame, sa xx:xx:xx:%2x:%2x:%2x.}",
2067         *((hi_u16 *)(mac_hdr + MAC_80211_FRAME_LEN)), sa_mac_addr[3], sa_mac_addr[4], sa_mac_addr[5]); /* 3 4 5 */
2068 
2069     mac_get_address2(mac_hdr, WLAN_MAC_ADDR_LEN, auc_bssid, WLAN_MAC_ADDR_LEN);
2070 
2071     hi_u32 ret = mac_vap_find_user_by_macaddr(hmac_vap->base_vap, auc_bssid, WLAN_MAC_ADDR_LEN, &user_idx);
2072     if (ret != HI_SUCCESS) {
2073         oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_rx_deauth_req::find user failed=%d}", ret);
2074         return ret;
2075     }
2076 
2077     hmac_user_stru *hmac_user_vap = (hmac_user_stru *)hmac_user_get_user_stru(user_idx);
2078     if ((hmac_user_vap == HI_NULL) || (hmac_user_vap->base_user == HI_NULL)) {
2079         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_rx_deauth_req::pst_hmac_user_vap null.}");
2080 
2081         /* 没有查到对应的USER,发送去认证消息 */
2082         hmac_mgmt_send_deauth_frame(hmac_vap->base_vap, auc_bssid, WLAN_MAC_ADDR_LEN, MAC_NOT_AUTHED);
2083 
2084         hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
2085 
2086         /* 上报内核sta已经和某个ap去关联 */
2087         hmac_sta_disassoc_rsp(hmac_vap, *((hi_u16 *)(mac_hdr + MAC_80211_FRAME_LEN)), DMAC_DISASOC_MISC_WOW_RX_DEAUTH);
2088         return HI_FAIL;
2089     }
2090 
2091 #ifdef _PRE_WLAN_FEATURE_PMF
2092     /* 检查是否需要发送SA query request */
2093     if ((hmac_user_vap->base_user->user_asoc_state == MAC_USER_STATE_ASSOC) &&
2094         (hmac_pmf_check_err_code(hmac_user_vap->base_user, protected, mac_hdr) == HI_SUCCESS)) {
2095         /* 在关联状态下收到未加密的ReasonCode 6/7需要启动SA Query流程 */
2096         ret = hmac_start_sa_query(hmac_vap->base_vap, hmac_user_vap, hmac_user_vap->base_user->cap_info.pmf_active);
2097         if (ret != HI_SUCCESS) {
2098             return HI_ERR_CODE_PMF_SA_QUERY_START_FAIL;
2099         }
2100 
2101         return HI_SUCCESS;
2102     }
2103 #endif
2104 
2105     /* 如果该用户的管理帧加密属性不一致,丢弃该报文 */
2106     mac_rx_get_da((mac_ieee80211_frame_stru *)mac_hdr, &da_mac_addr);
2107     if ((ether_is_multicast(da_mac_addr) != HI_TRUE) && (protected != hmac_user_vap->base_user->cap_info.pmf_active)) {
2108         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_rx_deauth_req::PMF check failed.}");
2109 
2110         return HI_FAIL;
2111     }
2112 
2113     hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
2114 
2115     /* 上报system error 复位 mac */
2116     /* 删除user */
2117     if (hmac_user_del(hmac_vap->base_vap, hmac_user_vap) != HI_SUCCESS) {
2118         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AUTH, "{hmac_sta_rx_deauth_req::hmac_user_del failed.}");
2119 
2120         /* 上报内核sta已经和某个ap去关联 */
2121         hmac_sta_disassoc_rsp(hmac_vap, *((hi_u16 *)(mac_hdr + MAC_80211_FRAME_LEN)), DMAC_DISASOC_MISC_WOW_RX_DEAUTH);
2122         return HI_FAIL;
2123     }
2124 
2125     /* 上报内核sta已经和某个ap去关联 */
2126     hmac_sta_disassoc_rsp(hmac_vap, *((hi_u16 *)(mac_hdr + MAC_80211_FRAME_LEN)), DMAC_DISASOC_MISC_WOW_RX_DEAUTH);
2127 
2128     return HI_SUCCESS;
2129 }
2130 
2131 /* ****************************************************************************
2132  功能描述  : STA收到Beacon帧后,处理HT相关信息元素
2133  输入参数  : pst_mac_vap    : MAC VAP结构体指针,指向STA
2134              puc_payload    : 指向Beacon帧体的指针
2135              us_frame_len   : Beacon帧体的长度(不包括帧头)
2136              us_frame_offset: Beacon帧中第一个IE相对帧体地址的偏移
2137  输出参数  : pst_mac_user   : MAC USER结构体指针,指向AP
2138  返 回 值  : hi_u8:相关信息是否有改变,是否需要同步?
2139  修改历史      :
2140   1.日    期   : 2014年3月3日
2141     作    者   : HiSilicon
2142     修改内容   : 新生成函数
2143 **************************************************************************** */
hmac_sta_up_update_ht_params(mac_vap_stru * mac_vap,const hi_u8 * puc_payload,hi_u16 us_frame_len,hi_u16 us_frame_offset,mac_user_stru * mac_user)2144 static hi_u32 hmac_sta_up_update_ht_params(mac_vap_stru *mac_vap, const hi_u8 *puc_payload, hi_u16 us_frame_len,
2145     hi_u16 us_frame_offset, mac_user_stru *mac_user)
2146 {
2147     hi_u16 us_index = us_frame_offset;
2148     mac_user_ht_hdl_stru ht_hdl;
2149     hi_u32 change = MAC_NO_CHANGE;
2150 
2151     if (memset_s(&ht_hdl, sizeof(mac_user_ht_hdl_stru), 0, sizeof(mac_user_ht_hdl_stru)) != EOK) {
2152         return HI_FAIL;
2153     }
2154     mac_user_get_ht_hdl(mac_user, &ht_hdl);
2155 
2156     while (us_index < us_frame_len) {
2157         if (puc_payload[us_index] == MAC_EID_HT_OPERATION) {
2158             change |= mac_proc_ht_opern_ie(mac_vap, &puc_payload[us_index], mac_user);
2159         }
2160         us_index += puc_payload[us_index + 1] + MAC_IE_HDR_LEN;
2161     }
2162 
2163     if (memcmp((hi_u8 *)(&ht_hdl), (hi_u8 *)(&mac_user->ht_hdl), sizeof(mac_user_ht_hdl_stru)) != 0) {
2164         return (change | MAC_HT_CHANGE);
2165     }
2166 
2167     return HI_FALSE;
2168 }
2169 
2170 /* ****************************************************************************
2171  功能描述  : sta up状态接收beacon帧处理
2172  修改历史      :
2173   1.日    期   : 2013年8月27日
2174     作    者   : HiSilicon
2175     修改内容   : 新生成函数
2176 **************************************************************************** */
hmac_sta_up_rx_beacon(const hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf)2177 static hi_u32 hmac_sta_up_rx_beacon(const hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf)
2178 {
2179     hi_u8 sa_mac_addr[WLAN_MAC_ADDR_LEN] = { 0 };
2180     hi_u8 user_idx = 0;
2181 
2182     hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2183     mac_ieee80211_frame_stru *mac_hdr = (mac_ieee80211_frame_stru *)(rx_ctrl->pul_mac_hdr_start_addr);
2184     hi_u8 *frame_body = (hi_u8 *)mac_hdr + rx_ctrl->mac_header_len;
2185     hi_u16 frame_len = rx_ctrl->us_frame_len - rx_ctrl->mac_header_len; /* 帧体长度 */
2186 
2187     hi_u16 frame_offset = MAC_TIME_STAMP_LEN + MAC_BEACON_INTERVAL_LEN + MAC_CAP_INFO_LEN;
2188     hi_u8 frame_sub_type = mac_get_frame_sub_type((hi_u8 *)mac_hdr);
2189 
2190     /* 来自其它bss的Beacon不做处理 */
2191     if (oal_compare_mac_addr(hmac_vap->base_vap->auc_bssid, mac_hdr->auc_address3, WLAN_MAC_ADDR_LEN) != 0) {
2192         return HI_SUCCESS;
2193     }
2194 
2195     /* 获取管理帧的源地址SA */
2196     mac_get_address2((hi_u8 *)mac_hdr, WLAN_MAC_ADDR_LEN, sa_mac_addr, WLAN_MAC_ADDR_LEN);
2197 
2198     /* 根据SA 地地找到对应AP USER结构 */
2199     if (mac_vap_find_user_by_macaddr(hmac_vap->base_vap, sa_mac_addr, WLAN_MAC_ADDR_LEN, &user_idx) != HI_SUCCESS) {
2200         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_sta_up_rx_beacon:mac_vap_find failed}");
2201         return HI_FAIL;
2202     }
2203     hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(user_idx);
2204     if ((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL)) {
2205         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_sta_up_rx_beacon::pst_hmac_user null.}");
2206         return HI_ERR_CODE_PTR_NULL;
2207     }
2208     /* 处理HT 相关信息元素 */
2209     hi_u32 change_flag = MAC_NO_CHANGE |
2210         hmac_sta_up_update_ht_params(hmac_vap->base_vap, frame_body, frame_len, frame_offset, hmac_user->base_user);
2211 
2212 #ifdef _PRE_WLAN_FEATURE_OPMODE_NOTIFY
2213     /* 处理Operating Mode Notification 信息元素 */
2214     if (hmac_check_opmode_notify(hmac_vap, (hi_u8 *)mac_hdr, frame_body, frame_offset, frame_len, hmac_user) !=
2215         HI_SUCCESS) {
2216         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_sta_up_rx_beacon::hmac_check failed.}");
2217     }
2218 #endif
2219 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
2220     if (((MAC_HT_CHANGE & change_flag) || (MAC_VHT_CHANGE & change_flag)) &&
2221         (hmac_config_user_rate_info_syn(hmac_vap->base_vap, hmac_user->base_user) != HI_SUCCESS)) {
2222         oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_sta_up_rx_beacon::user_rate failed.}");
2223     }
2224 #endif
2225     if (MAC_BW_CHANGE & change_flag) {
2226         hmac_sta_update_mac_user_info(hmac_user, user_idx);
2227 
2228         oam_warning_log3(0, OAM_SF_ASSOC, "{hmac_sta_up_rx_beacon::change BW.change[0x%x],channel[%d],bandwidth[%d].}",
2229             change_flag, hmac_vap->base_vap->channel.chan_number, hmac_vap->base_vap->channel.en_bandwidth);
2230         hmac_chan_sync(hmac_vap->base_vap, hmac_vap->base_vap->channel.chan_number,
2231             hmac_vap->base_vap->channel.en_bandwidth, HI_TRUE);
2232     }
2233 
2234     /* 更新edca参数 */
2235     hmac_edca_params_info_stru edca_params_info = { frame_body, frame_len, frame_offset };
2236     hmac_sta_up_update_edca_params(&edca_params_info, hmac_vap, frame_sub_type, hmac_user);
2237 
2238     return HI_SUCCESS;
2239 }
2240 
2241 /* ****************************************************************************
2242  功能描述  : STA up状态接收Channel Switch Announcement帧处理
2243  输入参数  : pst_mac_vap: MAC VAP结构体指针
2244              pst_netbuf : 包含Channel Switch Announcement帧的netbuf
2245  修改历史      :
2246   1.日    期   : 2014年3月12日
2247     作    者   : HiSilicon
2248     修改内容   : 新生成函数
2249 **************************************************************************** */
hmac_sta_up_rx_ch_switch(mac_vap_stru * mac_vap,oal_netbuf_stru * netbuf)2250 static hi_void hmac_sta_up_rx_ch_switch(mac_vap_stru *mac_vap, oal_netbuf_stru *netbuf)
2251 {
2252     hmac_rx_ctl_stru *rx_ctrl = HI_NULL;
2253     hi_u16 us_index;
2254     hi_u8 *puc_data = HI_NULL;
2255     hi_u16 us_framebody_len;
2256 
2257     if (HI_FALSE == mac_mib_get_spectrum_management_implemented(mac_vap)) {
2258         oam_info_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_sta_up_rx_ch_switch::Ignoring Spectrum Management frames.}");
2259         return;
2260     }
2261 
2262     rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2263     us_framebody_len = rx_ctrl->us_frame_len - rx_ctrl->mac_header_len;
2264 
2265     /* 获取帧体指针 */
2266     puc_data = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr + rx_ctrl->mac_header_len;
2267 
2268     us_index = MAC_ACTION_OFFSET_ACTION + 1;
2269 
2270     while (us_index < us_framebody_len) {
2271         if (puc_data[us_index] == MAC_EID_CHANSWITCHANN) {
2272             hmac_ie_proc_ch_switch_ie(mac_vap, &puc_data[us_index], MAC_EID_CHANSWITCHANN);
2273         } else if (puc_data[us_index] == MAC_EID_SEC_CH_OFFSET) {
2274             if (puc_data[us_index + 1] < MAC_SEC_CH_OFFSET_IE_LEN) {
2275                 oam_warning_log1(0, OAM_SF_ANY, "{dmac_sta_up_rx_ch_switch::invalid sec chan offset ie len[%d]}",
2276                     puc_data[us_index + 1]);
2277                 us_index += MAC_IE_HDR_LEN + puc_data[us_index + 1];
2278                 continue;
2279             }
2280             /* 如果通道发生改变了,不需要切信道么? */
2281             mac_vap->ch_switch_info.new_bandwidth = mac_get_bandwidth_from_sco(puc_data[us_index + MAC_IE_HDR_LEN]);
2282             oam_warning_log1(0, OAM_SF_ANY, "{hmac_sta_up_rx_sca:new_bw[%d]}", mac_vap->ch_switch_info.new_bandwidth);
2283         }
2284         us_index += MAC_IE_HDR_LEN + puc_data[us_index + 1];
2285     }
2286 }
2287 
2288 /* ****************************************************************************
2289  功能描述  : STA up状态接收Extended Channel Switch Announcement帧处理
2290  输入参数  : pst_mac_vap: MAC VAP结构体指针
2291              pst_netbuf : 包含Extended Channel Switch Announcement帧的netbuf
2292  修改历史      :
2293   1.日    期   : 2014年3月12日
2294     作    者   : HiSilicon
2295     修改内容   : 新生成函数
2296 **************************************************************************** */
hmac_sta_up_rx_ext_ch_switch(mac_vap_stru * mac_vap,oal_netbuf_stru * netbuf)2297 static hi_void hmac_sta_up_rx_ext_ch_switch(mac_vap_stru *mac_vap, oal_netbuf_stru *netbuf)
2298 {
2299     hmac_rx_ctl_stru *rx_ctrl = HI_NULL;
2300     hi_u8 *puc_data = HI_NULL;
2301 
2302     if (HI_FALSE == mac_mib_get_spectrum_management_implemented(mac_vap)) {
2303         oam_info_log0(mac_vap->vap_id, OAM_SF_BA,
2304             "{hmac_sta_up_rx_ext_ch_switch::Ignoring Spectrum Management frames.}");
2305         return;
2306     }
2307 
2308     rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2309     /* 获取帧体指针 */
2310     puc_data = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr + rx_ctrl->mac_header_len;
2311 
2312     hmac_ie_proc_ch_switch_ie(mac_vap, puc_data, MAC_EID_EXTCHANSWITCHANN);
2313 }
2314 
2315 /* ****************************************************************************
2316  功能描述  : STA在UP状态下的接收ACTION帧处理
2317  输入参数  : pst_hmac_vap: HMAC VAP结构体指针
2318              pst_netbuf  : Action帧所在的netbuf
2319  修改历史      :
2320   1.日    期   : 2014年3月12日
2321     作    者   : HiSilicon
2322     修改内容   : 新生成函数
2323 **************************************************************************** */
hmac_sta_up_rx_action(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,hi_u8 is_protected)2324 static hi_void hmac_sta_up_rx_action(hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf, hi_u8 is_protected)
2325 {
2326     hmac_user_stru   *hmac_user = HI_NULL;
2327     hmac_rx_ctl_stru *rx_ctrl   = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2328 
2329     /* 获取帧头信息 */
2330     mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
2331 #ifdef _PRE_WLAN_FEATURE_P2P
2332     /* P2P0设备所接受的action全部上报 */
2333     hi_u8 *puc_p2p0_mac_addr = hmac_vap->base_vap->mib_info->wlan_mib_sta_config.auc_p2p0_dot11_station_id;
2334     if (oal_compare_mac_addr(frame_hdr->auc_address1, puc_p2p0_mac_addr, WLAN_MAC_ADDR_LEN) == 0) {
2335         hmac_rx_mgmt_send_to_host(hmac_vap, netbuf);
2336     }
2337 #endif
2338 
2339     /* 获取发送端的用户指针 */
2340     hmac_user = mac_vap_get_hmac_user_by_addr(hmac_vap->base_vap, frame_hdr->auc_address2, WLAN_MAC_ADDR_LEN);
2341     if (hmac_user == HI_NULL) {
2342         oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_sta_up_rx_action::mac_vap_find_user failed.}");
2343         return;
2344     }
2345 
2346     /* 获取帧体指针 */
2347     hi_u8 *puc_data = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr + rx_ctrl->mac_header_len;
2348 
2349     /* Category */
2350     if (puc_data[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_BA) {
2351         hmac_mgmt_rx_action_ba(hmac_vap, hmac_user, puc_data);
2352     } else if (puc_data[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_SPECMGMT) {
2353         if (puc_data[MAC_ACTION_OFFSET_ACTION] == MAC_SPEC_CH_SWITCH_ANNOUNCE) {
2354             hmac_sta_up_rx_ch_switch(hmac_vap->base_vap, netbuf);
2355         }
2356     } else if (puc_data[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_PUBLIC) {
2357         if (puc_data[MAC_ACTION_OFFSET_ACTION] == MAC_PUB_EX_CH_SWITCH_ANNOUNCE) {
2358             hmac_sta_up_rx_ext_ch_switch(hmac_vap->base_vap, netbuf);
2359 #ifdef _PRE_WLAN_FEATURE_P2P
2360         } else if (puc_data[MAC_ACTION_OFFSET_ACTION] == MAC_PUB_VENDOR_SPECIFIC) {
2361             /* 查找OUI-OUI type值为 50 6F 9A - 09 (WFA P2P v1.0)  */
2362             /* 并用hmac_rx_mgmt_send_to_host接口上报 */
2363             if (mac_ie_check_p2p_action(puc_data + MAC_ACTION_OFFSET_ACTION) == HI_TRUE) {
2364                 hmac_rx_mgmt_send_to_host(hmac_vap, netbuf);
2365             }
2366 #endif
2367         }
2368 #ifdef _PRE_WLAN_FEATURE_PMF
2369     } else if (puc_data[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_SA_QUERY) {
2370         if (puc_data[MAC_ACTION_OFFSET_ACTION] == MAC_SA_QUERY_ACTION_REQUEST) {
2371             hmac_rx_sa_query_req(hmac_vap, netbuf, is_protected);
2372         } else if (puc_data[MAC_ACTION_OFFSET_ACTION] == MAC_SA_QUERY_ACTION_RESPONSE) {
2373             hmac_rx_sa_query_rsp(hmac_vap, netbuf, is_protected);
2374         }
2375 #endif
2376 #ifdef _PRE_WLAN_FEATURE_P2P
2377     } else if (puc_data[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_VENDOR) {
2378         /* 查找OUI-OUI type值为 50 6F 9A - 09 (WFA P2P v1.0)  */
2379         /* 并用hmac_rx_mgmt_send_to_host接口上报 */
2380         if (HI_TRUE == mac_ie_check_p2p_action(puc_data + MAC_ACTION_OFFSET_CATEGORY)) {
2381             hmac_rx_mgmt_send_to_host(hmac_vap, netbuf);
2382         }
2383 #endif
2384     }
2385 }
2386 
2387 /* ****************************************************************************
2388  功能描述  : AP在UP状态下的接收管理帧处理
2389  修改历史      :
2390   1.日    期   : 2013年6月24日
2391     作    者   : HiSilicon
2392     修改内容   : 新生成函数
2393 **************************************************************************** */
hmac_sta_up_rx_mgmt(hmac_vap_stru * hmac_vap,const dmac_wlan_crx_event_stru * crx_event)2394 hi_u32 hmac_sta_up_rx_mgmt(hmac_vap_stru *hmac_vap, const dmac_wlan_crx_event_stru *crx_event)
2395 {
2396     hmac_rx_ctl_stru    *rx_ctrl = HI_NULL;
2397     hi_u8               *puc_mac_hdr = HI_NULL;
2398     hi_u8               mgmt_frm_type;
2399     hi_u8               is_protected;
2400     if (crx_event == HI_NULL || crx_event->netbuf == HI_NULL) {
2401         oam_error_log0(0, OAM_SF_AUTH, "{hmac_sta_up_rx_mgmt::crx_event/crx_event->netbuf  is NULL}");
2402         return HI_ERR_CODE_PTR_NULL;
2403     }
2404 
2405     rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb((oal_netbuf_stru *)crx_event->netbuf);
2406 
2407     puc_mac_hdr = (hi_u8 *)(rx_ctrl->pul_mac_hdr_start_addr);
2408     if (puc_mac_hdr == HI_NULL) {
2409         oam_error_log0(0, OAM_SF_AUTH, "{hmac_sta_up_rx_mgmt::puc_mac_hdr is NULL}");
2410         return HI_ERR_CODE_PTR_NULL;
2411     }
2412 
2413     is_protected = mac_get_protectedframe(puc_mac_hdr);
2414 
2415     /* Bar frame proc here */
2416     if (WLAN_FC0_TYPE_CTL == mac_get_frame_type(puc_mac_hdr)) {
2417         mgmt_frm_type = mac_get_frame_sub_type(puc_mac_hdr);
2418         if ((mgmt_frm_type >> 4) == WLAN_BLOCKACK_REQ) { /* 右移4位 */
2419             hmac_up_rx_bar(hmac_vap, rx_ctrl);
2420         }
2421     }
2422 
2423     /* AP在UP状态下 接收到的各种管理帧处理 */
2424     mgmt_frm_type = mac_get_frame_sub_type(puc_mac_hdr);
2425 
2426     switch (mgmt_frm_type) {
2427         case WLAN_FC0_SUBTYPE_DEAUTH:
2428         case WLAN_FC0_SUBTYPE_DISASSOC:
2429             hmac_sta_rx_deauth_req(hmac_vap, puc_mac_hdr, is_protected);
2430             break;
2431 
2432         case WLAN_FC0_SUBTYPE_BEACON:
2433             hmac_sta_up_rx_beacon(hmac_vap, (oal_netbuf_stru *)crx_event->netbuf);
2434             break;
2435 
2436         case WLAN_FC0_SUBTYPE_ACTION:
2437             hmac_sta_up_rx_action(hmac_vap, (oal_netbuf_stru *)crx_event->netbuf, is_protected);
2438             break;
2439         default:
2440             break;
2441     }
2442 
2443     return HI_SUCCESS;
2444 }
2445 
2446 /* ****************************************************************************
2447  功能描述  : 开启25ms重传策略
2448  修改历史      :
2449   1.日    期   : 2019年9月11日
2450     作    者   : HiSilicon
2451     修改内容   : 新生成函数
2452 **************************************************************************** */
hmac_set_retry_time_en(const mac_vap_stru * mac_vap,hi_u8 retry_time,hi_u8 retry_frame_type)2453 hi_u32 hmac_set_retry_time_en(const mac_vap_stru *mac_vap, hi_u8 retry_time, hi_u8 retry_frame_type)
2454 {
2455     mac_cfg_retry_param_stru set_retry_first;
2456     mac_cfg_retry_param_stru set_retry_second;
2457     hi_u32 ret;
2458 
2459     if (mac_vap == HI_NULL) {
2460         oam_error_log0(0, OAM_SF_TX, "{hmac_set_retry_time_en::mac vap is null!}");
2461         return HI_ERR_CODE_PTR_NULL;
2462     }
2463 
2464     /* 将当前重传次数置0 */
2465     set_retry_first.limit = 0;
2466     set_retry_first.type = retry_frame_type;
2467 
2468     /* **************************************************************************
2469         抛事件到DMAC层, 同步DMAC数据
2470     ************************************************************************** */
2471     ret = hmac_config_send_event(mac_vap, WLAN_CFGID_SET_RETRY_LIMIT, sizeof(mac_cfg_retry_param_stru),
2472         (hi_u8 *)&set_retry_first);
2473     if (oal_unlikely(ret != HI_SUCCESS)) {
2474         oam_warning_log1(mac_vap->vap_id, OAM_SF_UM, "{hmac_set_retry_time_en::hmac_config_send_event failed[%d].}",
2475             ret);
2476         return ret;
2477     }
2478 
2479     /* 使能时间重传策略 */
2480     set_retry_second.limit = retry_time;
2481     set_retry_second.type = MAC_CFG_RETRY_TIMEOUT;
2482 
2483     /* **************************************************************************
2484             抛事件到DMAC层, 同步DMAC数据
2485     ************************************************************************** */
2486     ret = hmac_config_send_event(mac_vap, WLAN_CFGID_SET_RETRY_LIMIT, sizeof(mac_cfg_retry_param_stru),
2487         (hi_u8 *)&set_retry_second);
2488     if (oal_unlikely(ret != HI_SUCCESS)) {
2489         oam_warning_log1(mac_vap->vap_id, OAM_SF_UM, "{hmac_set_retry_time_en::hmac_config_send_event failed[%d].}",
2490             ret);
2491         return ret;
2492     }
2493 
2494     return HI_SUCCESS;
2495 }
2496 
2497 /* ****************************************************************************
2498  功能描述  : 关闭25ms重传策略
2499  修改历史      :
2500   1.日    期   : 2019年9月11日
2501     作    者   : HiSilicon
2502     修改内容   : 新生成函数
2503 **************************************************************************** */
hmac_set_retry_time_close(const mac_vap_stru * mac_vap)2504 hi_u32 hmac_set_retry_time_close(const mac_vap_stru *mac_vap)
2505 {
2506     mac_cfg_retry_param_stru set_retry_first;
2507     mac_cfg_retry_param_stru set_retry_second;
2508     mac_cfg_retry_param_stru set_retry_third;
2509     hi_u32 ret;
2510 
2511     if (mac_vap == HI_NULL) {
2512         oam_error_log0(0, OAM_SF_TX, "{hmac_set_retry_time_close::mac vap is null!}");
2513         return HI_ERR_CODE_PTR_NULL;
2514     }
2515 
2516     /* 恢复数据帧重传次数 */
2517     set_retry_first.limit = 5; /* DMAC_MAX_SW_RETRIES: 5 */
2518     set_retry_first.type = MAC_CFG_RETRY_DATA;
2519 
2520     /* **************************************************************************
2521         抛事件到DMAC层, 同步DMAC数据
2522     ************************************************************************** */
2523     ret = hmac_config_send_event(mac_vap, WLAN_CFGID_SET_RETRY_LIMIT, sizeof(mac_cfg_retry_param_stru),
2524         (hi_u8 *)&set_retry_first);
2525     if (oal_unlikely(ret != HI_SUCCESS)) {
2526         oam_warning_log1(mac_vap->vap_id, OAM_SF_UM,
2527                          "{hmac_set_retry_time_close::hmac_config_send_event failed[%d].}", ret);
2528         return ret;
2529     }
2530 
2531     /* 恢复管理帧重传次数 */
2532     set_retry_second.limit = DMAC_MGMT_MAX_SW_RETRIES;
2533     set_retry_second.type = MAC_CFG_RETRY_MGMT;
2534 
2535     /* **************************************************************************
2536             抛事件到DMAC层, 同步DMAC数据
2537     ************************************************************************** */
2538     ret = hmac_config_send_event(mac_vap, WLAN_CFGID_SET_RETRY_LIMIT, sizeof(mac_cfg_retry_param_stru),
2539         (hi_u8 *)&set_retry_second);
2540     if (oal_unlikely(ret != HI_SUCCESS)) {
2541         oam_warning_log1(mac_vap->vap_id, OAM_SF_UM,
2542                          "{hmac_set_retry_time_close::hmac_config_send_event failed[%d].}", ret);
2543         return ret;
2544     }
2545 
2546     /* 关闭时间重传策略 */
2547     set_retry_third.limit = 0;
2548     set_retry_third.type = MAC_CFG_RETRY_TIMEOUT;
2549 
2550     /* **************************************************************************
2551             抛事件到DMAC层, 同步DMAC数据
2552     ************************************************************************** */
2553     ret = hmac_config_send_event(mac_vap, WLAN_CFGID_SET_RETRY_LIMIT, sizeof(mac_cfg_retry_param_stru),
2554         (hi_u8 *)&set_retry_third);
2555     if (oal_unlikely(ret != HI_SUCCESS)) {
2556         oam_warning_log1(mac_vap->vap_id, OAM_SF_UM,
2557                          "{hmac_set_retry_time_close::hmac_config_send_event failed[%d].}", ret);
2558         return ret;
2559     }
2560 
2561     return HI_SUCCESS;
2562 }
2563 
2564 #ifdef __cplusplus
2565 #if __cplusplus
2566 }
2567 #endif
2568 #endif
2569