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