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 "mac_vap.h"
23 #include "mac_ie.h"
24 #include "mac_frame.h"
25 #include "hmac_mgmt_bss_comm.h"
26 #include "mac_resource.h"
27 #include "hmac_device.h"
28 #include "hmac_fsm.h"
29 #include "hmac_encap_frame.h"
30 #include "hmac_mgmt_ap.h"
31 #include "hmac_mgmt_sta.h"
32 #include "hmac_blockack.h"
33 #include "hmac_event.h"
34 #include "frw_timer.h"
35 #ifdef _PRE_WLAN_FEATURE_BTCOEX
36 #include "dmac_btcoex.h"
37 #endif
38 #include "hcc_hmac_if.h"
39
40 #ifdef __cplusplus
41 #if __cplusplus
42 extern "C" {
43 #endif
44 #endif
45
46 /* ****************************************************************************
47 2 全局变量定义
48 **************************************************************************** */
49 hi_u8 g_auc_avail_protocol_mode[WLAN_PROTOCOL_BUTT][WLAN_PROTOCOL_BUTT] = {
50 {WLAN_LEGACY_11A_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT,
51 WLAN_LEGACY_11A_MODE, WLAN_LEGACY_11A_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT},
52
53 {WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11B_MODE,
54 WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11B_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT},
55
56 {WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11G_MODE, WLAN_LEGACY_11G_MODE, WLAN_LEGACY_11G_MODE,
57 WLAN_LEGACY_11G_MODE, WLAN_LEGACY_11G_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11G_MODE},
58
59 {WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_ONE_11G_MODE,
60 WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11G_MODE},
61
62 {WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_TWO_11G_MODE,
63 WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11G_MODE},
64
65 {WLAN_LEGACY_11A_MODE, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_ONE_11G_MODE,
66 WLAN_HT_MODE, WLAN_HT_MODE, WLAN_HT_ONLY_MODE, WLAN_PROTOCOL_BUTT, WLAN_HT_11G_MODE},
67
68 {WLAN_LEGACY_11A_MODE, WLAN_LEGACY_11B_MODE, WLAN_LEGACY_11G_MODE, WLAN_MIXED_ONE_11G_MODE, WLAN_MIXED_ONE_11G_MODE,
69 WLAN_HT_MODE, WLAN_VHT_MODE, WLAN_HT_ONLY_MODE, WLAN_VHT_ONLY_MODE, WLAN_PROTOCOL_BUTT},
70
71 {WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT,
72 WLAN_HT_ONLY_MODE, WLAN_HT_ONLY_MODE, WLAN_HT_ONLY_MODE, WLAN_HT_ONLY_MODE, WLAN_HT_ONLY_MODE},
73
74 {WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT,
75 WLAN_PROTOCOL_BUTT, WLAN_VHT_ONLY_MODE, WLAN_PROTOCOL_BUTT, WLAN_VHT_ONLY_MODE, WLAN_PROTOCOL_BUTT},
76
77 {WLAN_PROTOCOL_BUTT, WLAN_PROTOCOL_BUTT, WLAN_LEGACY_11G_MODE, WLAN_LEGACY_11G_MODE, WLAN_LEGACY_11G_MODE,
78 WLAN_HT_11G_MODE, WLAN_PROTOCOL_BUTT, WLAN_HT_ONLY_MODE, WLAN_PROTOCOL_BUTT, WLAN_HT_11G_MODE},
79 };
80
81 /* ****************************************************************************
82 3 函数实现
83 **************************************************************************** */
hmac_get_auc_avail_protocol_mode(wlan_protocol_enum_uint8 vap_protocol,wlan_protocol_enum_uint8 user_protocol)84 hi_u8 hmac_get_auc_avail_protocol_mode(wlan_protocol_enum_uint8 vap_protocol, wlan_protocol_enum_uint8 user_protocol)
85 {
86 return g_auc_avail_protocol_mode[vap_protocol][user_protocol];
87 }
88
89 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
90 /* ****************************************************************************
91 功能描述 : VAP下 rx BA会话数减1
92 修改历史 :
93 1.日 期 : 2015年3月24日
94 作 者 : HiSilicon
95 修改内容 : 新生成函数
96 **************************************************************************** */
hmac_rx_ba_session_decr(hmac_vap_stru * hmac_vap)97 hi_void hmac_rx_ba_session_decr(hmac_vap_stru *hmac_vap)
98 {
99 if (hmac_vap->rx_ba_session_num == 0) {
100 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
101 "{hmac_rx_ba_session_decr:: rx_session already zero.}");
102 return;
103 }
104 hmac_vap->rx_ba_session_num--;
105 }
106
107 /* ****************************************************************************
108 功能描述 : VAP下 tx BA会话数减1
109 修改历史 :
110 1.日 期 : 2015年3月24日
111 作 者 : HiSilicon
112 修改内容 : 新生成函数
113 **************************************************************************** */
hmac_tx_ba_session_decr(hmac_vap_stru * hmac_vap)114 hi_void hmac_tx_ba_session_decr(hmac_vap_stru *hmac_vap)
115 {
116 if (hmac_vap->tx_ba_session_num == 0) {
117 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
118 "{hmac_tx_ba_session_decr:: tx_session already zero.}");
119 return;
120 }
121 hmac_vap->tx_ba_session_num--;
122 }
123 #else
124 /* ****************************************************************************
125 功能描述 : device下 rx BA会话数减1
126 修改历史 :
127 1.日 期 : 2015年3月24日
128 作 者 : HiSilicon
129 修改内容 : 新生成函数
130 **************************************************************************** */
hmac_rx_ba_session_decr(hmac_device_stru * hmac_dev)131 hi_void hmac_rx_ba_session_decr(hmac_device_stru *hmac_dev)
132 {
133 if (hmac_dev->rx_ba_session_num == 0) {
134 oam_warning_log0(0, OAM_SF_BA, "{hmac_rx_ba_session_decr:: rx_session already zero.}");
135 return;
136 }
137 hmac_dev->rx_ba_session_num--;
138 }
139
140 /* ****************************************************************************
141 功能描述 : device下 tx BA会话数减1
142 修改历史 :
143 1.日 期 : 2015年3月24日
144 作 者 : HiSilicon
145 修改内容 : 新生成函数
146 **************************************************************************** */
hmac_tx_ba_session_decr(hmac_device_stru * hmac_dev)147 hi_void hmac_tx_ba_session_decr(hmac_device_stru *hmac_dev)
148 {
149 if (hmac_dev->tx_ba_session_num == 0) {
150 oam_warning_log0(0, OAM_SF_BA, "{hmac_tx_ba_session_decr::tx_session already zero.}");
151 return;
152 }
153 hmac_dev->tx_ba_session_num--;
154 }
155 #endif
156 /* ****************************************************************************
157 功能描述 : 组装ADDBA_REQ帧
158 修改历史 :
159 1.日 期 : 2013年4月9日
160 作 者 : HiSilicon
161 修改内容 : 新生成函数
162 **************************************************************************** */
hmac_mgmt_encap_addba_req(hmac_vap_stru * hmac_vap,hi_u8 * puc_data,dmac_ba_tx_stru * tx_ba,hi_u8 tid)163 hi_u16 hmac_mgmt_encap_addba_req(hmac_vap_stru *hmac_vap, hi_u8 *puc_data, dmac_ba_tx_stru *tx_ba, hi_u8 tid)
164 {
165 #ifdef _PRE_WLAN_FEATURE_BTCOEX
166 hmac_device_stru *hmac_dev = hmac_get_device_stru();
167 #endif
168 if ((hmac_vap == HI_NULL) || (puc_data == HI_NULL) || (tx_ba == HI_NULL)) {
169 oam_error_log3(0, OAM_SF_BA, "{hmac_mgmt_encap_addba_req::null param.vap:%p data:%p ba:%p}",
170 (uintptr_t)hmac_vap, (uintptr_t)puc_data, (uintptr_t)tx_ba);
171 return HI_ERR_CODE_PTR_NULL;
172 }
173
174 /* *********************************************************************** */
175 /* Management Frame Format */
176 /* -------------------------------------------------------------------- */
177 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
178 /* -------------------------------------------------------------------- */
179 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
180 /* -------------------------------------------------------------------- */
181 /* */
182 /* *********************************************************************** */
183 /* *********************************************************************** */
184 /* Set the fields in the frame header */
185 /* *********************************************************************** */
186 /* Frame Control Field 中只需要设置Type/Subtype值,其他设置为0 */
187 mac_hdr_set_frame_control(puc_data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
188
189 /* DA is address of STA requesting association */
190 if (memcpy_s(puc_data + WLAN_HDR_ADDR1_OFFSET, WLAN_MAC_ADDR_LEN, tx_ba->puc_dst_addr, WLAN_MAC_ADDR_LEN) != EOK) {
191 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_req::memcpy_s fail.}");
192 return 0;
193 }
194 /* SA的值为dot11MACAddress的值 */
195 if (memcpy_s(puc_data + WLAN_HDR_ADDR2_OFFSET, WLAN_MAC_ADDR_LEN,
196 hmac_vap->base_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
197 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_req::memcpy_s fail.}");
198 return 0;
199 }
200 /* Set BSSID */
201 if (memcpy_s(puc_data + WLAN_HDR_ADDR3_OFFSET, WLAN_MAC_ADDR_LEN, hmac_vap->base_vap->auc_bssid,
202 WLAN_MAC_ADDR_LEN) != EOK) {
203 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_req::memcpy_s fail.}");
204 return 0;
205 }
206 /* *********************************************************************** */
207 /* Set the contents of the frame body */
208 /* *********************************************************************** */
209 /* 将索引指向frame body起始位置 */
210 hi_u16 us_index = MAC_80211_FRAME_LEN;
211
212 /* 设置Category */
213 puc_data[us_index++] = MAC_ACTION_CATEGORY_BA;
214
215 /* 设置Action */
216 puc_data[us_index++] = MAC_BA_ACTION_ADDBA_REQ;
217
218 /* 设置Dialog Token */
219 puc_data[us_index++] = tx_ba->dialog_token;
220
221 /*
222 设置Block Ack Parameter set field
223 bit0 - AMSDU Allowed
224 bit1 - Immediate or Delayed block ack
225 bit2-bit5 - TID
226 bit6-bit15 - Buffer size
227 */
228 hi_u16 us_ba_param = tx_ba->amsdu_supp; /* bit0 */
229 us_ba_param |= (tx_ba->ba_policy << 1); /* bit1 */
230 us_ba_param |= (tid << 2); /* bit2 */
231 #ifdef _PRE_WLAN_FEATURE_BTCOEX
232 /* 蓝牙共存打开,并且当前蓝牙正在使用,固定设置ba_size为1;如果当前蓝牙没有使用,则使用默认ba_size */
233 if (hmac_dev->d2h_btcoex_delba.ba_size == 1) {
234 us_ba_param |= (hi_u16)(hmac_dev->d2h_btcoex_delba.ba_size << 6); /* BIT6 */
235 } else {
236 us_ba_param |= (hi_u16)(tx_ba->us_baw_size << 6); /* BIT6 */
237 }
238 #else
239 us_ba_param |= (hi_u16)(tx_ba->us_baw_size << 6); /* bit6 */
240 #endif
241
242 puc_data[us_index++] = (hi_u8)(us_ba_param & 0xFF);
243 puc_data[us_index++] = (hi_u8)((us_ba_param >> 8) & 0xFF); /* 右移8位 */
244
245 /* 设置BlockAck timeout */
246 puc_data[us_index++] = (hi_u8)(tx_ba->us_ba_timeout & 0xFF);
247 puc_data[us_index++] = (hi_u8)((tx_ba->us_ba_timeout >> 8) & 0xFF); /* 右移8位 */
248
249 /*
250 Block ack starting sequence number字段由硬件设置
251 bit0-bit3 fragmentnumber
252 bit4-bit15: sequence number
253 */
254 /* us_buf_seq此处暂不填写,在dmac侧会补充填写 */
255 puc_data[us_index++] = 0;
256 puc_data[us_index++] = 0;
257
258 /* 返回的帧长度中不包括FCS */
259 return us_index;
260 }
261
262 /* ****************************************************************************
263 功能描述 : 组装ADDBA_RSP帧
264 修改历史 :
265 1.日 期 : 2013年4月9日
266 作 者 : HiSilicon
267 修改内容 : 新生成函数
268 **************************************************************************** */
hmac_mgmt_encap_addba_rsp(hmac_vap_stru * vap,hi_u8 * data,hmac_ba_rx_stru * addba_rsp,hi_u8 tid,hi_u8 status)269 hi_u16 hmac_mgmt_encap_addba_rsp(hmac_vap_stru *vap, hi_u8 *data, hmac_ba_rx_stru *addba_rsp, hi_u8 tid, hi_u8 status)
270 {
271 #ifdef _PRE_WLAN_FEATURE_BTCOEX
272 hmac_device_stru *hmac_dev = hmac_get_device_stru();
273 #endif
274
275 if ((vap == HI_NULL) || (data == HI_NULL) || (addba_rsp == HI_NULL)) {
276 oam_error_log3(0, OAM_SF_BA, "{hmac_mgmt_encap_addba_req::null param.vap:%p data:%p rsp:%p}", (uintptr_t)vap,
277 (uintptr_t)data, (uintptr_t)addba_rsp);
278 return HI_ERR_CODE_PTR_NULL;
279 }
280
281 /* *********************************************************************** */
282 /* Management Frame Format */
283 /* -------------------------------------------------------------------- */
284 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
285 /* -------------------------------------------------------------------- */
286 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
287 /* -------------------------------------------------------------------- */
288 /* */
289 /* *********************************************************************** */
290 /* *********************************************************************** */
291 /* Set the fields in the frame header */
292 /* *********************************************************************** */
293 /* All the fields of the Frame Control Field are set to zero. Only the */
294 /* Type/Subtype field is set. */
295 mac_hdr_set_frame_control(data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
296 /* DA is address of STA requesting association */
297 if (memcpy_s(data + WLAN_HDR_ADDR1_OFFSET, WLAN_MAC_ADDR_LEN,
298 addba_rsp->puc_transmit_addr, WLAN_MAC_ADDR_LEN) != EOK) {
299 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_rsp::memcpy_s fail.}");
300 return 0;
301 }
302 /* SA is the dot11MACAddress */
303 if (memcpy_s(data + WLAN_HDR_ADDR2_OFFSET, WLAN_MAC_ADDR_LEN,
304 vap->base_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
305 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_rsp::memcpy_s fail.}");
306 return 0;
307 }
308 /* Set BSSID */
309 if (memcpy_s(data + WLAN_HDR_ADDR3_OFFSET, WLAN_MAC_ADDR_LEN,
310 vap->base_vap->auc_bssid, WLAN_MAC_ADDR_LEN) != EOK) {
311 oam_error_log0(0, 0, "{hmac_mgmt_encap_addba_rsp::memcpy_s fail.}");
312 return 0;
313 }
314 /* *********************************************************************** */
315 /* Set the contents of the frame body */
316 /* *********************************************************************** */
317 /* *********************************************************************** */
318 /* ADDBA Response Frame - Frame Body */
319 /* --------------------------------------------------------------- */
320 /* | Category | Action | Dialog | Status | Parameters | Timeout | */
321 /* --------------------------------------------------------------- */
322 /* | 1 | 1 | 1 | 2 | 2 | 2 | */
323 /* --------------------------------------------------------------- */
324 /* */
325 /* *********************************************************************** */
326 /* Initialize index and the frame data pointer */
327 hi_u16 us_index = MAC_80211_FRAME_LEN;
328
329 /* Action Category设置 */
330 data[us_index++] = MAC_ACTION_CATEGORY_BA;
331
332 /* 特定Action种类下的action的帧类型 */
333 data[us_index++] = MAC_BA_ACTION_ADDBA_RSP;
334
335 /* Dialog Token域设置,需要从req中copy过来 */
336 data[us_index++] = addba_rsp->dialog_token;
337
338 /* 状态域设置 */
339 data[us_index++] = status;
340 data[us_index++] = 0;
341
342 /* Block Ack Parameter设置 */
343 /* B0 - AMSDU Support, B1- Immediate or Delayed block ack */
344 /* B2-B5 : TID, B6-B15: Buffer size */
345 hi_u16 us_ba_param = addba_rsp->amsdu_supp; /* BIT0 */
346 us_ba_param |= (addba_rsp->ba_policy << 1); /* BIT1 */
347 us_ba_param |= (tid << 2); /* BIT2 */
348 #ifdef _PRE_WLAN_FEATURE_BTCOEX
349 /* 蓝牙共存打开,并且当前蓝牙正在使用,固定设置ba_size为1;如果当前蓝牙没有使用,则使用默认ba_size */
350 if (hmac_dev->d2h_btcoex_delba.ba_size == 1) {
351 us_ba_param |= (hi_u16)(hmac_dev->d2h_btcoex_delba.ba_size << 6); /* BIT6 */
352 } else {
353 us_ba_param |= (hi_u16)(addba_rsp->us_baw_size << 6); /* BIT6 */
354 }
355 #else
356 us_ba_param |= (hi_u16)(addba_rsp->us_baw_size << 6); /* BIT6 */
357 #endif
358
359 data[us_index++] = (hi_u8)(us_ba_param & 0xFF);
360 data[us_index++] = (hi_u8)((us_ba_param >> 8) & 0xFF); /* 右移8位 */
361
362 data[us_index++] = 0x00;
363 data[us_index++] = 0x00;
364
365 /* 返回的帧长度中不包括FCS */
366 return us_index;
367 }
368
369 /* ****************************************************************************
370 功能描述 : 组装DELBA帧
371 修改历史 :
372 1.日 期 : 2013年4月9日
373 作 者 : HiSilicon
374 修改内容 : 新生成函数
375 **************************************************************************** */
hmac_mgmt_encap_delba(hmac_vap_stru * hmac_vap,hi_u8 * puc_data,const mac_action_mgmt_args_stru * action_args)376 hi_u16 hmac_mgmt_encap_delba(hmac_vap_stru *hmac_vap, hi_u8 *puc_data, const mac_action_mgmt_args_stru *action_args)
377 {
378 hi_u16 us_index;
379 hi_u8 tid = (hi_u8)action_args->arg1;
380 hi_u8 reason = (hi_u8)action_args->arg3;
381 mac_delba_initiator_enum_uint8 initiator = (hi_u8)action_args->arg2;
382
383 if ((hmac_vap == HI_NULL) || (puc_data == HI_NULL) || (action_args->puc_arg5 == HI_NULL)) {
384 oam_error_log3(0, OAM_SF_BA, "{hmac_mgmt_encap_delba::null param, %p %p %p.}", (uintptr_t)hmac_vap,
385 (uintptr_t)puc_data, (uintptr_t)(action_args->puc_arg5));
386 return HI_ERR_CODE_PTR_NULL;
387 }
388
389 /* *********************************************************************** */
390 /* Management Frame Format */
391 /* -------------------------------------------------------------------- */
392 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
393 /* -------------------------------------------------------------------- */
394 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
395 /* -------------------------------------------------------------------- */
396 /* */
397 /* *********************************************************************** */
398 /* *********************************************************************** */
399 /* Set the fields in the frame header */
400 /* *********************************************************************** */
401 /* All the fields of the Frame Control Field are set to zero. Only the */
402 /* Type/Subtype field is set. */
403 mac_hdr_set_frame_control(puc_data, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
404
405 /* duration */
406 puc_data[WLAN_HDR_DUR_OFFSET] = 0;
407 puc_data[WLAN_HDR_DUR_OFFSET + 1] = 0;
408 /* DA is address of STA requesting association */
409 if (memcpy_s(puc_data + WLAN_HDR_ADDR1_OFFSET, WLAN_MAC_ADDR_LEN, action_args->puc_arg5, WLAN_MAC_ADDR_LEN) !=
410 EOK) {
411 oam_error_log0(0, 0, "{hmac_mgmt_encap_delba::memcpy_s fail.}");
412 return 0;
413 }
414 /* SA is the dot11MACAddress */
415 if (memcpy_s(puc_data + WLAN_HDR_ADDR2_OFFSET, WLAN_MAC_ADDR_LEN,
416 hmac_vap->base_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
417 oam_error_log0(0, 0, "{hmac_mgmt_encap_delba::memcpy_s fail.}");
418 return 0;
419 }
420 /* Set BSSID */
421 if (memcpy_s(puc_data + WLAN_HDR_ADDR3_OFFSET, WLAN_MAC_ADDR_LEN, hmac_vap->base_vap->auc_bssid,
422 WLAN_MAC_ADDR_LEN) != EOK) {
423 oam_error_log0(0, 0, "{hmac_mgmt_encap_delba::memcpy_s fail.}");
424 return 0;
425 }
426
427 /* seq control */
428 puc_data[WLAN_HDR_FRAG_OFFSET] = 0;
429 puc_data[WLAN_HDR_FRAG_OFFSET + 1] = 0;
430
431 /* *********************************************************************** */
432 /* Set the contents of the frame body */
433 /* *********************************************************************** */
434 /* *********************************************************************** */
435 /* DELBA Response Frame - Frame Body */
436 /* ------------------------------------------------- */
437 /* | Category | Action | Parameters | Reason code | */
438 /* ------------------------------------------------- */
439 /* | 1 | 1 | 2 | 2 | */
440 /* ------------------------------------------------- */
441 /* Parameters */
442 /* ------------------------------- */
443 /* | Reserved | Initiator | TID | */
444 /* ------------------------------- */
445 /* bit | 11 | 1 | 4 | */
446 /* -------------------------------- */
447 /* *********************************************************************** */
448 /* Initialize index and the frame data pointer */
449 us_index = MAC_80211_FRAME_LEN;
450
451 /* Category */
452 puc_data[us_index++] = MAC_ACTION_CATEGORY_BA;
453
454 /* Action */
455 puc_data[us_index++] = MAC_BA_ACTION_DELBA;
456
457 /* DELBA parameter set */
458 /* B0 - B10 -reserved */
459 /* B11 - initiator */
460 /* B12-B15 - TID */
461 puc_data[us_index++] = 0;
462 puc_data[us_index] = (hi_u8)(initiator << 3); /* 左移3位 */
463 puc_data[us_index++] |= (hi_u8)(tid << 4); /* 左移4位 */
464
465 /* Reason field */
466 /* Reason can be either of END_BA, QSTA_LEAVING, UNKNOWN_BA */
467 puc_data[us_index++] = reason;
468 puc_data[us_index++] = 0;
469
470 /* 返回的帧长度中不包括FCS */
471 return us_index;
472 }
473
hmac_mgmt_set_addba_req(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,dmac_ba_tx_stru * tx_ba,oal_netbuf_stru * addba_req,const hmac_addba_req_info * addba_info)474 hi_u32 hmac_mgmt_set_addba_req(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user, dmac_ba_tx_stru *tx_ba,
475 oal_netbuf_stru *addba_req, const hmac_addba_req_info *addba_info)
476 {
477 mac_vap_stru *mac_vap = hmac_vap->base_vap;
478 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(addba_req);
479
480 dmac_ctx_action_event_stru wlan_ctx_action = { 0 };
481
482 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化 */
483 memset_s(oal_netbuf_cb(addba_req), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
484
485 /* 调用封装管理帧接口 */
486 hi_u16 us_frame_len = hmac_mgmt_encap_addba_req(hmac_vap, oal_netbuf_data(addba_req), tx_ba, addba_info->tidno);
487 if (us_frame_len == 0) {
488 oam_error_log0(0, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::frame len is 0.}");
489 oal_netbuf_free(addba_req);
490 return HI_FAIL;
491 }
492
493 /* 赋值要传入Dmac的信息 */
494 wlan_ctx_action.us_frame_len = us_frame_len;
495 wlan_ctx_action.hdr_len = MAC_80211_FRAME_LEN;
496 wlan_ctx_action.action_category = MAC_ACTION_CATEGORY_BA;
497 wlan_ctx_action.action = MAC_BA_ACTION_ADDBA_REQ;
498 wlan_ctx_action.user_idx = hmac_user->base_user->us_assoc_id;
499 wlan_ctx_action.tidno = addba_info->tidno;
500 wlan_ctx_action.dialog_token = tx_ba->dialog_token;
501 wlan_ctx_action.ba_policy = tx_ba->ba_policy;
502 wlan_ctx_action.us_baw_size = tx_ba->us_baw_size;
503 wlan_ctx_action.us_ba_timeout = tx_ba->us_ba_timeout;
504
505 if (memcpy_s((hi_u8 *)(oal_netbuf_data(addba_req) + us_frame_len), sizeof(dmac_ctx_action_event_stru),
506 (hi_u8 *)&wlan_ctx_action, sizeof(dmac_ctx_action_event_stru)) != EOK) {
507 oal_netbuf_free(addba_req);
508 oam_error_log0(0, OAM_SF_CFG, "hmac_mgmt_tx_addba_req:: st_wlan_ctx_action memcpy_s fail.");
509 return HI_FAIL;
510 }
511 oal_netbuf_put(addba_req, (us_frame_len + sizeof(dmac_ctx_action_event_stru)));
512
513 tx_ctl->us_mpdu_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
514 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
515 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(addba_req);
516 tx_ctl->mac_head_type = 1;
517
518 mac_vap_set_cb_tx_user_idx(mac_vap, tx_ctl, hmac_user->base_user->user_mac_addr);
519
520 *(addba_info->frame_len) = us_frame_len;
521
522 return HI_SUCCESS;
523 }
524
hmac_mgmt_send_addba_event(const mac_vap_stru * mac_vap,oal_netbuf_stru * addba_req,hi_u16 us_frame_len)525 hi_u32 hmac_mgmt_send_addba_event(const mac_vap_stru *mac_vap, oal_netbuf_stru *addba_req, hi_u16 us_frame_len)
526 {
527 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_tx_event_stru));
528 if (event_mem == HI_NULL) {
529 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::event_mem null.}");
530 oal_netbuf_free(addba_req);
531 return HI_ERR_CODE_PTR_NULL;
532 }
533
534 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
535 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_ACTION,
536 sizeof(dmac_tx_event_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
537
538 dmac_tx_event_stru *tx_event = (dmac_tx_event_stru *)(event->auc_event_data);
539 tx_event->netbuf = addba_req;
540 tx_event->us_frame_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
541
542 hi_u32 ret = hcc_hmac_tx_data_event(event_mem, addba_req, HI_TRUE);
543 if (ret != HI_SUCCESS) {
544 oal_netbuf_free(addba_req);
545 oam_error_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::frw_event_dispatch_event Err[%d].}", ret);
546 frw_event_free(event_mem);
547 return ret;
548 }
549
550 frw_event_free(event_mem);
551
552 return HI_SUCCESS;
553 }
554
hmac_mgmt_set_ba_tx_info(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const mac_vap_stru * mac_vap,const dmac_ba_tx_stru * tx_ba,hi_u8 tidno)555 hi_u32 hmac_mgmt_set_ba_tx_info(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, const mac_vap_stru *mac_vap,
556 const dmac_ba_tx_stru *tx_ba, hi_u8 tidno)
557 {
558 hi_unref_param(hmac_vap);
559
560 if (hmac_user->ast_tid_info[tidno].ba_tx_info != HI_NULL) {
561 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req:tid[%d] already set up}", tidno);
562 hmac_ba_reset_tx_handle(&hmac_user->ast_tid_info[tidno].ba_tx_info);
563 }
564
565 hmac_user->ast_tid_info[tidno].ba_tx_info = (hmac_ba_tx_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
566 (hi_u16) sizeof(hmac_ba_tx_stru));
567 if (hmac_user->ast_tid_info[tidno].ba_tx_info == HI_NULL) {
568 oam_error_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::mem alloc failed.tid[%d]}", tidno);
569 return HI_ERR_CODE_PTR_NULL;
570 }
571
572 if (memset_s(hmac_user->ast_tid_info[tidno].ba_tx_info, sizeof(hmac_ba_tx_stru),
573 0, sizeof(hmac_ba_tx_stru)) != EOK) {
574 oal_mem_free(hmac_user->ast_tid_info[tidno].ba_tx_info);
575 hmac_user->ast_tid_info[tidno].ba_tx_info = HI_NULL;
576 oam_error_log0(0, OAM_SF_CFG, "hmac_mgmt_tx_addba_req:: ba_tx_info memset_s fail.");
577 return HI_FAIL;
578 }
579
580 hmac_ba_tx_stru *tx_ba_stru = hmac_user->ast_tid_info[tidno].ba_tx_info;
581 /* 更新对应的TID信息 */
582 tx_ba_stru->ba_status = DMAC_BA_INPROGRESS;
583 tx_ba_stru->dialog_token = tx_ba->dialog_token;
584 /* 初始化超时定时器资源 */
585 tx_ba_stru->alarm_data.ba = tx_ba_stru;
586 tx_ba_stru->alarm_data.mac_user_idx = (hi_u8)hmac_user->base_user->us_assoc_id;
587 tx_ba_stru->alarm_data.vap_id = mac_vap->vap_id;
588 tx_ba_stru->alarm_data.tid = tidno;
589 tx_ba_stru->alarm_data.us_timeout_times = 0;
590 tx_ba_stru->alarm_data.direction = MAC_ORIGINATOR_DELBA;
591
592 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
593 hmac_vap->tx_ba_session_num++;
594 #else
595 /* 获取device结构 */
596 hmac_device_stru *hmac_dev = hmac_get_device_stru();
597 hmac_dev->tx_ba_session_num++;
598 #endif
599
600 /* 启动ADDBA超时计时器 */
601 frw_timer_create_timer(&(hmac_user->ast_tid_info[tidno].ba_tx_info->addba_timer), hmac_mgmt_tx_addba_timeout,
602 WLAN_ADDBA_TIMEOUT, &(hmac_user->ast_tid_info[tidno].ba_tx_info->alarm_data), HI_FALSE);
603
604 return HI_SUCCESS;
605 }
606
hmac_mgmt_tx_addba_rsp_send_event(hmac_ba_rx_stru * ba_rx_info,const mac_vap_stru * mac_vap,oal_netbuf_stru * addba_rsp,hmac_tx_ctl_stru * tx_ctl,hi_u16 us_frame_len)607 hi_u32 hmac_mgmt_tx_addba_rsp_send_event(hmac_ba_rx_stru *ba_rx_info, const mac_vap_stru *mac_vap,
608 oal_netbuf_stru *addba_rsp, hmac_tx_ctl_stru *tx_ctl, hi_u16 us_frame_len)
609 {
610 tx_ctl->us_mpdu_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
611 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
612 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(addba_rsp);
613 tx_ctl->mac_head_type = 1;
614
615 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_tx_event_stru));
616 if (event_mem == HI_NULL) {
617 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_rsp::event_mem mem alloc failed.}");
618 oal_netbuf_free(addba_rsp);
619 return HI_ERR_CODE_PTR_NULL;
620 }
621
622 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
623 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_ACTION,
624 sizeof(dmac_tx_event_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
625
626 /* 填写事件payload */
627 dmac_tx_event_stru *tx_event = (dmac_tx_event_stru *)(event->auc_event_data);
628 tx_event->netbuf = addba_rsp;
629 tx_event->us_frame_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
630
631 hi_u32 ret = hcc_hmac_tx_data_event(event_mem, addba_rsp, HI_TRUE);
632 if (ret != HI_SUCCESS) {
633 oal_netbuf_free(addba_rsp);
634 oam_error_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_rsp::hcc_hmac_tx_data_event Err=%d}", ret);
635 } else {
636 ba_rx_info->ba_status = DMAC_BA_COMPLETE;
637 }
638
639 frw_event_free(event_mem);
640
641 return ret;
642 }
643
644 /* ****************************************************************************
645 功能描述 : 发送ADDBA_REQ帧
646 修改历史 :
647 1.日 期 : 2013年4月14日
648 作 者 : HiSilicon
649 修改内容 : 新生成函数
650 **************************************************************************** */
hmac_mgmt_tx_addba_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const mac_action_mgmt_args_stru * action_args)651 hi_u32 hmac_mgmt_tx_addba_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
652 const mac_action_mgmt_args_stru *action_args)
653 {
654 dmac_ba_tx_stru tx_ba = { 0 };
655 hmac_addba_req_info addba_req_info = { 0 };
656 mac_vap_stru *mac_vap = hmac_vap->base_vap;
657
658 hi_u16 us_frame_len = 0;
659 hi_u8 tidno = (hi_u8)(action_args->arg1);
660
661 /* 确定vap处于工作状态 */
662 if (mac_vap->vap_state == MAC_VAP_STATE_BUTT) {
663 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::vap state[%d]Err}", mac_vap->vap_state);
664 return HI_FAIL;
665 }
666
667 /* 申请ADDBA_REQ管理帧内存 */
668 oal_netbuf_stru *addba_req = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
669 if (addba_req == HI_NULL) {
670 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_req::pst_addba_req null.}");
671 return HI_ERR_CODE_PTR_NULL;
672 }
673
674 hmac_vap->ba_dialog_token++;
675
676 tx_ba.dialog_token = hmac_vap->ba_dialog_token; /* 保证ba会话创建能够区分 */
677 tx_ba.us_baw_size = (hi_u8)(action_args->arg2);
678 tx_ba.ba_policy = (hi_u8)(action_args->arg3);
679 tx_ba.us_ba_timeout = (hi_u16)(action_args->arg4);
680 tx_ba.puc_dst_addr = hmac_user->base_user->user_mac_addr;
681 tx_ba.amsdu_supp = (hi_u8)hmac_vap->amsdu_ampdu_active; /* 发端对AMPDU+AMSDU的支持 */
682
683 /* 下面的~操作符表达式中的变量是无符号数,误报告警,lin_t e502告警屏蔽 */
684 if (tx_ba.amsdu_supp == HI_FALSE) {
685 hmac_user_set_amsdu_not_support(hmac_user, tidno);
686 } else {
687 /* lin_t +e502 */
688 hmac_user_set_amsdu_support(hmac_user, tidno);
689 }
690
691 addba_req_info.tidno = tidno;
692 addba_req_info.frame_len = &us_frame_len;
693 hi_u32 ret = hmac_mgmt_set_addba_req(hmac_vap, hmac_user, &tx_ba, addba_req, &addba_req_info);
694 if (ret != HI_SUCCESS) {
695 return ret;
696 }
697
698 ret = hmac_mgmt_send_addba_event(mac_vap, addba_req, us_frame_len);
699 if (ret != HI_SUCCESS) {
700 return ret;
701 }
702
703 ret = hmac_mgmt_set_ba_tx_info(hmac_vap, hmac_user, mac_vap, &tx_ba, tidno);
704 return ret;
705 }
706
707 /* ****************************************************************************
708 功能描述 :发送ADDBA_RSP帧
709 修改历史 :
710 1.日 期 : 2014年11月29日
711 作 者 : HiSilicon
712 修改内容 : 新生成函数
713 **************************************************************************** */
hmac_mgmt_tx_addba_rsp(hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,hmac_ba_rx_stru * ba_rx_info,hi_u8 tid,hi_u8 status)714 hi_u32 hmac_mgmt_tx_addba_rsp(hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user, hmac_ba_rx_stru *ba_rx_info,
715 hi_u8 tid, hi_u8 status)
716 {
717 dmac_ctx_action_event_stru wlan_ctx_action = { 0 };
718 mac_vap_stru *mac_vap = hmac_vap->base_vap;
719
720 if (mac_vap->vap_state == MAC_VAP_STATE_BUTT) {
721 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_rsp:VapDown/Del,stat%d}", mac_vap->vap_state);
722 return HI_FAIL;
723 }
724
725 /* 申请ADDBA_RSP管理帧内存 */
726 oal_netbuf_stru *addba_rsp = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
727 if (addba_rsp == HI_NULL) {
728 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_rsp::addba_rsp mem alloc failed}");
729 return HI_ERR_CODE_PTR_NULL;
730 }
731
732 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化 */
733 memset_s(oal_netbuf_cb(addba_rsp), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
734
735 /* 填写netbuf的cb字段,共发送管理帧和发送完成接口使用 */
736 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(addba_rsp);
737 tx_ctl->us_tx_user_idx = hmac_user->base_user->us_assoc_id;
738 tx_ctl->tid = tid;
739 tx_ctl->is_amsdu = HI_FALSE;
740
741 hi_u16 us_frame_len = hmac_mgmt_encap_addba_rsp(hmac_vap, oal_netbuf_data(addba_rsp), ba_rx_info, tid, status);
742 if (us_frame_len == 0) {
743 oal_netbuf_free(addba_rsp);
744 return HI_FAIL;
745 }
746
747 wlan_ctx_action.action_category = MAC_ACTION_CATEGORY_BA;
748 wlan_ctx_action.action = MAC_BA_ACTION_ADDBA_RSP;
749 wlan_ctx_action.hdr_len = MAC_80211_FRAME_LEN;
750 wlan_ctx_action.us_baw_size = ba_rx_info->us_baw_size;
751 wlan_ctx_action.us_frame_len = us_frame_len;
752 wlan_ctx_action.user_idx = hmac_user->base_user->us_assoc_id;
753 wlan_ctx_action.tidno = tid;
754 wlan_ctx_action.stauts = status;
755 wlan_ctx_action.us_ba_timeout = ba_rx_info->us_ba_timeout;
756 wlan_ctx_action.back_var = ba_rx_info->back_var;
757 wlan_ctx_action.lut_index = ba_rx_info->lut_index;
758 wlan_ctx_action.us_baw_start = ba_rx_info->us_baw_start;
759 wlan_ctx_action.ba_policy = ba_rx_info->ba_policy;
760
761 if (memcpy_s((hi_u8 *)(oal_netbuf_data(addba_rsp) + us_frame_len), sizeof(dmac_ctx_action_event_stru),
762 (hi_u8 *)&wlan_ctx_action, sizeof(dmac_ctx_action_event_stru)) != EOK) {
763 oal_netbuf_free(addba_rsp);
764 oam_error_log0(0, OAM_SF_CFG, "hmac_mgmt_tx_addba_rsp:: st_wlan_ctx_action memcpy_s fail.");
765 return HI_FAIL;
766 }
767
768 oal_netbuf_put(addba_rsp, (us_frame_len + sizeof(dmac_ctx_action_event_stru)));
769
770 hi_u32 ret = hmac_mgmt_tx_addba_rsp_send_event(ba_rx_info, mac_vap, addba_rsp, tx_ctl, us_frame_len);
771 return ret;
772 }
773
hmac_mgmt_tx_delba_send_event(hmac_user_stru * hmac_user,const mac_action_mgmt_args_stru * action_args,mac_vap_stru * mac_vap,oal_netbuf_stru * delba,hi_u16 us_frame_len)774 hi_u32 hmac_mgmt_tx_delba_send_event(hmac_user_stru *hmac_user, const mac_action_mgmt_args_stru *action_args,
775 mac_vap_stru *mac_vap, oal_netbuf_stru *delba, hi_u16 us_frame_len)
776 {
777 hi_u8 tidno = (hi_u8)(action_args->arg1);
778 mac_delba_initiator_enum_uint8 initiator = (mac_delba_initiator_enum_uint8)(action_args->arg2);
779
780 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(delba);
781
782 tx_ctl->us_mpdu_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
783 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
784 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(delba);
785 tx_ctl->mac_head_type = 1;
786
787 mac_vap_set_cb_tx_user_idx(mac_vap, tx_ctl, hmac_user->base_user->user_mac_addr);
788
789 /* 抛事件,到DMAC模块发送 */
790 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_tx_event_stru));
791 if (event_mem == HI_NULL) {
792 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba::event_mem null.}");
793 /* 释放管理帧内存到netbuf内存池 */
794 oal_netbuf_free(delba);
795 return HI_ERR_CODE_PTR_NULL;
796 }
797
798 /* 获得事件指针 */
799 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
800
801 /* 填写事件头 */
802 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_ACTION,
803 sizeof(dmac_tx_event_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
804
805 /* 填写事件payload */
806 dmac_tx_event_stru *tx_event = (dmac_tx_event_stru *)(event->auc_event_data);
807 tx_event->netbuf = delba;
808 tx_event->us_frame_len = us_frame_len + sizeof(dmac_ctx_action_event_stru);
809
810 /* 分发 */
811 hi_u32 ret = hcc_hmac_tx_data_event(event_mem, delba, HI_TRUE);
812 if (ret != HI_SUCCESS) {
813 oal_netbuf_free(delba);
814 oam_error_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba::frw_event_dispatch_event failed[%d].}", ret);
815 frw_event_free(event_mem);
816 return ret;
817 }
818
819 frw_event_free(event_mem);
820
821 if (initiator == MAC_RECIPIENT_DELBA) {
822 hmac_ba_reset_rx_handle(&hmac_user->ast_tid_info[tidno].ba_rx_info, tidno);
823 } else {
824 hmac_ba_reset_tx_handle(&hmac_user->ast_tid_info[tidno].ba_tx_info);
825
826 /* 还原设置AMPDU下AMSDU的支持情况 */
827 hmac_user_set_amsdu_support(hmac_user, tidno);
828 }
829
830 return HI_SUCCESS;
831 }
832
833 /* ****************************************************************************
834 功能描述 : 发送DELBA处理接口
835 修改历史 :
836 1.日 期 : 2013年4月14日
837 作 者 : HiSilicon
838 修改内容 : 新生成函数
839 **************************************************************************** */
hmac_mgmt_tx_delba(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const mac_action_mgmt_args_stru * action_args)840 hi_u32 hmac_mgmt_tx_delba(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
841 const mac_action_mgmt_args_stru *action_args)
842 {
843 dmac_ctx_action_event_stru wlan_ctx_action = { 0 };
844 mac_vap_stru *mac_vap = hmac_vap->base_vap;
845
846 /* 需确定vap处于工作状态 */
847 if (mac_vap->vap_state == MAC_VAP_STATE_BUTT) {
848 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba::vap_state[%d]Err}", mac_vap->vap_state);
849 return HI_FAIL;
850 }
851
852 mac_delba_initiator_enum_uint8 initiator = (mac_delba_initiator_enum_uint8)(action_args->arg2);
853 hi_u8 tidno = (hi_u8)(action_args->arg1);
854 if (tidno >= WLAN_TID_MAX_NUM) {
855 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba: tid=[%d] invalid tid num!.}", tidno);
856 return HI_FAIL;
857 }
858
859 /* 睡眠唤醒后,dmac删除delba失败,再次删除时将无法发送。需将此条件去掉。 */
860 if ((initiator == MAC_ORIGINATOR_DELBA) && (hmac_user->ast_tid_info[tidno].ba_tx_info == HI_NULL)) {
861 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba:tid=%d ba_tx_info null}", action_args->arg1);
862 }
863
864 /* 申请DEL_BA管理帧内存 */
865 oal_netbuf_stru *delba = oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
866 if (delba == HI_NULL) {
867 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_delba::pst_delba null.}");
868 return HI_ERR_CODE_PTR_NULL;
869 }
870
871 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化 */
872 memset_s(oal_netbuf_cb(delba), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
873
874 /* 调用封装管理帧接口 */
875 hi_u16 us_frame_len = hmac_mgmt_encap_delba(hmac_vap, (hi_u8 *)oal_netbuf_header(delba), action_args);
876 if (us_frame_len == 0) {
877 oal_netbuf_free(delba);
878 return HI_FAIL;
879 }
880
881 wlan_ctx_action.us_frame_len = us_frame_len;
882 wlan_ctx_action.hdr_len = MAC_80211_FRAME_LEN;
883 wlan_ctx_action.action_category = MAC_ACTION_CATEGORY_BA;
884 wlan_ctx_action.action = MAC_BA_ACTION_DELBA;
885 wlan_ctx_action.user_idx = (hi_u8)hmac_user->base_user->us_assoc_id;
886 wlan_ctx_action.tidno = tidno;
887 wlan_ctx_action.initiator = initiator;
888
889 if (memcpy_s((hi_u8 *)(oal_netbuf_data(delba) + us_frame_len), sizeof(dmac_ctx_action_event_stru),
890 (hi_u8 *)&wlan_ctx_action, sizeof(dmac_ctx_action_event_stru)) != EOK) {
891 oal_netbuf_free(delba);
892 oam_error_log0(0, OAM_SF_CFG, "hmac_mgmt_tx_delba:: st_wlan_ctx_action memcpy_s fail.");
893 return HI_FAIL;
894 }
895 oal_netbuf_put(delba, (us_frame_len + sizeof(dmac_ctx_action_event_stru)));
896
897 hi_u32 ret = hmac_mgmt_tx_delba_send_event(hmac_user, action_args, mac_vap, delba, us_frame_len);
898 return ret;
899 }
900
901 /* ****************************************************************************
902 功能描述 : 从空口接收BA相关帧的处理函数
903 修改历史 :
904 1.日 期 : 2013年4月14日
905 作 者 : HiSilicon
906 修改内容 : 新生成函数
907 **************************************************************************** */
hmac_mgmt_rx_action_ba(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const hi_u8 * puc_data)908 hi_void hmac_mgmt_rx_action_ba(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, const hi_u8 *puc_data)
909 {
910 switch (puc_data[MAC_ACTION_OFFSET_ACTION]) {
911 case MAC_BA_ACTION_ADDBA_REQ:
912 hmac_mgmt_rx_addba_req(hmac_vap, hmac_user, puc_data);
913 break;
914
915 case MAC_BA_ACTION_ADDBA_RSP:
916 hmac_mgmt_rx_addba_rsp(hmac_vap, hmac_user, puc_data);
917 break;
918
919 case MAC_BA_ACTION_DELBA:
920 hmac_mgmt_rx_delba(hmac_vap, hmac_user, puc_data);
921 break;
922
923 default:
924 break;
925 }
926 }
927
hmac_mgmt_rx_addba_req_init(const hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,const hi_u8 * puc_payload,hmac_ba_rx_stru * ba_rx_stru,hi_u8 tid)928 static hi_void hmac_mgmt_rx_addba_req_init(const hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user,
929 const hi_u8 *puc_payload, hmac_ba_rx_stru *ba_rx_stru, hi_u8 tid)
930 {
931 hi_u8 reorder_index;
932 hi_u16 aus_rx_timeout[WLAN_WME_AC_BUTT] = {HMAC_BA_RX_BE_TIMEOUT, HMAC_BA_RX_BK_TIMEOUT,
933 HMAC_BA_RX_VI_TIMEOUT, HMAC_BA_RX_VO_TIMEOUT};
934
935 /* 内存已清0 置0操作可省去 */
936 /* ba_status置DMAC_BA_INIT */
937 ba_rx_stru->dialog_token = puc_payload[2]; /* 2 元素索引 */
938
939 /* 初始化reorder队列 */
940 for (reorder_index = 0; reorder_index < WLAN_AMPDU_RX_BUFFER_SIZE; reorder_index++) {
941 /* in_use seq_num num_buf清0 */
942 oal_netbuf_list_head_init(&(ba_rx_stru->ast_re_order_list[reorder_index].netbuf_head));
943 }
944
945 /* 初始化接收窗口 */
946 ba_rx_stru->us_baw_start = (puc_payload[7] >> 4) | (puc_payload[8] << 4); /* 7 8 元素索引 4 移动位数 */
947 ba_rx_stru->us_baw_size = (puc_payload[3] & 0xC0) >> 6; /* 3 元素索引 右移6位 */
948 ba_rx_stru->us_baw_size |= (puc_payload[4] << 2); /* 4 元素索引 左移2位 */
949 if ((ba_rx_stru->us_baw_size == 0) || (ba_rx_stru->us_baw_size > WLAN_AMPDU_RX_BUFFER_SIZE)) {
950 ba_rx_stru->us_baw_size = WLAN_AMPDU_RX_BUFFER_SIZE;
951 }
952
953 if (ba_rx_stru->us_baw_size == 1) {
954 ba_rx_stru->us_baw_size = WLAN_AMPDU_RX_BUFFER_SIZE;
955 }
956
957 ba_rx_stru->us_baw_end = dmac_ba_seq_add(ba_rx_stru->us_baw_start, (ba_rx_stru->us_baw_size - 1));
958 ba_rx_stru->us_baw_tail = dmac_ba_seqno_sub(ba_rx_stru->us_baw_start, 1);
959 ba_rx_stru->us_baw_head = dmac_ba_seqno_sub(ba_rx_stru->us_baw_start, HMAC_BA_BMP_SIZE);
960 /* mpdu_cnt置0 */
961 ba_rx_stru->is_ba = HI_TRUE; /* Ba session is processing */
962 /* 初始化定时器资源 */
963 ba_rx_stru->alarm_data.ba = ba_rx_stru;
964 ba_rx_stru->alarm_data.vap_id = hmac_vap->base_vap->vap_id;
965 ba_rx_stru->alarm_data.tid = tid; /* 其余参数timeout_times timer_triggered清0 */
966 /* Ba会话参数初始化 */
967 ba_rx_stru->us_ba_timeout = puc_payload[5] | (puc_payload[6] << 8); /* 5 6 元素索引 左移8位 */
968 ba_rx_stru->amsdu_supp = hmac_vap->amsdu_ampdu_active;
969 ba_rx_stru->back_var = MAC_BACK_COMPRESSED;
970 ba_rx_stru->puc_transmit_addr = hmac_user->base_user->user_mac_addr;
971 ba_rx_stru->ba_policy = (puc_payload[3] & 0x02) >> 1; /* 3 元素索引 */
972
973 frw_timer_create_timer(&(ba_rx_stru->ba_timer), hmac_ba_timeout_fn, aus_rx_timeout[wlan_wme_tid_to_ac(tid)],
974 &(ba_rx_stru->alarm_data), HI_FALSE);
975 }
976
977 /* ****************************************************************************
978 功能描述 : 从空口接收ADDBA_REQ帧的处理函数
979 修改历史 :
980 1.日 期 : 2013年4月14日
981 作 者 : HiSilicon
982 修改内容 : 新生成函数
983
984 2.日 期 : 2014年12月3日
985 作 者 : HiSilicon
986 修改内容 : 将Reorder队列相关信息移植Hmac
987 **************************************************************************** */
hmac_mgmt_rx_addba_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const hi_u8 * puc_payload)988 hi_u32 hmac_mgmt_rx_addba_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, const hi_u8 *puc_payload)
989 {
990 hmac_device_stru *hmac_dev = hmac_get_device_stru();
991
992 if (puc_payload == HI_NULL) {
993 oam_error_log0(0, OAM_SF_BA, "{hmac_mgmt_rx_addba_req::addba req receive failed, null param.}");
994 return HI_ERR_CODE_PTR_NULL;
995 }
996
997 mac_vap_stru *mac_vap = hmac_vap->base_vap;
998
999 /* 11n以上能力才可接收ampdu */
1000 if ((!(mac_vap->protocol >= WLAN_HT_MODE)) || (!(hmac_user->base_user->protocol_mode >= WLAN_HT_MODE))) {
1001 oam_warning_log2(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_req::protocol mode=%d,user protocol mode=%d}",
1002 mac_vap->protocol, hmac_user->base_user->protocol_mode);
1003 return HI_SUCCESS;
1004 }
1005
1006 /* **************************************************************** */
1007 /* ADDBA Request Frame - Frame Body */
1008 /* --------------------------------------------------------------- */
1009 /* | Category | Action | Dialog | Parameters | Timeout | SSN | */
1010 /* --------------------------------------------------------------- */
1011 /* | 1 | 1 | 1 | 2 | 2 | 2 | */
1012 /* --------------------------------------------------------------- */
1013 /* */
1014 /* **************************************************************** */
1015 hi_u8 tid = (puc_payload[3] & 0x3C) >> 2; /* 3 元素索引 右移2位 */
1016 if (tid >= WLAN_TID_MAX_NUM) {
1017 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_req::addba req receive failed, tid %d}", tid);
1018 return HI_ERR_CODE_ARRAY_OVERFLOW;
1019 }
1020
1021 if (hmac_user->ast_tid_info[tid].ba_rx_info != HI_NULL) {
1022 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_req::addba req received, but tid [%d]}", tid);
1023 hmac_ba_reset_rx_handle(&hmac_user->ast_tid_info[tid].ba_rx_info, tid);
1024 }
1025
1026 hmac_user->ast_tid_info[tid].ba_rx_info =
1027 (hmac_ba_rx_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, (hi_u16)sizeof(hmac_ba_rx_stru));
1028 if (hmac_user->ast_tid_info[tid].ba_rx_info == HI_NULL) {
1029 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_req: ba_rx_hdl mem alloc fail.tid %d}", tid);
1030 return HI_ERR_CODE_PTR_NULL;
1031 }
1032
1033 hmac_ba_rx_stru *ba_rx_stru = hmac_user->ast_tid_info[tid].ba_rx_info;
1034 if (memset_s(ba_rx_stru, sizeof(hmac_ba_rx_stru), 0, sizeof(hmac_ba_rx_stru)) != EOK) { /* 内存清0 */
1035 return HI_FAIL;
1036 }
1037
1038 oal_spin_lock_init(&ba_rx_stru->st_ba_lock);
1039 hmac_mgmt_rx_addba_req_init(hmac_vap, hmac_user, puc_payload, ba_rx_stru, tid);
1040
1041 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
1042 hmac_vap->rx_ba_session_num++;
1043 #else
1044 hmac_dev->rx_ba_session_num++;
1045 #endif
1046
1047 /* 判断建立能否成功 */
1048 hi_u8 status = hmac_mgmt_check_set_rx_ba_ok(hmac_vap, ba_rx_stru, hmac_dev);
1049 if (status == MAC_SUCCESSFUL_STATUSCODE) {
1050 hmac_user->ast_tid_info[tid].ba_rx_info->ba_status = DMAC_BA_INPROGRESS;
1051 }
1052
1053 hi_u32 ret = hmac_mgmt_tx_addba_rsp(hmac_vap, hmac_user, ba_rx_stru, tid, status);
1054
1055 oam_warning_log4(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_req:tid %d,status %d,baw_start %d,baw_size %d}\n",
1056 tid, status, ba_rx_stru->us_baw_start, ba_rx_stru->us_baw_size);
1057
1058 if ((status != MAC_SUCCESSFUL_STATUSCODE) || (ret != HI_SUCCESS)) {
1059 /* pst_hmac_user->ast_tid_info[uc_tid].pst_ba_rx_info修改为在函数中置空,与其他
1060 调用一致 */
1061 hmac_ba_reset_rx_handle(&hmac_user->ast_tid_info[tid].ba_rx_info, tid);
1062 }
1063
1064 return HI_SUCCESS;
1065 }
1066
hmac_mgmt_rx_addba_rsp_send_event(const hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const hi_u8 * puc_payload,hmac_tid_stru * tid,hi_u8 tidno)1067 hi_u32 hmac_mgmt_rx_addba_rsp_send_event(const hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
1068 const hi_u8 *puc_payload, hmac_tid_stru *tid, hi_u8 tidno)
1069 {
1070 mac_vap_stru *mac_vap = hmac_vap->base_vap;
1071 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_ctx_action_event_stru));
1072
1073 if (event_mem == HI_NULL) {
1074 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_rsp::event_mem null}");
1075 return HI_ERR_CODE_PTR_NULL;
1076 }
1077
1078 /* 获得事件指针 */
1079 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
1080
1081 /* 填写事件头 */
1082 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_BA_SYNC,
1083 sizeof(dmac_ctx_action_event_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
1084
1085 /* 获取帧体信息,由于DMAC的同步,填写事件payload */
1086 dmac_ctx_action_event_stru *rx_addba_rsp_event = (dmac_ctx_action_event_stru *)(event->auc_event_data);
1087 rx_addba_rsp_event->action_category = MAC_ACTION_CATEGORY_BA;
1088 rx_addba_rsp_event->action = MAC_BA_ACTION_ADDBA_RSP;
1089 rx_addba_rsp_event->user_idx = (hi_u8)hmac_user->base_user->us_assoc_id;
1090 rx_addba_rsp_event->stauts = puc_payload[3]; /* 3 元素索引 */
1091 rx_addba_rsp_event->tidno = tidno;
1092 rx_addba_rsp_event->dialog_token = puc_payload[2]; /* 2 元素索引 */
1093
1094 if (rx_addba_rsp_event->stauts != MAC_SUCCESSFUL_STATUSCODE) {
1095 /* 重置HMAC模块信息 */
1096 hmac_ba_reset_tx_handle(&tid->ba_tx_info);
1097 } else {
1098 /* 只有状态为成功时,才有必要将这些信息传递给dmac */
1099 rx_addba_rsp_event->ba_policy = ((puc_payload[5] & 0x02) >> 1); /* 5 元素索引 */
1100 rx_addba_rsp_event->us_ba_timeout = puc_payload[7] | (puc_payload[8] << 8); /* 7 8 元素索引 左移8位 */
1101 rx_addba_rsp_event->amsdu_supp = puc_payload[5] & BIT0; /* 5 元素索引 */
1102
1103 hi_u16 us_baw_size = (hi_u16)(((puc_payload[5] & 0xC0) >> 6) | (puc_payload[6] << 2)); /* 5 6 索引 左移2位 */
1104 hi_u8 ampdu_max_num = (hi_u8)us_baw_size / WLAN_AMPDU_TX_SCHD_STRATEGY;
1105
1106 rx_addba_rsp_event->ampdu_max_num = oal_max(ampdu_max_num, 1);
1107 rx_addba_rsp_event->us_baw_size = us_baw_size;
1108
1109 /* 设置hmac模块对应的BA句柄的信息 */
1110 tid->ba_tx_info->ba_status = DMAC_BA_COMPLETE;
1111 tid->tx_ba_attemps = 0;
1112 if (rx_addba_rsp_event->amsdu_supp && hmac_vap->amsdu_ampdu_active) {
1113 hmac_user_set_amsdu_support(hmac_user, tidno);
1114 } else {
1115 /* 下面宏函数中包含的~操作符表达式中所有变量都是无符号数,误报告警,lin_t e502告警屏蔽 */
1116 hmac_user_set_amsdu_not_support(hmac_user, tidno);
1117 }
1118 }
1119
1120 hcc_hmac_tx_control_event(event_mem, sizeof(dmac_ctx_action_event_stru));
1121
1122 /* 释放事件内存 */
1123 frw_event_free(event_mem);
1124
1125 return HI_SUCCESS;
1126 }
1127
1128 /* ****************************************************************************
1129 功能描述 : 从空口接收ADDBA_RSP帧的处理函数
1130 修改历史 :
1131 1.日 期 : 2013年4月14日
1132 作 者 : HiSilicon
1133 修改内容 : 新生成函数
1134 **************************************************************************** */
hmac_mgmt_rx_addba_rsp(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const hi_u8 * puc_payload)1135 hi_u32 hmac_mgmt_rx_addba_rsp(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, const hi_u8 *puc_payload)
1136 {
1137 mac_action_mgmt_args_stru action_args;
1138
1139 if ((hmac_vap == HI_NULL) || (hmac_user == HI_NULL) || (puc_payload == HI_NULL)) {
1140 oam_error_log3(0, OAM_SF_BA, "{hmac_mgmt_rx_addba_rsp::null param, %p %p %p.}", (uintptr_t)hmac_vap,
1141 (uintptr_t)hmac_user, (uintptr_t)puc_payload);
1142 return HI_ERR_CODE_PTR_NULL;
1143 }
1144
1145 mac_vap_stru *mac_vap = hmac_vap->base_vap;
1146 hi_unref_param(mac_vap);
1147 /* **************************************************************** */
1148 /* ADDBA Response Frame - Frame Body */
1149 /* --------------------------------------------------------------- */
1150 /* | Category | Action | Dialog | Status | Parameters | Timeout | */
1151 /* --------------------------------------------------------------- */
1152 /* | 1 | 1 | 1 | 2 | 2 | 2 | */
1153 /* --------------------------------------------------------------- */
1154 /* */
1155 /* **************************************************************** */
1156 hi_u8 tidno = (puc_payload[5] & 0x3C) >> 2; /* 5: 元素下标 2: 右移两位 */
1157 /* 协议支持tid为0~15,02只支持tid0~7 */
1158 if (tidno >= WLAN_TID_MAX_NUM) {
1159 /* 对于tid > 7的resp直接忽略 */
1160 oam_warning_log3(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_rsp::addba rsp tid[%d]} token[%d] state[%d]",
1161 tidno, puc_payload[2], /* 2 元素索引 */
1162 puc_payload[3]); /* 3 元素索引 */
1163 return HI_SUCCESS;
1164 }
1165
1166 hmac_tid_stru *tid = &(hmac_user->ast_tid_info[tidno]);
1167 hi_u8 dialog_token = puc_payload[2]; /* 2 元素索引 */
1168
1169 if (tid->ba_tx_info == HI_NULL) {
1170 /* 发送DELBA帧 */
1171 action_args.category = MAC_ACTION_CATEGORY_BA;
1172 action_args.action = MAC_BA_ACTION_DELBA;
1173 action_args.arg1 = tidno; /* 该数据帧对应的TID号 */
1174 action_args.arg2 = MAC_ORIGINATOR_DELBA; /* DELBA中,触发删除BA会话的发起端 */
1175 action_args.arg3 = MAC_UNSPEC_QOS_REASON; /* DELBA中代表删除reason */
1176 action_args.puc_arg5 = hmac_user->base_user->user_mac_addr; /* DELBA中代表目的地址 */
1177
1178 if (hmac_mgmt_tx_delba(hmac_vap, hmac_user, &action_args) != HI_SUCCESS) {
1179 oam_warning_log0(mac_vap->vap_id, OAM_SF_BA, "hmac_mgmt_tx_delba return NON SUCCESS. ");
1180 }
1181
1182 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_addba_rsp::tx ba info null.tid[%d]}", tidno);
1183 return HI_SUCCESS;
1184 }
1185
1186 if ((tid->ba_tx_info->ba_status == DMAC_BA_COMPLETE) || (dialog_token != tid->ba_tx_info->dialog_token)) {
1187 oam_warning_log4(mac_vap->vap_id, OAM_SF_BA,
1188 "{hmac_mgmt_rx_addba_rsp::status ialog_token wrong.tid %d, status %d, rsp dialog %d, req dialog %d}",
1189 tidno, tid->ba_tx_info->ba_status, dialog_token, tid->ba_tx_info->dialog_token);
1190 return HI_SUCCESS;
1191 }
1192 /* 停止计时器 */
1193 frw_timer_immediate_destroy_timer(&(tid->ba_tx_info->addba_timer));
1194
1195 /* 抛事件到DMAC处理 */
1196 hi_u32 ret = hmac_mgmt_rx_addba_rsp_send_event(hmac_vap, hmac_user, puc_payload, tid, tidno);
1197 return ret;
1198 }
1199
1200 /* ****************************************************************************
1201 功能描述 : 从空口接收DEL_BA帧的处理函数
1202 修改历史 :
1203 1.日 期 : 2013年4月14日
1204 作 者 : HiSilicon
1205 修改内容 : 新生成函数
1206 **************************************************************************** */
hmac_mgmt_rx_delba(const hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const hi_u8 * puc_payload)1207 hi_u32 hmac_mgmt_rx_delba(const hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, const hi_u8 *puc_payload)
1208 {
1209 if (oal_unlikely(puc_payload == HI_NULL)) {
1210 oam_error_log1(0, OAM_SF_BA, "{hmac_mgmt_rx_delba::null param, %p.}", (uintptr_t)puc_payload);
1211 return HI_ERR_CODE_PTR_NULL;
1212 }
1213
1214 /* ********************************************** */
1215 /* DELBA Response Frame - Frame Body */
1216 /* -------------------------------------------- */
1217 /* | Category | Action | Parameters | Reason | */
1218 /* -------------------------------------------- */
1219 /* | 1 | 1 | 2 | 2 | */
1220 /* -------------------------------------------- */
1221 /* */
1222 /************************************************/
1223 hi_u8 tid_value = (puc_payload[3] & 0xF0) >> 4; /* 3 元素索引 右移4位 */
1224 hi_u8 initiator = (puc_payload[3] & 0x08) >> 3; /* 3 元素索引 右移3位 */
1225 hi_u16 us_reason = (puc_payload[4] & 0xFF) | ((puc_payload[5] << 8) & 0xFF00); /* 4 5 元素索引 左移8位 */
1226
1227 /* tid保护,避免数组越界 */
1228 if (tid_value >= WLAN_TID_MAX_NUM) {
1229 oam_warning_log1(0, OAM_SF_BA, "{hmac_mgmt_rx_delba::delba receive failed, tid %d overflow.}", tid_value);
1230 return HI_ERR_CODE_ARRAY_OVERFLOW;
1231 }
1232
1233 hmac_tid_stru *tid = &(hmac_user->ast_tid_info[tid_value]);
1234 hi_unref_param(us_reason); /* 用于解决关闭维测后的编译告警问题 */
1235 oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_BA,
1236 "{hmac_mgmt_rx_delba::receive delba from peer sta, tid[%d], uc_initiator[%d], reason[%d].}", tid_value,
1237 initiator, us_reason);
1238 /* 重置BA发送会话 */
1239 if (initiator == MAC_RECIPIENT_DELBA) {
1240 if (tid->ba_tx_info == HI_NULL) {
1241 return HI_SUCCESS;
1242 }
1243 tid->ba_flag = 0;
1244 /* 还原设置AMPDU下AMSDU的支持情况 */
1245 hmac_user_set_amsdu_support(hmac_user, tid_value);
1246 hmac_ba_reset_tx_handle(&tid->ba_tx_info);
1247 } else { /* 重置BA接收会话 */
1248 if (tid->ba_rx_info == HI_NULL) {
1249 return HI_SUCCESS;
1250 }
1251 hmac_ba_reset_rx_handle(&tid->ba_rx_info, tid_value);
1252 }
1253
1254 /* 抛事件到DMAC处理 */
1255 /* 申请事件返回的内存指针 */
1256 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(dmac_ctx_action_event_stru));
1257 if ((event_mem == HI_NULL) || (event_mem->puc_data == HI_NULL)) {
1258 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA, "{hmac_mgmt_rx_delba::event_mem null.}");
1259 return HI_ERR_CODE_PTR_NULL;
1260 }
1261
1262 /* 获得事件指针 */
1263 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
1264
1265 /* 填写事件头 */
1266 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_BA_SYNC,
1267 sizeof(dmac_ctx_action_event_stru), FRW_EVENT_PIPELINE_STAGE_1, hmac_vap->base_vap->vap_id);
1268
1269 /* 填写事件payload */
1270 dmac_ctx_action_event_stru *wlan_crx_action = (dmac_ctx_action_event_stru *)(event->auc_event_data);
1271 wlan_crx_action->action_category = MAC_ACTION_CATEGORY_BA;
1272 wlan_crx_action->action = MAC_BA_ACTION_DELBA;
1273 wlan_crx_action->user_idx = (hi_u8)hmac_user->base_user->us_assoc_id;
1274 wlan_crx_action->tidno = tid_value;
1275 wlan_crx_action->initiator = initiator;
1276 hcc_hmac_tx_control_event(event_mem, sizeof(dmac_ctx_action_event_stru));
1277 /* 释放事件内存 */
1278 frw_event_free(event_mem);
1279 return HI_SUCCESS;
1280 }
1281
1282 /* ****************************************************************************
1283 功能描述 : 发送ADDBA req帧超时处理
1284 修改历史 :
1285 1.日 期 : 2013年4月22日
1286 作 者 : HiSilicon
1287 修改内容 : 新生成函数
1288 **************************************************************************** */
hmac_mgmt_tx_addba_timeout(hi_void * arg)1289 hi_u32 hmac_mgmt_tx_addba_timeout(hi_void *arg)
1290 {
1291 hmac_vap_stru *hmac_vap = HI_NULL; /* vap指针 */
1292 hi_u8 *da_mac_addr = HI_NULL; /* 保存用户目的地址的指针 */
1293 hmac_user_stru *hmac_user = HI_NULL;
1294 mac_action_mgmt_args_stru action_args;
1295 dmac_ba_alarm_stru *alarm_data = HI_NULL;
1296 hi_u32 ret;
1297
1298 if (arg == HI_NULL) {
1299 oam_error_log0(0, OAM_SF_BA, "{hmac_mgmt_tx_addba_timeout::p_arg null.}");
1300 return HI_ERR_CODE_PTR_NULL;
1301 }
1302
1303 alarm_data = (dmac_ba_alarm_stru *)arg;
1304 hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(alarm_data->mac_user_idx);
1305 if ((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL)) {
1306 oam_error_log0(0, OAM_SF_BA, "{hmac_mgmt_tx_addba_timeout::pst_hmac_user null.}");
1307 return HI_ERR_CODE_PTR_NULL;
1308 }
1309
1310 da_mac_addr = hmac_user->base_user->user_mac_addr;
1311
1312 hmac_vap = hmac_vap_get_vap_stru(alarm_data->vap_id);
1313 if (oal_unlikely(hmac_vap == HI_NULL)) {
1314 oam_error_log0(hmac_user->base_user->vap_id, OAM_SF_BA, "{hmac_mgmt_tx_addba_timeout::pst_hmac_user null.}");
1315 return HI_ERR_CODE_PTR_NULL;
1316 }
1317
1318 /* 生成DELBA帧 */
1319 action_args.category = MAC_ACTION_CATEGORY_BA;
1320 action_args.action = MAC_BA_ACTION_DELBA;
1321 action_args.arg1 = alarm_data->tid; /* 该数据帧对应的TID号 */
1322 action_args.arg2 = MAC_ORIGINATOR_DELBA; /* DELBA中,触发删除BA会话的发起端 */
1323 action_args.arg3 = MAC_QSTA_TIMEOUT; /* DELBA中代表删除reason */
1324 action_args.puc_arg5 = da_mac_addr; /* DELBA中代表目的地址 */
1325
1326 ret = hmac_mgmt_tx_delba(hmac_vap, hmac_user, &action_args);
1327 if (ret != HI_SUCCESS) {
1328 oam_warning_log0(hmac_user->base_user->vap_id, OAM_SF_BA, "hmac_mgmt_tx_delba return NON SUCCESS. ");
1329 }
1330
1331 return HI_SUCCESS;
1332 }
1333
1334 /* ****************************************************************************
1335 功能描述 : 设置启动AMPDU所需要的参数
1336 修改历史 :
1337 1.日 期 : 2013年4月26日
1338 作 者 : HiSilicon
1339 修改内容 : 新生成函数
1340 **************************************************************************** */
hmac_mgmt_tx_ampdu_start(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_priv_req_args_stru * priv_req)1341 hi_u32 hmac_mgmt_tx_ampdu_start(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, mac_priv_req_args_stru *priv_req)
1342 {
1343 frw_event_mem_stru *event_mem = HI_NULL; /* 申请事件返回的内存指针 */
1344 frw_event_stru *event = HI_NULL;
1345 mac_priv_req_args_stru *rx_ampdu_start_event = HI_NULL;
1346 hi_u8 tidno;
1347 hmac_tid_stru *tid = HI_NULL;
1348 hi_u32 ret;
1349
1350 if ((hmac_vap == HI_NULL) || (hmac_user == HI_NULL) || (priv_req == HI_NULL)) {
1351 oam_error_log3(0, OAM_SF_AMPDU, "{hmac_mgmt_tx_ampdu_start::param null, %p %p %p.}", (uintptr_t)hmac_vap,
1352 (uintptr_t)hmac_user, (uintptr_t)priv_req);
1353 return HI_ERR_CODE_PTR_NULL;
1354 }
1355
1356 tidno = priv_req->arg1;
1357 tid = &(hmac_user->ast_tid_info[tidno]);
1358
1359 /* AMPDU为NORMAL ACK时,对应的BA会话没有建立,则返回 */
1360 if (priv_req->arg3 == WLAN_TX_NORMAL_ACK) {
1361 if (tid->ba_tx_info == HI_NULL) {
1362 return HI_SUCCESS;
1363 }
1364 }
1365
1366 /* 抛事件到DMAC处理 */
1367 event_mem = frw_event_alloc(sizeof(mac_priv_req_args_stru));
1368 if (event_mem == HI_NULL) {
1369 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AMPDU, "{hmac_mgmt_tx_ampdu_start::event_mem null.}");
1370 return HI_ERR_CODE_PTR_NULL;
1371 }
1372
1373 /* 获得事件指针 */
1374 event = (frw_event_stru *)event_mem->puc_data;
1375
1376 /* 填写事件头 */
1377 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_PRIV_REQ,
1378 sizeof(mac_priv_req_args_stru), FRW_EVENT_PIPELINE_STAGE_1, hmac_vap->base_vap->vap_id);
1379
1380 /* 获取设置AMPDU的参数,到dmac进行设置 */
1381 rx_ampdu_start_event = (mac_priv_req_args_stru *)(event->auc_event_data);
1382 rx_ampdu_start_event->type = MAC_A_MPDU_START;
1383 rx_ampdu_start_event->arg1 = priv_req->arg1;
1384 rx_ampdu_start_event->arg2 = priv_req->arg2;
1385 rx_ampdu_start_event->arg3 = priv_req->arg3;
1386 rx_ampdu_start_event->user_idx = (hi_u8)hmac_user->base_user->us_assoc_id; /* 保存的是资源池的索引 */
1387
1388 /* 分发 */
1389 ret = hcc_hmac_tx_control_event(event_mem, sizeof(mac_priv_req_args_stru));
1390
1391 /* 释放事件内存 */
1392 frw_event_free(event_mem);
1393
1394 return ret;
1395 }
1396
1397 /* ****************************************************************************
1398 功能描述 : 设置关闭AMPDU
1399 修改历史 :
1400 1.日 期 : 2013年6月7日
1401 作 者 : HiSilicon
1402 修改内容 : 新生成函数
1403 **************************************************************************** */
hmac_mgmt_tx_ampdu_end(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_priv_req_args_stru * priv_req)1404 hi_u32 hmac_mgmt_tx_ampdu_end(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, mac_priv_req_args_stru *priv_req)
1405 {
1406 frw_event_mem_stru *event_mem = HI_NULL; /* 申请事件返回的内存指针 */
1407 frw_event_stru *event = HI_NULL;
1408 mac_priv_req_args_stru *rx_ampdu_end_event = HI_NULL;
1409 hi_u32 ret;
1410
1411 if ((hmac_vap == HI_NULL) || (hmac_user == HI_NULL) || (priv_req == HI_NULL)) {
1412 oam_error_log3(0, OAM_SF_AMPDU, "{hmac_mgmt_tx_ampdu_end::param null, %p %p %p.}", (uintptr_t)hmac_vap,
1413 (uintptr_t)hmac_user, (uintptr_t)priv_req);
1414 return HI_ERR_CODE_PTR_NULL;
1415 }
1416
1417 /* 抛事件到DMAC处理 */
1418 event_mem = frw_event_alloc(sizeof(mac_priv_req_args_stru));
1419 if (event_mem == HI_NULL) {
1420 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AMPDU, "{hmac_mgmt_tx_ampdu_end::event_mem null.}");
1421 return HI_ERR_CODE_PTR_NULL;
1422 }
1423
1424 /* 获得事件指针 */
1425 event = (frw_event_stru *)event_mem->puc_data;
1426
1427 /* 填写事件头 */
1428 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_PRIV_REQ,
1429 sizeof(mac_priv_req_args_stru), FRW_EVENT_PIPELINE_STAGE_1, hmac_vap->base_vap->vap_id);
1430
1431 /* 获取设置AMPDU的参数,到dmac进行设置 */
1432 rx_ampdu_end_event = (mac_priv_req_args_stru *)(event->auc_event_data);
1433 rx_ampdu_end_event->type = MAC_A_MPDU_END; /* 类型 */
1434 rx_ampdu_end_event->arg1 = priv_req->arg1; /* tid no */
1435 rx_ampdu_end_event->user_idx = (hi_u8)hmac_user->base_user->us_assoc_id; /* 保存的是资源池的索引 */
1436
1437 /* 分发 */
1438 ret = hcc_hmac_tx_control_event(event_mem, sizeof(mac_priv_req_args_stru));
1439
1440 /* 释放事件内存 */
1441 frw_event_free(event_mem);
1442
1443 return ret;
1444 }
1445
1446 /* ****************************************************************************
1447 功能描述 : 发送管理帧抛事件
1448 修改历史 :
1449 1.日 期 : 2013年5月29日
1450 作 者 : HiSilicon
1451 修改内容 : 新生成函数
1452 **************************************************************************** */
hmac_tx_mgmt_send_event(const mac_vap_stru * mac_vap,oal_netbuf_stru * mgmt_frame,hi_u32 us_frame_len)1453 hi_u32 hmac_tx_mgmt_send_event(const mac_vap_stru *mac_vap, oal_netbuf_stru *mgmt_frame, hi_u32 us_frame_len)
1454 {
1455 frw_event_mem_stru *event_mem = HI_NULL;
1456 frw_event_stru *event = HI_NULL;
1457 hi_u32 return_code;
1458 dmac_tx_event_stru *ctx_stru = HI_NULL;
1459
1460 /* 抛事件给DMAC,让DMAC完成配置VAP创建 */
1461 event_mem = frw_event_alloc(sizeof(dmac_tx_event_stru));
1462 if (oal_unlikely(event_mem == HI_NULL)) {
1463 oam_error_log0(mac_vap->vap_id, OAM_SF_SCAN, "{hmac_tx_mgmt_send_event::event_mem null.}");
1464 return HI_ERR_CODE_PTR_NULL;
1465 }
1466
1467 event = (frw_event_stru *)event_mem->puc_data;
1468
1469 /* 填写事件头 */
1470 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_MGMT,
1471 sizeof(dmac_tx_event_stru), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
1472
1473 ctx_stru = (dmac_tx_event_stru *)event->auc_event_data;
1474 ctx_stru->netbuf = mgmt_frame;
1475 ctx_stru->us_frame_len = us_frame_len;
1476
1477 return_code = hcc_hmac_tx_data_event(event_mem, mgmt_frame, HI_TRUE);
1478 if (return_code != HI_SUCCESS) {
1479 oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN,
1480 "{hmac_tx_mgmt_send_event::frw_event_dispatch_event failed[%d].}", return_code);
1481 frw_event_free(event_mem);
1482 return return_code;
1483 }
1484
1485 /* 释放事件 */
1486 frw_event_free(event_mem);
1487
1488 return HI_SUCCESS;
1489 }
1490
1491 /* ****************************************************************************
1492 功能描述 : 收到认证请求 关联请求时 重置用户的节能状态
1493 修改历史 :
1494 1.日 期 : 2014年5月17日
1495 作 者 : HiSilicon
1496 修改内容 : 新生成函数
1497 2.日 期 : 2015年1月26日
1498 作 者 : HiSilicon
1499 修改内容 : 增加keepalive重置
1500 **************************************************************************** */
hmac_mgmt_reset_psm(const mac_vap_stru * mac_vap,hi_u8 user_id)1501 hi_u32 hmac_mgmt_reset_psm(const mac_vap_stru *mac_vap, hi_u8 user_id)
1502 {
1503 frw_event_mem_stru *event_mem = HI_NULL;
1504 frw_event_stru *event = HI_NULL;
1505 hi_u8 *puc_user_id = HI_NULL;
1506 hmac_user_stru *hmac_user = HI_NULL;
1507
1508 /* 在这里直接做重置的一些操作,不需要再次同步 */
1509 hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(user_id);
1510 if (oal_unlikely(mac_vap == HI_NULL || hmac_user == HI_NULL)) {
1511 oam_error_log2(0, OAM_SF_PWR, "{hmac_mgmt_reset_psm::mac_vap/hmac_user null! mac_vap=%p, hmac_user=%p}",
1512 (uintptr_t)mac_vap, (uintptr_t)hmac_user);
1513 return HI_ERR_CODE_PTR_NULL;
1514 }
1515
1516 event_mem = frw_event_alloc(sizeof(hi_u8));
1517 if (oal_unlikely(event_mem == HI_NULL)) {
1518 oam_error_log0(mac_vap->vap_id, OAM_SF_PWR, "{hmac_mgmt_reset_psm::event_mem null.}");
1519 return HI_ERR_CODE_PTR_NULL;
1520 }
1521
1522 event = (frw_event_stru *)event_mem->puc_data;
1523
1524 /* 填写事件头 */
1525 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_RESET_PSM,
1526 sizeof(hi_u16), FRW_EVENT_PIPELINE_STAGE_1, mac_vap->vap_id);
1527
1528 puc_user_id = event->auc_event_data;
1529 *puc_user_id = user_id;
1530 hcc_hmac_tx_control_event(event_mem, sizeof(hi_u16));
1531 frw_event_free(event_mem);
1532
1533 return HI_SUCCESS;
1534 }
1535
1536 #ifdef _PRE_WLAN_FEATURE_OPMODE_NOTIFY
1537 /* ****************************************************************************
1538 功能描述 : 检查Operating Mode字段参数是否合理
1539 输入参数 : pst_mac_user: MAC USER结构体指针
1540 puc_payload : 指向Operating Mode Notification IE的指针
1541 返 回 值 : HI_SUCCESS或其它错误码
1542 修改历史 :
1543 1.日 期 : 2014年6月10日
1544 作 者 : HiSilicon
1545 修改内容 : 新生成函数
1546 **************************************************************************** */
hmac_ie_check_proc_opmode_param(mac_user_stru * mac_user,mac_opmode_notify_stru * opmode_notify)1547 static hi_u32 hmac_ie_check_proc_opmode_param(mac_user_stru *mac_user, mac_opmode_notify_stru *opmode_notify)
1548 {
1549 /* USER新限定带宽、空间流不允许大于其能力 */
1550 if ((mac_user->bandwidth_cap < opmode_notify->channel_width) ||
1551 (mac_user->num_spatial_stream < opmode_notify->rx_nss)) {
1552 oam_warning_log4(mac_user->vap_id, OAM_SF_ANY,
1553 "{hmac_ie_check_proc_opmode_param:: cap over limit! bw_cap=[%d], op_bw=[%d],user_nss=[%d], op_nss=[%d]!}",
1554 mac_user->bandwidth_cap, opmode_notify->channel_width,
1555 mac_user->num_spatial_stream, opmode_notify->rx_nss);
1556 return HI_FAIL;
1557 }
1558
1559 /* Nss Type值为1,则表示beamforming Rx Nss不能超过其声称值 */
1560 if (opmode_notify->rx_nss_type == 1) {
1561 if (mac_user->vht_hdl.vht_cap_info.num_bf_ant_supported < opmode_notify->rx_nss) {
1562 oam_warning_log2(mac_user->vap_id, OAM_SF_ANY,
1563 "{hmac_ie_check_proc_opmode_param::rx_nss over limit!ant_supported = [%d], rx_nss = [%d]!}",
1564 mac_user->vht_hdl.vht_cap_info.num_bf_ant_supported, opmode_notify->rx_nss);
1565 return HI_FAIL;
1566 }
1567 }
1568
1569 return HI_SUCCESS;
1570 }
1571
1572 /* ****************************************************************************
1573 功能描述 : 处理Operating Mode字段
1574 输入参数 : pst_mac_user: MAC USER结构体指针
1575 puc_payload : 指向Operating Mode Notification IE的指针
1576 返 回 值 : HI_SUCCESS或其它错误码
1577 修改历史 :
1578 1.日 期 : 2014年6月10日
1579 作 者 : HiSilicon
1580 修改内容 : 新生成函数
1581 **************************************************************************** */
hmac_ie_proc_opmode_field(mac_vap_stru * mac_vap,mac_user_stru * mac_user,mac_opmode_notify_stru * opmode_notify,hi_u8 mgmt_frm_type)1582 hi_u32 hmac_ie_proc_opmode_field(mac_vap_stru *mac_vap, mac_user_stru *mac_user, mac_opmode_notify_stru *opmode_notify,
1583 hi_u8 mgmt_frm_type)
1584 {
1585 wlan_bw_cap_enum_uint8 bwcap_vap = 0; /* vap自身带宽能力 */
1586 wlan_bw_cap_enum_uint8 avail_bw; /* vap自身带宽能力 */
1587
1588 if (oal_unlikely((mac_user == HI_NULL) || (opmode_notify == HI_NULL) || (mac_vap == HI_NULL))) {
1589 oam_error_log3(0, OAM_SF_ANY,
1590 "{hmac_ie_proc_opmode_field::pst_mac_user = [%x], pst_opmode_notify = [%x], pst_mac_vap = [%x]!}\r\n",
1591 mac_user, opmode_notify, mac_vap);
1592 return HI_ERR_CODE_PTR_NULL;
1593 }
1594
1595 if (HI_FAIL == hmac_ie_check_proc_opmode_param(mac_user, opmode_notify)) {
1596 oam_warning_log0(mac_user->vap_id, OAM_SF_ANY,
1597 "{hmac_ie_proc_opmode_field::hmac_ie_check_proc_opmode_param return fail!}\r\n");
1598 return HI_FAIL;
1599 }
1600
1601 /* 判断Rx Nss Type是否为beamforming模式 */
1602 if (opmode_notify->rx_nss_type == 1) {
1603 oam_info_log0(mac_vap->vap_id, OAM_SF_ANY,
1604 "{hmac_ie_proc_opmode_field::pst_opmode_notify->bit_rx_nss_type == 1!}\r\n");
1605
1606 /* 判断Rx Nss是否与user之前使用Rx Nss相同 */
1607 if (opmode_notify->rx_nss != mac_user->avail_bf_num_spatial_stream) {
1608 mac_user_avail_bf_num_spatial_stream(mac_user, opmode_notify->rx_nss);
1609 }
1610
1611 return HI_SUCCESS;
1612 }
1613
1614 /* 判断Rx Nss是否与user之前使用Rx Nss相同 */
1615 if (opmode_notify->rx_nss != mac_user->avail_num_spatial_stream) {
1616 oam_info_log2(mac_vap->vap_id, OAM_SF_ANY,
1617 "{hmac_ie_proc_opmode_field::opmode rx_nss = [%x], mac_user avail_num_spatial_stream = [%x]!}",
1618 opmode_notify->rx_nss, mac_user->avail_num_spatial_stream);
1619 /* 与AP的能力取交集 */
1620 mac_user_set_avail_num_spatial_stream(mac_user, oal_min(mac_vap->vap_rx_nss, opmode_notify->rx_nss));
1621
1622 oam_info_log2(mac_vap->vap_id, OAM_SF_ANY,
1623 "{hmac_ie_proc_opmode_field::change nss. mac_vap rx_nss=[%x], mac_user avail_num_spatial_stream=[%x]!}",
1624 mac_vap->vap_rx_nss, mac_user->avail_num_spatial_stream);
1625 }
1626
1627 /* 判断channel_width是否与user之前使用channel_width相同 */
1628 if (opmode_notify->channel_width != mac_user->avail_bandwidth) {
1629 oam_info_log2(mac_vap->vap_id, OAM_SF_ANY,
1630 "{hmac_ie_proc_opmode_field:: opmode channel_width = [%x], mac_user avail_bandwidth = [%x]!}",
1631 opmode_notify->channel_width, mac_user->avail_bandwidth);
1632
1633 /* 获取vap带宽能力与用户带宽能力的交集 */
1634 mac_vap_get_bandwidth_cap(mac_vap, &bwcap_vap);
1635
1636 avail_bw = oal_min(bwcap_vap, opmode_notify->channel_width);
1637 mac_user_set_bandwidth_info(mac_user, avail_bw, avail_bw);
1638
1639 oam_info_log2(mac_vap->vap_id, OAM_SF_ANY,
1640 "{hmac_ie_proc_opmode_field::change bandwidth. bwcap_vap = [%x], mac_user avail_bandwidth = [%x]!}",
1641 bwcap_vap, mac_user->avail_bandwidth);
1642 }
1643
1644 return HI_SUCCESS;
1645 }
1646 #endif
1647
1648 #ifdef _PRE_WLAN_FEATURE_PMF
1649 /* ****************************************************************************
1650 功能描述 : 开始SA Query timer1超时删除user
1651 输入参数 : pst_mac_vap:挂此user的vap
1652 puc_addr:需要删除的user mac地址
1653 返 回 值 : HI_SUCCESS:删除用户成功
1654 修改历史 :
1655 1.日 期 : 2014年4月21日
1656 作 者 : HiSilicon
1657 修改内容 : 新生成函数
1658 **************************************************************************** */
hmac_sa_query_del_user(mac_vap_stru * mac_vap,hmac_user_stru * hmac_user)1659 static hi_u32 hmac_sa_query_del_user(mac_vap_stru *mac_vap, hmac_user_stru *hmac_user)
1660 {
1661 wlan_vap_mode_enum_uint8 vap_mode;
1662 hmac_vap_stru *hmac_vap = HI_NULL;
1663 hi_u32 ret;
1664 mac_sa_query_stru *sa_query_info = HI_NULL;
1665
1666 if ((mac_vap == HI_NULL) || (hmac_user == HI_NULL)) {
1667 oam_error_log2(0, OAM_SF_PMF, "{hmac_sa_query_del_user::param null, %p %p.}", (uintptr_t)mac_vap,
1668 (uintptr_t)hmac_user);
1669 return HI_ERR_CODE_PTR_NULL;
1670 }
1671
1672 hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
1673 if (hmac_vap == HI_NULL) {
1674 oam_error_log0(0, OAM_SF_PMF, "{hmac_sa_query_del_user::pst_hmac_vap null.}");
1675 return HI_ERR_CODE_PTR_NULL;
1676 }
1677
1678 /* pending SA Query requests 计数器清零 & sa query流程开始时间清零 */
1679 sa_query_info = &hmac_user->sa_query_info;
1680 sa_query_info->us_sa_query_count = 0;
1681 sa_query_info->sa_query_start_time = 0;
1682
1683 /* 修改 state & 删除 user */
1684 vap_mode = mac_vap->vap_mode;
1685 switch (vap_mode) {
1686 #ifdef _PRE_WLAN_FEATURE_MESH
1687 case WLAN_VAP_MODE_MESH:
1688 #endif
1689 case WLAN_VAP_MODE_BSS_AP: {
1690 /* 抛事件上报内核,已经去关联某个STA */
1691 hmac_handle_disconnect_rsp_ap(hmac_vap, hmac_user);
1692 } break;
1693
1694 case WLAN_VAP_MODE_BSS_STA: {
1695 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
1696
1697 /* 上报内核sta已经和某个ap去关联 */
1698 /* hmac_sa_query_del_user, dmac_reason_code is 7 */
1699 hmac_sta_disassoc_rsp(hmac_vap, HMAC_REPORT_ACTION, DMAC_DISASOC_SA_QUERY_DEL_USER);
1700 } break;
1701 default:
1702 break;
1703 }
1704
1705 /* 删除user */
1706 ret = hmac_user_del(hmac_vap->base_vap, hmac_user);
1707 if (ret != HI_SUCCESS) {
1708 oam_error_log1(0, OAM_SF_PMF, "{hmac_sa_query_del_user::hmac_user_del failed[%d].}", ret);
1709 return HI_FAIL;
1710 }
1711 return HI_SUCCESS;
1712 }
1713
1714 /* ****************************************************************************
1715 功能描述 : hmac_start_sa_query的下级函数,没有设置timer的功能
1716 输入参数 : pst_mac_vap:启动SA查询的mac vap结构体
1717 puc_da:目标user的mac 地址
1718 en_is_protected:SA Query帧的加密标志位
1719 修改历史 :
1720 1.日 期 : 2014年4月21日
1721 作 者 : HiSilicon
1722 修改内容 : 新生成函数
1723 **************************************************************************** */
hmac_send_sa_query_req(mac_vap_stru * mac_vap,hmac_user_stru * hmac_user,hi_u8 is_protected,hi_u16 us_init_trans_id)1724 static hi_u32 hmac_send_sa_query_req(mac_vap_stru *mac_vap, hmac_user_stru *hmac_user, hi_u8 is_protected,
1725 hi_u16 us_init_trans_id)
1726 {
1727 if ((mac_vap == HI_NULL) || (hmac_user == HI_NULL)) {
1728 oam_error_log2(0, OAM_SF_PMF, "{hmac_send_sa_query_req::param null, %p %p.}", (uintptr_t)mac_vap,
1729 (uintptr_t)hmac_user);
1730 return HI_ERR_CODE_PTR_NULL;
1731 }
1732
1733 /* 申请SA Query 帧空间 */
1734 oal_netbuf_stru *sa_query = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
1735 if (sa_query == HI_NULL) {
1736 oam_error_log0(mac_vap->vap_id, OAM_SF_PMF, "{hmac_send_sa_query_req::pst_sa_query null.}");
1737 return HI_ERR_CODE_ALLOC_MEM_FAIL;
1738 }
1739
1740 /* 设置 trans id */
1741 hmac_user->sa_query_info.us_sa_query_trans_id = us_init_trans_id + 1;
1742 /* 更新sa query request计数器 */
1743 hmac_user->sa_query_info.us_sa_query_count += 1;
1744 /* 封装SA Query request帧 */
1745 if (memset_s(oal_netbuf_cb(sa_query), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size()) != EOK) {
1746 oam_warning_log0(mac_vap->vap_id, OAM_SF_PMF, "{hmac_send_sa_query_req::memset_s fail.}");
1747 oal_netbuf_free(sa_query);
1748 return HI_FAIL;
1749 }
1750 hi_u16 sa_query_len = hmac_encap_sa_query_req(mac_vap, (hi_u8 *)oal_netbuf_header(sa_query),
1751 hmac_user->base_user->user_mac_addr, hmac_user->sa_query_info.us_sa_query_trans_id);
1752 if (sa_query_len == 0) {
1753 oam_warning_log0(mac_vap->vap_id, OAM_SF_PMF, "{hmac_send_sa_query_req::sa query len is 0.}");
1754 oal_netbuf_free(sa_query);
1755 return HI_FAIL;
1756 }
1757 /* 单播管理帧加密 */
1758 if (is_protected == HI_TRUE) {
1759 mac_set_protectedframe((hi_u8 *)oal_netbuf_header(sa_query));
1760 }
1761
1762 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(sa_query); /* 获取cb结构体 */
1763 tx_ctl->us_mpdu_len = sa_query_len; /* dmac发送需要的mpdu长度 */
1764 tx_ctl->us_tx_user_idx = MAC_INVALID_USER_ID;
1765 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(sa_query);
1766 tx_ctl->mac_head_type = 1;
1767 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
1768 oal_netbuf_put(sa_query, sa_query_len);
1769
1770 /* Buffer this frame in the Memory Queue for transmission */
1771 hi_u32 ret = hmac_tx_mgmt_send_event(mac_vap, sa_query, sa_query_len);
1772 if (ret != HI_SUCCESS) {
1773 oal_netbuf_free(sa_query);
1774 oam_warning_log1(mac_vap->vap_id, OAM_SF_PMF, "{hmac_send_sa_query_req::hmac_tx_mgmt_send_event failed[%d].}",
1775 ret);
1776 return ret;
1777 }
1778
1779 return HI_SUCCESS;
1780 }
1781
1782 /* ****************************************************************************
1783 功能描述 : 判断是否对收到的去关联去认证帧进行PMF特性的处理
1784 返 回 值 : HI_SUCCESS: 允许进行PMF特性的处理(如开启sa query流程)
1785 修改历史 :
1786 1.日 期 : 2014年6月25日
1787 作 者 : HiSilicon
1788 修改内容 : 新生成函数
1789 **************************************************************************** */
hmac_pmf_check_err_code(const mac_user_stru * user_base_info,hi_u8 is_protected,const hi_u8 * puc_mac_hdr)1790 hi_u32 hmac_pmf_check_err_code(const mac_user_stru *user_base_info, hi_u8 is_protected, const hi_u8 *puc_mac_hdr)
1791 {
1792 hi_u8 aim_err_code;
1793 hi_u16 us_err_code;
1794
1795 us_err_code = hi_makeu16(puc_mac_hdr[MAC_80211_FRAME_LEN], puc_mac_hdr[MAC_80211_FRAME_LEN + 1]);
1796 aim_err_code = ((MAC_NOT_AUTHED == us_err_code) || (MAC_NOT_ASSOCED == us_err_code)) ? HI_TRUE : HI_FALSE;
1797
1798 if ((user_base_info->cap_info.pmf_active == HI_TRUE) && (aim_err_code == HI_TRUE) && (is_protected == HI_FALSE)) {
1799 return HI_SUCCESS;
1800 }
1801
1802 return HI_FAIL;
1803 }
1804
1805 /* ****************************************************************************
1806 功能描述 : 开始SA Query timer2超时操作
1807 输入参数 : p_arg:timer2超时处理入参结构体
1808 返 回 值 : HI_SUCCESS:超时处理成功
1809 修改历史 :
1810 1.日 期 : 2014年4月21日
1811 作 者 : HiSilicon
1812 修改内容 : 新生成函数
1813 **************************************************************************** */
hmac_sa_query_interval_timeout(hi_void * arg)1814 hi_u32 hmac_sa_query_interval_timeout(hi_void *arg)
1815 {
1816 hmac_interval_timer_stru *interval_timer_arg = HI_NULL;
1817 hi_u32 relt;
1818
1819 if (arg == HI_NULL) {
1820 oam_error_log0(0, OAM_SF_ANY, "{hmac_sa_query_interval_timeout::p_arg null.}");
1821 return HI_ERR_CODE_PTR_NULL;
1822 }
1823 interval_timer_arg = (hmac_interval_timer_stru *)arg;
1824
1825 if ((interval_timer_arg->hmac_user == HI_NULL) ||
1826 (interval_timer_arg->hmac_user->base_user->user_asoc_state != MAC_USER_STATE_ASSOC)) {
1827 oam_error_log0(interval_timer_arg->mac_vap->vap_id, OAM_SF_ANY,
1828 "{hmac_sa_query_interval_timeout::invalid param.}");
1829 return HI_ERR_CODE_PTR_NULL;
1830 }
1831
1832 /* 判断是否超时 */
1833 if (interval_timer_arg->hmac_user->sa_query_info.us_sa_query_count >= 3) { /* 3 边界 */
1834 relt = hmac_sa_query_del_user(interval_timer_arg->mac_vap, interval_timer_arg->hmac_user);
1835 if (relt != HI_SUCCESS) {
1836 oam_error_log1(interval_timer_arg->mac_vap->vap_id, OAM_SF_ANY,
1837 "{hmac_sa_query_interval_timeout::hmac_sa_query_del_user failed[%d].}", relt);
1838 return HI_ERR_CODE_PMF_SA_QUERY_DEL_USER_FAIL;
1839 }
1840 return HI_SUCCESS;
1841 }
1842
1843 /* 循环发送sa query request */
1844 relt = hmac_send_sa_query_req(interval_timer_arg->mac_vap, interval_timer_arg->hmac_user,
1845 interval_timer_arg->is_protected, interval_timer_arg->us_trans_id);
1846 if (relt != HI_SUCCESS) {
1847 oam_error_log1(interval_timer_arg->mac_vap->vap_id, OAM_SF_ANY,
1848 "{hmac_sa_query_interval_timeout::hmac_send_sa_query_req failed[%d].}", relt);
1849 return HI_ERR_CODE_PMF_SA_QUERY_REQ_SEND_FAIL;
1850 }
1851
1852 hi_u16 timeout = (hi_u16)mac_mib_get_dot11_association_saquery_retry_timeout(interval_timer_arg->mac_vap);
1853 frw_timer_restart_timer(&(interval_timer_arg->hmac_user->sa_query_info.sa_query_interval_timer), timeout, HI_TRUE);
1854
1855 return HI_SUCCESS;
1856 }
1857
1858 /* ****************************************************************************
1859 功能描述 : 开始SA Query 查询流程
1860 输入参数 : pst_mac_vap:启动SA查询的mac vap结构体
1861 puc_da:目标user的mac 地址
1862 en_is_protected:SA Query帧的加密标志位
1863 修改历史 :
1864 1.日 期 : 2014年4月21日
1865 作 者 : HiSilicon
1866 修改内容 : 新生成函数
1867 **************************************************************************** */
hmac_start_sa_query(mac_vap_stru * mac_vap,hmac_user_stru * hmac_user,hi_u8 is_protected)1868 hi_u32 hmac_start_sa_query(mac_vap_stru *mac_vap, hmac_user_stru *hmac_user, hi_u8 is_protected)
1869 {
1870 hi_u32 ret;
1871 hi_u16 us_init_trans_id;
1872
1873 /* 入参判断 */
1874 if ((mac_vap == HI_NULL) || (hmac_user == HI_NULL)) {
1875 oam_error_log2(0, OAM_SF_ANY, "{hmac_start_sa_query::param null, %p %p.}", (uintptr_t)mac_vap,
1876 (uintptr_t)hmac_user);
1877 return HI_ERR_CODE_PTR_NULL;
1878 }
1879
1880 /* 判断vap有无pmf能力 */
1881 if (hmac_user->base_user->cap_info.pmf_active != HI_TRUE) {
1882 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_start_sa_query::bit_pmf_active is down.}");
1883 return HI_ERR_CODE_PMF_DISABLED;
1884 }
1885
1886 /* 避免重复启动SA Query流程 */
1887 if (hmac_user->sa_query_info.us_sa_query_count != 0) {
1888 oam_info_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_start_sa_query::SA Query is already in process.}");
1889 return HI_SUCCESS;
1890 }
1891
1892 /* 获得hmac vap 结构指针 */
1893 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
1894 if (hmac_vap == HI_NULL) {
1895 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_start_sa_query::pst_hmac_vap null.}");
1896 return HI_ERR_CODE_PTR_NULL;
1897 }
1898
1899 /* 获得初始trans_id */
1900 us_init_trans_id = (hi_u16)hi_get_milli_seconds();
1901
1902 /* 设置timer超时函数入参 */
1903 hmac_interval_timer_stru *interval_timer_arg =
1904 (hmac_interval_timer_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_interval_timer_stru));
1905 if (interval_timer_arg == HI_NULL) {
1906 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_start_sa_query::pst_interval_timer_arg null.}");
1907 return HI_ERR_CODE_ALLOC_MEM_FAIL;
1908 }
1909 interval_timer_arg->mac_vap = mac_vap;
1910 interval_timer_arg->hmac_user = hmac_user;
1911 interval_timer_arg->is_protected = is_protected;
1912 interval_timer_arg->us_trans_id = us_init_trans_id;
1913 hi_u16 retry_timeout = (hi_u16)mac_mib_get_dot11_association_saquery_retry_timeout(mac_vap);
1914
1915 /* 记录sa query流程开始时间,单位ms */
1916 hmac_user->sa_query_info.sa_query_start_time = (hi_u32)hi_get_milli_seconds();
1917 /* 设置间隔定时器 */
1918 frw_timer_create_timer(&(hmac_user->sa_query_info.sa_query_interval_timer), hmac_sa_query_interval_timeout,
1919 retry_timeout, interval_timer_arg, HI_TRUE);
1920
1921 /* 发送SA Query request,开始查询流程 */
1922 ret = hmac_send_sa_query_req(mac_vap, hmac_user, is_protected, us_init_trans_id);
1923 if (ret != HI_SUCCESS) {
1924 if (hmac_user->sa_query_info.sa_query_interval_timer.is_enabled == HI_TRUE) {
1925 frw_timer_immediate_destroy_timer(&(hmac_user->sa_query_info.sa_query_interval_timer));
1926 }
1927 oam_error_log1(mac_vap->vap_id, OAM_SF_ANY, "{hmac_start_sa_query::hmac_send_sa_query_req failed[%d].}", ret);
1928 oal_mem_free(interval_timer_arg);
1929 return HI_ERR_CODE_PMF_SA_QUERY_REQ_SEND_FAIL;
1930 }
1931
1932 return HI_SUCCESS;
1933 }
1934
1935 /* ****************************************************************************
1936 功能描述 : 发送SA query response帧
1937 输入参数 : pst_mac_vap:发送SA query responsed的mac vap结构体
1938 pst_hdr:接收的sa query request帧的帧头指针
1939 en_is_protected:SA Query帧的加密标志位
1940 修改历史 :
1941 1.日 期 : 2014年4月21日
1942 作 者 : HiSilicon
1943 修改内容 : 新生成函数
1944 **************************************************************************** */
hmac_send_sa_query_rsp(mac_vap_stru * mac_vap,hi_u8 * hdr,hi_u8 is_protected)1945 hi_void hmac_send_sa_query_rsp(mac_vap_stru *mac_vap, hi_u8 *hdr, hi_u8 is_protected)
1946 {
1947 hi_u16 us_sa_query_len;
1948 oal_netbuf_stru *sa_query = 0;
1949 hmac_tx_ctl_stru *tx_ctl = HI_NULL;
1950 hi_u32 ret;
1951
1952 if (mac_vap == HI_NULL || hdr == HI_NULL) {
1953 oam_error_log2(0, OAM_SF_ANY, "{hmac_send_sa_query_rsp::param null, %p %p.}", (uintptr_t)mac_vap,
1954 (uintptr_t)hdr);
1955 return;
1956 }
1957 oam_info_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_send_sa_query_rsp::AP ready to TX a sa query rsp.}");
1958
1959 sa_query = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
1960 if (sa_query == HI_NULL) {
1961 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_send_sa_query_rsp::pst_sa_query null.}");
1962 return;
1963 }
1964
1965 if (memset_s(oal_netbuf_cb(sa_query), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size()) != EOK) {
1966 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_send_sa_query_rsp::memset_s fail!}");
1967 oal_netbuf_free(sa_query);
1968 return;
1969 }
1970 us_sa_query_len = hmac_encap_sa_query_rsp(mac_vap, hdr, (hi_u8 *)oal_netbuf_header(sa_query));
1971 if (us_sa_query_len == 0) {
1972 oam_error_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_send_sa_query_rsp::sa_query_len is 0!}");
1973 oal_netbuf_free(sa_query);
1974 return;
1975 }
1976
1977 /* 单播管理帧加密 */
1978 if (is_protected == HI_TRUE) {
1979 mac_set_protectedframe((hi_u8 *)oal_netbuf_header(sa_query));
1980 }
1981
1982 tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(sa_query); /* 获取cb结构体 */
1983 tx_ctl->us_mpdu_len = us_sa_query_len; /* dmac发送需要的mpdu长度 */
1984 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(sa_query);
1985 tx_ctl->mac_head_type = 1;
1986 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
1987 /* pmf5.3.3.4 认证失败,无法发送sa response帧 */
1988 /* 发送完成需要获取user结构体 */
1989 oal_netbuf_put(sa_query, us_sa_query_len);
1990
1991 /* Buffer this frame in the Memory Queue for transmission */
1992 ret = hmac_tx_mgmt_send_event(mac_vap, sa_query, us_sa_query_len);
1993 if (ret != HI_SUCCESS) {
1994 oal_netbuf_free(sa_query);
1995 oam_warning_log1(mac_vap->vap_id, OAM_SF_ANY,
1996 "{hmac_send_sa_query_rsp::hmac_tx_mgmt_send_event failed[%d].}", ret);
1997 }
1998
1999 return;
2000 }
2001 #endif
2002 /* ****************************************************************************
2003 功能描述 : 发送去认证帧
2004 修改历史 :
2005 1.日 期 : 2013年7月1日
2006 作 者 : HiSilicon
2007 修改内容 : 新生成函数
2008 **************************************************************************** */
hmac_mgmt_send_deauth_frame(mac_vap_stru * mac_vap,const hi_u8 * da_mac_addr,hi_u8 addr_len,hi_u16 err_code)2009 hi_void hmac_mgmt_send_deauth_frame(mac_vap_stru *mac_vap, const hi_u8 *da_mac_addr, hi_u8 addr_len, hi_u16 err_code)
2010 {
2011 hi_u8 user_idx = 0xff;
2012
2013 if ((mac_vap == HI_NULL) || (da_mac_addr == HI_NULL)) {
2014 oam_error_log2(0, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame::%p %p.}", (uintptr_t)mac_vap, (uintptr_t)mac_vap);
2015 return;
2016 }
2017
2018 /* 发送去认证前需确定vap处于工作状态 */
2019 if (mac_vap->vap_state == MAC_VAP_STATE_BUTT) {
2020 oam_warning_log1(mac_vap->vap_id, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame:vap_state%d}", mac_vap->vap_state);
2021 return;
2022 }
2023
2024 oal_netbuf_stru *deauth = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
2025 if (deauth == HI_NULL) {
2026 deauth = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
2027 if (deauth == HI_NULL) {
2028 oam_error_log0(mac_vap->vap_id, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame::pst_deauth null.}");
2029 return;
2030 }
2031 }
2032 /* 规则6.6:禁止使用内存操作类危险函数 例外(1)对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
2033 memset_s(oal_netbuf_cb(deauth), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
2034
2035 hi_u16 deauth_len = hmac_mgmt_encap_deauth(mac_vap, (hi_u8 *)oal_netbuf_header(deauth), da_mac_addr, err_code);
2036 if (deauth_len == 0) {
2037 oam_error_log0(mac_vap->vap_id, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame:: us_deauth_len = 0.}");
2038 oal_netbuf_free(deauth);
2039 return;
2040 }
2041 oal_netbuf_put(deauth, deauth_len);
2042
2043 /* 增加发送去认证帧时的维测信息 */
2044 oam_warning_log4(mac_vap->vap_id, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame::frameXX:XX:XX:%2x:%2x:%2x,code[%d]}",
2045 da_mac_addr[3], da_mac_addr[4], da_mac_addr[5], err_code); /* 3 4 5 元素索引 */
2046
2047 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(deauth); /* 获取cb结构体 */
2048 tx_ctl->us_mpdu_len = deauth_len; /* dmac发送需要的mpdu长度 */
2049 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
2050 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(deauth);
2051 tx_ctl->mac_head_type = 1;
2052
2053 mac_vap_set_cb_tx_user_idx(mac_vap, tx_ctl, da_mac_addr);
2054
2055 /* Buffer this frame in the Memory Queue for transmission */
2056 if (hmac_tx_mgmt_send_event(mac_vap, deauth, deauth_len) != HI_SUCCESS) {
2057 oal_netbuf_free(deauth);
2058 oam_warning_log0(mac_vap->vap_id, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame::hmac_tx_mgmt failed.}");
2059 }
2060
2061 if (mac_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) {
2062 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
2063 if ((mac_vap_find_user_by_macaddr(mac_vap, da_mac_addr, addr_len, &user_idx) != HI_SUCCESS) ||
2064 (hmac_vap == HI_NULL)) {
2065 oam_warning_log0(0, OAM_SF_AUTH, "{hmac_mgmt_send_deauth_frame:mac_vap_find_user failed or hmac_vap null}");
2066 return;
2067 }
2068
2069 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
2070 }
2071 }
2072
hmac_mgmt_send_disassoc_frame_param_check(mac_vap_stru * mac_vap,const hi_u8 * da_mac_addr)2073 hi_u32 hmac_mgmt_send_disassoc_frame_param_check(mac_vap_stru *mac_vap, const hi_u8 *da_mac_addr)
2074 {
2075 if (mac_vap == HI_NULL || da_mac_addr == HI_NULL) {
2076 oam_error_log2(0, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame_param_check::%p %p}", (uintptr_t)mac_vap,
2077 (uintptr_t)da_mac_addr);
2078 return HI_FAIL;
2079 }
2080
2081 /* 发送去关联前需确定vap处于工作状态 */
2082 if (mac_vap->vap_state == MAC_VAP_STATE_BUTT) {
2083 oam_warning_log1(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame_param_check:state %d}",
2084 mac_vap->vap_state);
2085 return HI_FAIL;
2086 }
2087
2088 return HI_SUCCESS;
2089 }
2090
2091 /* ****************************************************************************
2092 功能描述 : 发送去关联帧
2093 输入参数 : vap指针, DA, errcode
2094 修改历史 :
2095 1.日 期 : 2014年1月2日
2096 作 者 : HiSilicon
2097 修改内容 : 新生成函数
2098 **************************************************************************** */
hmac_mgmt_send_disassoc_frame(mac_vap_stru * mac_vap,const hi_u8 * da_mac_addr,hi_u16 err_code,hi_u8 is_protected)2099 hi_void hmac_mgmt_send_disassoc_frame(mac_vap_stru *mac_vap, const hi_u8 *da_mac_addr, hi_u16 err_code,
2100 hi_u8 is_protected)
2101 {
2102 if (hmac_mgmt_send_disassoc_frame_param_check(mac_vap, da_mac_addr) != HI_SUCCESS) {
2103 return;
2104 }
2105
2106 oal_netbuf_stru *disassoc = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
2107 if (disassoc == HI_NULL) {
2108 oam_error_log0(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame::pst_disassoc null.}");
2109 return;
2110 }
2111 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
2112 hi_u32 pedding_data = 0;
2113 hmac_config_scan_abort(mac_vap, sizeof(hi_u32), (hi_u8 *)&pedding_data);
2114 #endif
2115
2116 /* 规则6.6:禁止使用内存操作类危险函数 例外(1)对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
2117 memset_s(oal_netbuf_cb(disassoc), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
2118
2119 hi_u16 mpdu_len = hmac_mgmt_encap_disassoc(mac_vap, (hi_u8 *)oal_netbuf_header(disassoc), da_mac_addr, err_code);
2120 if (mpdu_len == 0) {
2121 oam_error_log0(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame:: us_disassoc_len = 0.}");
2122 oal_netbuf_free(disassoc);
2123 return;
2124 }
2125 #ifdef _PRE_WLAN_FEATURE_PMF
2126 if (is_protected == HI_TRUE) {
2127 mac_set_protectedframe((hi_u8 *)oal_netbuf_header(disassoc));
2128 }
2129 #endif
2130
2131 /* 增加发送去关联帧时的维测信息 */
2132 oam_warning_log4(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame:ecode[%d],da xx:xx:xx:%2x:%2x:%2x}",
2133 err_code, da_mac_addr[3], da_mac_addr[4], da_mac_addr[5]); /* 3 4 5 元素索引 */
2134
2135 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(disassoc);
2136 tx_ctl->us_mpdu_len = mpdu_len;
2137 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
2138 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(disassoc);
2139 tx_ctl->mac_head_type = 1;
2140
2141 mac_vap_set_cb_tx_user_idx(mac_vap, tx_ctl, da_mac_addr);
2142
2143 oal_netbuf_put(disassoc, mpdu_len);
2144
2145 /* 加入发送队列 */
2146 if (hmac_tx_mgmt_send_event(mac_vap, disassoc, mpdu_len) != HI_SUCCESS) {
2147 oal_netbuf_free(disassoc);
2148 oam_warning_log0(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame::hmac_tx_mgmt failed.}");
2149 }
2150
2151 if (mac_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) {
2152 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
2153 if (hmac_vap == HI_NULL) {
2154 oam_error_log1(mac_vap->vap_id, OAM_SF_ASSOC, "{hmac_mgmt_send_disassoc_frame:vap_id:%d}", mac_vap->vap_id);
2155 return;
2156 }
2157
2158 hmac_fsm_change_state(hmac_vap, MAC_VAP_STATE_STA_FAKE_UP);
2159 }
2160 }
2161
2162 /* ****************************************************************************
2163 功能描述 : 更新对应关联实体的qos能力信息:函数的功能是在关联用户WMM使能的情况下
2164 往dmac抛事件写寄存器,如果关联用户之前就是WMM使能的,则不必重复写寄
2165 存器,如果之前不是WMM使能的,现在也不是WMM使能的,则不用写寄存器
2166 输入参数 : puc_payload :指向帧体的指针
2167 ul_msg_len :帧的长度
2168 us_info_elem_offset:目前帧体位置的偏移
2169 pst_hmac_user :指向hmac_user的指针
2170 修改历史 :
2171 1.日 期 : 2013年10月24日
2172 作 者 : HiSilicon
2173 修改内容 : 新生成函数
2174 **************************************************************************** */
hmac_mgmt_update_assoc_user_qos(hi_u8 * puc_payload,hi_u16 us_msg_len,hi_u16 us_info_elem_offset,const hmac_user_stru * hmac_user)2175 hi_void hmac_mgmt_update_assoc_user_qos(hi_u8 *puc_payload, hi_u16 us_msg_len, hi_u16 us_info_elem_offset,
2176 const hmac_user_stru *hmac_user)
2177 {
2178 hi_u8 *puc_ie = HI_NULL;
2179 hi_u16 us_msg_idx = us_info_elem_offset;
2180
2181 /* 如果关联用户之前就是wmm使能的,什么都不用做,直接返回 */
2182 if (hmac_user->base_user->cap_info.qos == HI_TRUE) {
2183 oam_info_log0(hmac_user->base_user->vap_id, OAM_SF_ASSOC,
2184 "{hmac_mgmt_update_assoc_user_qos_table::assoc user is wmm cap already.}");
2185 return;
2186 }
2187
2188 mac_user_set_qos(hmac_user->base_user, HI_FALSE);
2189 while (us_msg_idx < us_msg_len) {
2190 if (mac_is_wmm_ie(&puc_payload[us_msg_idx]) == HI_TRUE) {
2191 mac_user_set_qos(hmac_user->base_user, HI_TRUE);
2192 break;
2193 }
2194 us_msg_idx += (puc_payload[us_msg_idx + 1] + MAC_IE_HDR_LEN);
2195 }
2196
2197 mac_vap_stru *mac_vap = mac_vap_get_vap_stru(hmac_user->base_user->vap_id);
2198 if (oal_unlikely(mac_vap == HI_NULL)) {
2199 oam_error_log0(hmac_user->base_user->vap_id, OAM_SF_ASSOC,
2200 "{hmac_mgmt_update_assoc_user_qos_table::pst_mac_vap null.}");
2201 return;
2202 }
2203
2204 if (us_msg_len <= us_info_elem_offset) {
2205 oam_error_log0(hmac_user->base_user->vap_id, OAM_SF_ASSOC,
2206 "{hmac_mgmt_update_assoc_user_qos_table::msg_len less offset.}");
2207 return;
2208 }
2209
2210 puc_ie = mac_find_ie(MAC_EID_WMM, puc_payload + us_info_elem_offset, us_msg_len - us_info_elem_offset);
2211 if (puc_ie != HI_NULL) {
2212 mac_user_set_qos(hmac_user->base_user, mac_vap->mib_info->wlan_mib_sta_config.dot11_qos_option_implemented);
2213 } else {
2214 if (is_sta(mac_vap)) {
2215 puc_ie = mac_find_ie(MAC_EID_HT_CAP, puc_payload + us_info_elem_offset, us_msg_len - us_info_elem_offset);
2216 /* 查找HT CAP能力第2字节BIT5 short GI for 20M 能力位 */
2217 if ((puc_ie != HI_NULL) && ((puc_ie[1] >= OAL_IE_HDR_LEN) && (puc_ie[2] & BIT5))) {
2218 mac_user_set_qos(hmac_user->base_user, HI_TRUE);
2219 }
2220 }
2221 }
2222
2223 /* 如果关联用户到现在仍然不是wmm使能的,什么也不做,直接返回 */
2224 if (hmac_user->base_user->cap_info.qos == HI_FALSE) {
2225 oam_info_log0(hmac_user->base_user->vap_id, OAM_SF_ASSOC,
2226 "{hmac_mgmt_update_assoc_user_qos_table::assoc user is not wmm cap.}");
2227 return;
2228 }
2229 }
2230
2231 /* ****************************************************************************
2232 功能描述 : check capabilities info field 中mac信息,如BSS type, Privacy等是否与VAP相符
2233 修改历史 :
2234 1.日 期 : 2013年12月6日
2235 作 者 : HiSilicon
2236 修改内容 : 新生成函数
2237 **************************************************************************** */
hmac_check_bss_cap_info(hi_u16 us_cap_info,mac_vap_stru * mac_vap)2238 hi_u8 hmac_check_bss_cap_info(hi_u16 us_cap_info, mac_vap_stru *mac_vap)
2239 {
2240 hmac_vap_stru *hmac_vap = HI_NULL;
2241 wlan_mib_desired_bsstype_enum_uint8 bss_type;
2242
2243 /* 获取CAP INFO里BSS TYPE */
2244 bss_type = mac_get_bss_type(us_cap_info);
2245
2246 hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
2247 if (hmac_vap == HI_NULL || mac_vap->mib_info == HI_NULL) {
2248 oam_warning_log0(mac_vap->vap_id, OAM_SF_CFG, "{hmac_check_bss_cap_info::hmac_vap/mib_info null.}");
2249 return HI_FALSE;
2250 }
2251
2252 /* 比较BSS TYPE是否一致 不一致,如果是STA仍然发起入网,增加兼容性,其它模式则返回不支持 */
2253 #ifdef _PRE_WLAN_FEATURE_MESH
2254 if (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_MESH) {
2255 if ((bss_type != mac_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type) &&
2256 (bss_type != WLAN_MIB_DESIRED_BSSTYPE_ANY)) {
2257 oam_warning_log1(mac_vap->vap_id, OAM_SF_ASSOC,
2258 "{hmac_check_bss_cap_info::MESH:asoc_user_bss_type[%d] is different from any and Infra}", bss_type);
2259 }
2260 } else {
2261 if (bss_type != mac_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type) {
2262 oam_warning_log2(mac_vap->vap_id, OAM_SF_ASSOC,
2263 "{hmac_check_bss_cap_info::vap_bss_type[%d] is different from asoc_user_bss_type[%d].}",
2264 mac_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type, bss_type);
2265 }
2266 }
2267 #else
2268 if (bss_type != mac_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type) {
2269 oam_warning_log2(mac_vap->vap_id, OAM_SF_ASSOC,
2270 "{hmac_check_bss_cap_info::vap_bss_type[%d] is different from asoc_user_bss_type[%d].}",
2271 mac_vap->mib_info->wlan_mib_sta_config.dot11_desired_bss_type, bss_type);
2272 }
2273 #endif
2274
2275 if (hmac_vap->wps_active == HI_TRUE) {
2276 return HI_TRUE;
2277 }
2278
2279 /* 比较CAP INFO中privacy位,检查是否加密,加密不一致,返回失败 */
2280 if (!mac_check_mac_privacy(us_cap_info, (hi_u8 *)mac_vap)) {
2281 oam_warning_log0(mac_vap->vap_id, OAM_SF_ASSOC,
2282 "{hmac_check_bss_cap_info::mac privacy capabilities is different.}");
2283 }
2284
2285 return HI_TRUE;
2286 }
2287
2288 /* ****************************************************************************
2289 功能描述 : 获取用户的协议模式
2290 修改历史 :
2291 1.日 期 : 2013年10月16日
2292 作 者 : HiSilicon
2293 修改内容 : 新生成函数
2294 **************************************************************************** */
hmac_set_user_protocol_mode(const mac_vap_stru * mac_vap,hmac_user_stru * hmac_user)2295 hi_void hmac_set_user_protocol_mode(const mac_vap_stru *mac_vap, hmac_user_stru *hmac_user)
2296 {
2297 mac_user_ht_hdl_stru *mac_ht_hdl = HI_NULL;
2298 mac_user_stru *mac_user = HI_NULL;
2299 hi_u32 is_support_11g;
2300 hi_u32 is_support_11b;
2301
2302 /* 获取HT和VHT结构体指针 */
2303 mac_user = hmac_user->base_user;
2304 mac_ht_hdl = &(mac_user->ht_hdl);
2305
2306 if (mac_ht_hdl->ht_capable == HI_TRUE) {
2307 mac_user_set_protocol_mode(mac_user, WLAN_HT_MODE);
2308 } else {
2309 is_support_11g = hmac_is_support_11grate(hmac_user->op_rates.auc_rs_rates, hmac_user->op_rates.rs_nrates);
2310 is_support_11b = hmac_is_support_11brate(hmac_user->op_rates.auc_rs_rates, hmac_user->op_rates.rs_nrates);
2311 if (is_support_11g == HI_TRUE) {
2312 mac_user_set_protocol_mode(mac_user, WLAN_LEGACY_11G_MODE);
2313 if (is_support_11b == HI_TRUE) {
2314 mac_user_set_protocol_mode(mac_user, WLAN_MIXED_ONE_11G_MODE);
2315 }
2316 } else if (is_support_11b == HI_TRUE) {
2317 mac_user_set_protocol_mode(mac_user, WLAN_LEGACY_11B_MODE);
2318 } else {
2319 oam_warning_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_set_user_protocol_mode::set user protocol failed.}");
2320 }
2321 }
2322
2323 /* 兼容性问题:思科AP 2.4G(11b)和5G(11a)共存时发送的assoc rsp帧携带的速率分别是11g和11b,
2324 导致STA创建用户时通知算法失败,Autorate失效,DBAC情况下,DBAC无法启动已工作的VAP状态无法恢复的问题 临时方案,
2325 建议针对对端速率异常的情况统一分析优化 */
2326 if (((mac_user->protocol_mode == WLAN_LEGACY_11B_MODE) && (mac_vap->protocol == WLAN_LEGACY_11A_MODE)) ||
2327 ((mac_user->protocol_mode == WLAN_LEGACY_11G_MODE) && (mac_vap->protocol == WLAN_LEGACY_11B_MODE))) {
2328 mac_user_set_protocol_mode(mac_user, mac_vap->protocol);
2329 if (memcpy_s((hi_void *)&(hmac_user->op_rates), sizeof(mac_rate_stru),
2330 (hi_void *)&(mac_vap->curr_sup_rates.rate), sizeof(mac_rate_stru)) != EOK) {
2331 oam_error_log0(0, OAM_SF_CFG, "hmac_set_user_protocol_mode:: st_rate memcpy_s fail.");
2332 return;
2333 }
2334 }
2335 }
2336
2337 #ifdef _PRE_WLAN_FEATURE_PMF
2338 /* ****************************************************************************
2339 功能描述 : AP在UP状态下的接收SA Query request帧处理
2340 输入参数 : pst_hmac_vap: HMAC VAP指针
2341 pst_netbuf : 管理帧所在的sk_buff
2342 en_is_protected 此管理帧是否受单播保护
2343 修改历史 :
2344 1.日 期 : 2014年4月09日
2345 作 者 : HiSilicon
2346 修改内容 : 新生成函数
2347 **************************************************************************** */
hmac_rx_sa_query_req(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,hi_u8 is_protected)2348 hi_void hmac_rx_sa_query_req(hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf, hi_u8 is_protected)
2349 {
2350 hi_u8 *sa_mac_addr = HI_NULL;
2351 hmac_user_stru *hmac_user = HI_NULL;
2352 hi_u8 *puc_mac_hdr = HI_NULL;
2353
2354 if ((hmac_vap == HI_NULL) || (netbuf == HI_NULL)) {
2355 oam_error_log2(0, OAM_SF_RX, "{hmac_rx_sa_query_req::null param %p %p.}", (uintptr_t)hmac_vap,
2356 (uintptr_t)netbuf);
2357 return;
2358 }
2359
2360 puc_mac_hdr = oal_netbuf_header(netbuf);
2361
2362 mac_rx_get_sa((mac_ieee80211_frame_stru *)puc_mac_hdr, &sa_mac_addr);
2363 hmac_user = mac_vap_get_hmac_user_by_addr(hmac_vap->base_vap, sa_mac_addr, WLAN_MAC_ADDR_LEN);
2364 if (hmac_user == HI_NULL) {
2365 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_sa_query_req::pst_hmac_user null.}");
2366 return;
2367 }
2368
2369 /* 如果该用户的管理帧加密属性不一致,丢弃该报文 */
2370 if (is_protected != hmac_user->base_user->cap_info.pmf_active) {
2371 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_sa_query_req::PMF check failed.}");
2372 return;
2373 }
2374
2375 /* sa Query rsp发送 */
2376 hmac_send_sa_query_rsp(hmac_vap->base_vap, puc_mac_hdr, is_protected);
2377
2378 return;
2379 }
2380
2381 /* ****************************************************************************
2382 功能描述 : UP状态下的接收SA Query rsponse帧处理
2383 输入参数 : pst_hmac_vap : HMAC VAP指针
2384 pst_netbuf : 管理帧所在的sk_buff
2385 en_is_protected: 单播管理帧加密的标志位
2386 修改历史 :
2387 1.日 期 : 2014年4月09日
2388 作 者 : HiSilicon
2389 修改内容 : 新生成函数
2390 **************************************************************************** */
hmac_rx_sa_query_rsp(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,hi_u8 is_protected)2391 hi_void hmac_rx_sa_query_rsp(hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf, hi_u8 is_protected)
2392 {
2393 hi_u8 *puc_mac_hdr = HI_NULL;
2394 hi_u8 *sa_mac_addr = HI_NULL;
2395 hmac_user_stru *hmac_user = HI_NULL;
2396 hi_u16 *pus_trans_id = HI_NULL;
2397 mac_sa_query_stru *sa_query_info = HI_NULL;
2398
2399 if ((hmac_vap == HI_NULL) || (netbuf == HI_NULL)) {
2400 oam_error_log2(0, OAM_SF_AMPDU, "{hmac_rx_sa_query_rsp::param null,%p %p.}", (uintptr_t)hmac_vap,
2401 (uintptr_t)netbuf);
2402 return;
2403 }
2404
2405 puc_mac_hdr = oal_netbuf_header(netbuf);
2406
2407 mac_rx_get_sa((mac_ieee80211_frame_stru *)puc_mac_hdr, &sa_mac_addr);
2408 hmac_user = mac_vap_get_hmac_user_by_addr(hmac_vap->base_vap, sa_mac_addr, WLAN_MAC_ADDR_LEN);
2409 if (hmac_user == HI_NULL) {
2410 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AMPDU, "{hmac_rx_sa_query_rsp::pst_hmac_user null.}");
2411 return;
2412 }
2413
2414 /* 如果该用户的管理帧加密属性不一致,丢弃该报文 */
2415 if (is_protected != hmac_user->base_user->cap_info.pmf_active) {
2416 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_AMPDU, "{hmac_rx_sa_query_rsp::PMF check failed.}");
2417 return;
2418 }
2419
2420 /* 对比trans_id */
2421 pus_trans_id = (hi_u16 *)(puc_mac_hdr + MAC_80211_FRAME_LEN + 2); /* 2 偏置项 */
2422 sa_query_info = &hmac_user->sa_query_info;
2423
2424 /* 收到有效的SA query reqponse,保留这条有效的SA */
2425 if (0 == memcmp(pus_trans_id, &(sa_query_info->us_sa_query_trans_id), 2)) { /* 2 复制长度 */
2426 /* pending SA Query requests 计数器清零 & sa query流程开始时间清零 */
2427 sa_query_info->us_sa_query_count = 0;
2428 sa_query_info->sa_query_start_time = 0;
2429
2430 /* 删除timer */
2431 if (sa_query_info->sa_query_interval_timer.is_registerd != HI_FALSE) {
2432 frw_timer_immediate_destroy_timer(&(sa_query_info->sa_query_interval_timer));
2433 }
2434
2435 /* 删除timers的入参存储空间 */
2436 if (sa_query_info->sa_query_interval_timer.timeout_arg != HI_NULL) {
2437 oal_mem_free((hi_void *)sa_query_info->sa_query_interval_timer.timeout_arg);
2438 sa_query_info->sa_query_interval_timer.timeout_arg = HI_NULL;
2439 }
2440 }
2441 return;
2442 }
2443 #endif
2444 #ifdef _PRE_WLAN_FEATURE_OPMODE_NOTIFY
hmac_send_psm_opmode_notify_event(hmac_vap_stru * hmac_vap,mac_user_stru * mac_user,hi_u8 user_idx)2445 hi_u32 hmac_send_psm_opmode_notify_event(hmac_vap_stru *hmac_vap, mac_user_stru *mac_user, hi_u8 user_idx)
2446 {
2447 frw_event_mem_stru *event_mem = frw_event_alloc(sizeof(hi_u8));
2448 if (event_mem == HI_NULL) {
2449 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_ANY, "{hmac_mgmt_rx_opmode_notify_frame:event_allocErr}");
2450 return HI_FAIL;
2451 }
2452
2453 /* 填写事件 */
2454 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
2455 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_PSM_OPMODE_NOTIFY,
2456 sizeof(hi_u16), FRW_EVENT_PIPELINE_STAGE_1, mac_user->vap_id);
2457
2458 event->auc_event_data[0] = user_idx;
2459
2460 /* 分发事件 */
2461 hcc_hmac_tx_control_event(event_mem, sizeof(hi_u16));
2462 frw_event_free(event_mem);
2463
2464 return HI_SUCCESS;
2465 }
2466
2467 /* ****************************************************************************
2468 功能描述 : 从空口接收opmode_notify帧的处理函数
2469 修改历史 :
2470 1.日 期 : 2014年6月10日
2471 作 者 : HiSilicon
2472 修改内容 : 新生成函数
2473 **************************************************************************** */
hmac_mgmt_rx_opmode_notify_frame(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf)2474 hi_u32 hmac_mgmt_rx_opmode_notify_frame(hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf)
2475 {
2476 hi_u8 user_idx = 0;
2477 hi_u8 sta_mac_addr[WLAN_MAC_ADDR_LEN] = {0};
2478
2479 if ((mac_mib_get_VHTOptionImplemented(hmac_vap->base_vap) == HI_FALSE) ||
2480 (mac_mib_get_operating_mode_notification_implemented(hmac_vap->base_vap) == HI_FALSE)) {
2481 oam_info_log0(hmac_vap->base_vap->vap_id, OAM_SF_ANY,
2482 "{hmac_mgmt_rx_opmode_notify_frame::the vap is not support OperatingModeNotification}");
2483 return HI_SUCCESS;
2484 }
2485
2486 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2487 mac_get_address2((hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr, WLAN_MAC_ADDR_LEN, sta_mac_addr, WLAN_MAC_ADDR_LEN);
2488
2489 hi_u32 ret = mac_vap_find_user_by_macaddr(hmac_vap->base_vap, sta_mac_addr, WLAN_MAC_ADDR_LEN, &user_idx);
2490 if (ret != HI_SUCCESS) {
2491 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_SMPS, "{hmac_mgmt_rx_opmode_notify_frame:Err=%d}", ret);
2492 return HI_ERR_CODE_PTR_NULL;
2493 }
2494
2495 mac_user_stru *mac_user = mac_user_get_user_stru(user_idx);
2496 if (mac_user == HI_NULL) {
2497 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_SMPS, "{hmac_mgmt_rx_opmode_notify_frame::mac_user null}");
2498 return HI_ERR_CODE_PTR_NULL;
2499 }
2500
2501 /* 获取帧体指针 */
2502 hi_u8 *puc_data = (hi_u8 *)rx_ctrl->pul_mac_hdr_start_addr;
2503 hi_u8 mgmt_frm_type = mac_get_frame_sub_type(puc_data);
2504
2505 /* 是否需要处理Power Management bit位 */
2506 mac_ieee80211_frame_stru *mac_header = (mac_ieee80211_frame_stru *)puc_data;
2507 hi_u8 power_save = (hi_u8)mac_header->frame_control.power_mgmt;
2508
2509 /* 如果节能位开启(bit_power_mgmt == 1),抛事件到DMAC,处理用户节能信息 */
2510 if ((power_save == HI_TRUE) && ((hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_BSS_AP)
2511 #ifdef _PRE_WLAN_FEATURE_MESH
2512 || (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_MESH)
2513 #endif
2514 )) {
2515 if (hmac_send_psm_opmode_notify_event(hmac_vap, mac_user, user_idx) != HI_SUCCESS) {
2516 return HI_FAIL;
2517 }
2518 }
2519
2520 /* ************************************************** */
2521 /* OperatingModeNotification Frame - Frame Body */
2522 /* ------------------------------------------------- */
2523 /* | Category | Action | OperatingMode | */
2524 /* ------------------------------------------------- */
2525 /* | 1 | 1 | 1 | */
2526 /* ------------------------------------------------- */
2527 /* */
2528 /* ************************************************** */
2529 /* 获取payload的指针 */
2530 hi_u8 *puc_frame_payload = puc_data + MAC_80211_FRAME_LEN;
2531 mac_opmode_notify_stru *opmode_notify = (mac_opmode_notify_stru *)(puc_frame_payload + MAC_ACTION_OFFSET_ACTION + 1);
2532
2533 ret = hmac_ie_proc_opmode_field(hmac_vap->base_vap, mac_user, opmode_notify, mgmt_frm_type);
2534 if (oal_unlikely(ret != HI_SUCCESS)) {
2535 oam_warning_log1(mac_user->vap_id, OAM_SF_CFG, "{hmac_mgmt_rx_opmode_notify_frame::proc_opmode Err=%d}", ret);
2536 return ret;
2537 }
2538
2539 /* opmode息同步dmac */
2540 ret = hmac_config_update_opmode_event(hmac_vap->base_vap, mac_user, mgmt_frm_type);
2541 if (oal_unlikely(ret != HI_SUCCESS)) {
2542 oam_warning_log1(mac_user->vap_id, OAM_SF_CFG, "{hmac_mgmt_rx_opmode_notify_frame::update_opmode Err=%d}", ret);
2543 }
2544
2545 return ret;
2546 }
2547 #endif
2548
2549 /* ****************************************************************************
2550 功能描述 : 上报接收到的管理帧
2551 输入参数 : [1]hmac_vap
2552 [2]puc_buf
2553 [3]us_len
2554 [4]l_freq
2555 返 回 值 : 无
2556 **************************************************************************** */
hmac_send_mgmt_to_host(const hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,hi_u16 us_len,hi_s32 l_freq)2557 hi_void hmac_send_mgmt_to_host(const hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf, hi_u16 us_len, hi_s32 l_freq)
2558 {
2559 hmac_rx_mgmt_event_stru mgmt_frame;
2560 hmac_rx_ctl_stru *rx_info = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2561 hi_u8 *mgmt_data = (hi_u8 *)oal_memalloc(us_len);
2562 if (mgmt_data == HI_NULL) {
2563 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_SCAN, "{hmac_send_mgmt_to_host::pst_mgmt_data null.}");
2564 return;
2565 }
2566 memcpy_s(mgmt_data, us_len, (hi_u8 *)rx_info->pul_mac_hdr_start_addr, us_len);
2567
2568 /* 填写上报管理帧数据 */
2569 mgmt_frame.puc_buf = (hi_u8 *)mgmt_data;
2570 mgmt_frame.us_len = us_len;
2571 mgmt_frame.l_freq = l_freq;
2572 oal_netbuf_set_len(netbuf, us_len);
2573
2574 memcpy_s(mgmt_frame.ac_name, OAL_IF_NAME_SIZE, hmac_vap->net_device->name, OAL_IF_NAME_SIZE);
2575 #ifdef _PRE_WLAN_FEATURE_P2P
2576 mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)(rx_info->pul_mac_hdr_start_addr);
2577 mac_vap_stru *mac_vap = hmac_vap->base_vap;
2578 if (!is_legacy_vap(mac_vap)) {
2579 /* 仅针对P2P设备做处理。P2P vap 存在一个vap 对应多个hal_vap 情况
2580 * 非P2P vap 不存在一个vap 对应多个hal_vap 情况
2581 * 对比接收到的管理帧vap_id 是否和vap 中hal_vap_id 相同
2582 * 从管理帧cb字段中的hal vap id 的相应信息查找对应的net dev 指针
2583 */
2584 if (oal_compare_mac_addr(frame_hdr->auc_address1,
2585 mac_vap->mib_info->wlan_mib_sta_config.auc_p2p0_dot11_station_id, WLAN_MAC_ADDR_LEN) == 0) {
2586 /* 第二个net dev槽 */
2587 memcpy_s(mgmt_frame.ac_name, OAL_IF_NAME_SIZE, hmac_vap->p2p0_net_device->name, OAL_IF_NAME_SIZE);
2588 } else if (oal_compare_mac_addr(frame_hdr->auc_address1,
2589 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) == 0) {
2590 memcpy_s(mgmt_frame.ac_name, OAL_IF_NAME_SIZE, hmac_vap->net_device->name, OAL_IF_NAME_SIZE);
2591 } else {
2592 oal_free(mgmt_data);
2593 return;
2594 }
2595 }
2596 #endif
2597 if (hmac_send_event_to_host(hmac_vap->base_vap, (const hi_u8 *)(&mgmt_frame), sizeof(hmac_rx_mgmt_event_stru),
2598 HMAC_HOST_CTX_EVENT_SUB_TYPE_RX_MGMT) != HI_SUCCESS) {
2599 oal_free(mgmt_data);
2600 }
2601 return;
2602 }
2603
2604 /* ****************************************************************************
2605 功能描述 : 发送wpa_supplicant action frame
2606 修改历史 :
2607 1.日 期 : 2014年12月25日
2608 作 者 : HiSilicon
2609 修改内容 : 新生成函数
2610 **************************************************************************** */
hmac_wpas_mgmt_tx(mac_vap_stru * mac_vap,hi_u16 us_len,const hi_u8 * puc_param)2611 hi_u32 hmac_wpas_mgmt_tx(mac_vap_stru *mac_vap, hi_u16 us_len, const hi_u8 *puc_param)
2612 {
2613 hi_unref_param(us_len);
2614 if (mac_vap == HI_NULL || puc_param == HI_NULL) {
2615 oam_error_log2(0, OAM_SF_P2P, "{hmac_wpas_mgmt_tx::param null,%p %p}", (uintptr_t)mac_vap, (uintptr_t)mac_vap);
2616 return HI_FAIL;
2617 }
2618
2619 mac_mgmt_frame_stru *mgmt_tx = (mac_mgmt_frame_stru *)puc_param;
2620 oam_warning_log1(mac_vap->vap_id, OAM_SF_P2P, "{hmac_wpas_mgmt_tx::mgmt frame id=[%d]}", mgmt_tx->mgmt_frame_id);
2621
2622 /* 申请netbuf 空间 */
2623 oal_netbuf_stru *netbuf_mgmt_tx = (oal_netbuf_stru *)oal_netbuf_alloc(mgmt_tx->us_len, 0, 4); /* align 4 */
2624 if (netbuf_mgmt_tx == HI_NULL) {
2625 netbuf_mgmt_tx = (oal_netbuf_stru *)oal_netbuf_alloc(WLAN_MGMT_NETBUF_SIZE, 0, 4); /* align 4 */
2626 if (netbuf_mgmt_tx == HI_NULL) {
2627 oam_error_log0(mac_vap->vap_id, OAM_SF_P2P, "{hmac_wpas_mgmt_tx::pst_mgmt_tx null.}");
2628 return HI_FAIL;
2629 }
2630 }
2631 if (memset_s(oal_netbuf_cb(netbuf_mgmt_tx), sizeof(hmac_tx_ctl_stru), 0, sizeof(hmac_tx_ctl_stru)) != EOK) {
2632 oam_error_log0(0, OAM_SF_CFG, "hmac_wpas_mgmt_tx::memset_s fail.");
2633 oal_netbuf_free(netbuf_mgmt_tx);
2634 return HI_FAIL;
2635 }
2636
2637 /* 填充netbuf */
2638 if (mgmt_tx->puc_frame != HI_NULL) {
2639 if (memcpy_s((hi_u8 *)oal_netbuf_header(netbuf_mgmt_tx), mgmt_tx->us_len, mgmt_tx->puc_frame,
2640 mgmt_tx->us_len) != EOK) {
2641 oal_netbuf_free(netbuf_mgmt_tx);
2642 oam_error_log0(0, OAM_SF_CFG, "hmac_wpas_mgmt_tx:: pst_mgmt_tx memcpy_s fail.");
2643 return HI_FAIL;
2644 }
2645 }
2646 oal_netbuf_put(netbuf_mgmt_tx, mgmt_tx->us_len);
2647
2648 hmac_tx_ctl_stru *tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(netbuf_mgmt_tx); /* 获取cb结构体 */
2649 tx_ctl->us_mpdu_len = mgmt_tx->us_len; /* dmac发送需要的mpdu长度 */
2650 tx_ctl->need_rsp = HI_TRUE;
2651 tx_ctl->is_vipframe = HI_TRUE;
2652 tx_ctl->is_needretry = HI_TRUE;
2653 tx_ctl->mgmt_frame_id = mgmt_tx->mgmt_frame_id;
2654 tx_ctl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_header(netbuf_mgmt_tx);
2655 tx_ctl->mac_head_type = 1;
2656 tx_ctl->frame_header_length = MAC_80211_FRAME_LEN;
2657 tx_ctl->us_tx_user_idx = MAC_INVALID_USER_ID;
2658
2659 /* Buffer this frame in the Memory Queue for transmission */
2660 hi_u32 ret = hmac_tx_mgmt_send_event(mac_vap, netbuf_mgmt_tx, mgmt_tx->us_len);
2661 if (ret != HI_SUCCESS) {
2662 oal_netbuf_free(netbuf_mgmt_tx);
2663 oam_warning_log1(mac_vap->vap_id, OAM_SF_P2P, "{hmac_wpas_mgmt_tx::hmac_tx_mgmt_send_event failed[%d].}", ret);
2664 return HI_FAIL;
2665 }
2666 return HI_SUCCESS;
2667 }
2668
2669 /* ****************************************************************************
2670 功能描述 : 接收到管理帧并上报host
2671 输入参数 : hmac_vap_stru *pst_hmac_vap
2672 oal_netbuf_stru *pst_netbuf
2673 修改历史 :
2674 1.日 期 : 2015年7月25日
2675 作 者 : HiSilicon
2676 修改内容 : 新生成函数
2677 **************************************************************************** */
hmac_rx_mgmt_send_to_host(const hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf)2678 hi_void hmac_rx_mgmt_send_to_host(const hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf)
2679 {
2680 hmac_rx_ctl_stru *rx_info = HI_NULL;
2681 hi_s32 l_freq;
2682
2683 rx_info = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
2684
2685 l_freq = oal_ieee80211_channel_to_frequency(rx_info->channel_number,
2686 (rx_info->channel_number > 14) ? IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ); /* 14 用于判断 */
2687 hmac_send_mgmt_to_host(hmac_vap, netbuf, rx_info->us_frame_len, l_freq);
2688 }
2689 /* ****************************************************************************
2690 功能描述 : 处理dmac上报管理帧发送的结果,上报WAL
2691 修改历史 :
2692 1.日 期 : 2014年12月31日
2693 作 者 : HiSilicon
2694 修改内容 : 新生成函数
2695 **************************************************************************** */
2696 /* 结构体数组g_ast_hmac_config_syn成员hmac_config_syn_stru(dmac_config_syn_stru),其中函数指针
2697 dmac_config_data_acq_status对所指向的内容进行了修改,lin_t e818告警屏蔽 */
hmac_mgmt_tx_event_status(mac_vap_stru * mac_vap,hi_u8 len,const hi_u8 * puc_param)2698 hi_u32 hmac_mgmt_tx_event_status(mac_vap_stru *mac_vap, hi_u8 len, const hi_u8 *puc_param)
2699 {
2700 dmac_crx_mgmt_tx_status_stru *mgmt_tx_status_param = HI_NULL;
2701 if (mac_vap == HI_NULL || puc_param == HI_NULL) {
2702 oam_error_log2(0, OAM_SF_ANY, "{hmac_mgmt_tx_event_status::pst_mac_vap[%p] NULL or pst_puc_param[%p] NULL!}",
2703 (uintptr_t)mac_vap, (uintptr_t)puc_param);
2704 return HI_ERR_CODE_PTR_NULL;
2705 }
2706 hi_unref_param(len);
2707
2708 mgmt_tx_status_param = (dmac_crx_mgmt_tx_status_stru *)puc_param;
2709
2710 oam_warning_log3(mac_vap->vap_id, OAM_SF_P2P,
2711 "{hmac_mgmt_tx_event_status::dmac tx mgmt status report.userindx[%d], tx mgmt status[%d], frame_id[%d]}",
2712 mgmt_tx_status_param->user_idx, mgmt_tx_status_param->tx_status, mgmt_tx_status_param->mgmt_frame_id);
2713
2714 return hmac_send_event_to_host(mac_vap, (const hi_u8 *)mgmt_tx_status_param, sizeof(dmac_crx_mgmt_tx_status_stru),
2715 HMAC_HOST_CTX_EVENT_SUB_TYPE_MGMT_TX_STATUS);
2716 }
2717
2718 /* ****************************************************************************
2719 功能描述 : 获取用户和VAP可用的11a/b/g公共速率
2720 修改历史 :
2721 1.日 期 : 2013年10月16日
2722 作 者 : HiSilicon
2723 修改内容 : 新生成函数
2724 **************************************************************************** */
hmac_vap_set_user_avail_rates(mac_vap_stru * mac_vap,hmac_user_stru * hmac_user)2725 hi_void hmac_vap_set_user_avail_rates(mac_vap_stru *mac_vap, hmac_user_stru *hmac_user)
2726 {
2727 mac_user_stru *mac_user = HI_NULL;
2728 mac_curr_rateset_stru *mac_vap_rate = HI_NULL;
2729 mac_rate_stru *mac_user_rate = HI_NULL;
2730 mac_rate_stru avail_op_rates;
2731 hi_u8 mac_vap_rate_num;
2732 hi_u8 mac_user_rate_num;
2733 hi_u8 vap_rate_idx;
2734 hi_u8 user_rate_idx;
2735 hi_u8 user_avail_rate_idx = 0;
2736
2737 /* 获取VAP和USER速率的结构体指针 */
2738 mac_user = hmac_user->base_user;
2739 mac_vap_rate = &(mac_vap->curr_sup_rates);
2740 mac_user_rate = &(hmac_user->op_rates);
2741 if (memset_s((hi_u8 *)(&avail_op_rates), sizeof(mac_rate_stru), 0, sizeof(mac_rate_stru)) != EOK) {
2742 return;
2743 }
2744
2745 mac_vap_rate_num = mac_vap_rate->rate.rs_nrates;
2746 mac_user_rate_num = mac_user_rate->rs_nrates;
2747
2748 for (vap_rate_idx = 0; vap_rate_idx < mac_vap_rate_num; vap_rate_idx++) {
2749 for (user_rate_idx = 0; user_rate_idx < mac_user_rate_num; user_rate_idx++) {
2750 if ((mac_vap_rate->rate.ast_rs_rates[vap_rate_idx].mac_rate > 0) &&
2751 ((mac_vap_rate->rate.ast_rs_rates[vap_rate_idx].mac_rate & 0x7F) ==
2752 (mac_user_rate->auc_rs_rates[user_rate_idx] & 0x7F))) {
2753 avail_op_rates.auc_rs_rates[user_avail_rate_idx] =
2754 mac_vap_rate->rate.ast_rs_rates[vap_rate_idx].mac_rate;
2755 user_avail_rate_idx++;
2756 avail_op_rates.rs_nrates++;
2757 }
2758 }
2759 }
2760
2761 mac_user_set_avail_op_rates(mac_user, avail_op_rates.rs_nrates, avail_op_rates.auc_rs_rates);
2762 if (avail_op_rates.rs_nrates == 0) {
2763 oam_warning_log0(mac_vap->vap_id, OAM_SF_ANY, "{hmac_vap_set_user_avail_rates::uc_avail_op_rates_num=0.}");
2764 }
2765 }
2766
2767 /* ****************************************************************************
2768 功能描述 : 处理ht_cap_ie,并更新相应的vap及user能力
2769 修改历史 :
2770 1.日 期 : 2015年6月8日
2771 作 者 : HiSilicon
2772 修改内容 : 新生成函数
2773 **************************************************************************** */
hmac_proc_ht_cap_ie(mac_vap_stru * mac_vap,mac_user_stru * mac_user,const hi_u8 * puc_ht_cap_ie)2774 hi_u32 hmac_proc_ht_cap_ie(mac_vap_stru *mac_vap, mac_user_stru *mac_user, const hi_u8 *puc_ht_cap_ie)
2775 {
2776 hi_u16 us_offset = 0;
2777 hi_u8 mcs_bmp_index;
2778
2779 if ((mac_vap == HI_NULL) || (mac_user == HI_NULL) || (puc_ht_cap_ie == HI_NULL)) {
2780 oam_warning_log3(0, OAM_SF_ANY, "{hmac_proc_ht_cap_ie::PARAM NULL! vap=[%p],user=[%p],cap_ie=[%p].}",
2781 (uintptr_t)mac_vap, (uintptr_t)mac_user, (uintptr_t)puc_ht_cap_ie);
2782 return HI_ERR_CODE_PTR_NULL;
2783 }
2784
2785 /* 至少支持11n才进行后续的处理 */
2786 if (HI_FALSE == mac_mib_get_high_throughput_option_implemented(mac_vap)) {
2787 return HI_SUCCESS;
2788 }
2789
2790 mac_user_set_ht_capable(mac_user, HI_TRUE);
2791
2792 mac_user_ht_hdl_stru *ht_hdl = &mac_user->ht_hdl;
2793
2794 /* 带有 HT Capability Element 的 AP,标示它具有HT capable. */
2795 ht_hdl->ht_capable = HI_TRUE;
2796
2797 us_offset += MAC_IE_HDR_LEN;
2798
2799 /* ****************************************** */
2800 /* 解析 HT Capabilities Info Field */
2801 /* ****************************************** */
2802 hi_u16 us_ht_cap_info = hi_makeu16(puc_ht_cap_ie[us_offset], puc_ht_cap_ie[us_offset + 1]);
2803
2804 /* 检查STA所支持的LDPC编码能力 B0,0:不支持,1:支持 */
2805 ht_hdl->ht_capinfo.ldpc_coding_cap = (us_ht_cap_info & BIT0);
2806
2807 /* 提取AP所支持的带宽能力 */
2808 ht_hdl->ht_capinfo.supported_channel_width = ((us_ht_cap_info & BIT1) >> 1);
2809
2810 /* 检查空间复用节能模式 B2~B3 */
2811 ht_hdl->ht_capinfo.sm_power_save = mac_ie_proc_sm_power_save_field((hi_u8)(us_ht_cap_info & (BIT2 | BIT3)));
2812
2813 /* 提取AP支持Greenfield情况 */
2814 ht_hdl->ht_capinfo.ht_green_field = ((us_ht_cap_info & BIT4) >> 4); /* 右移4位 */
2815
2816 /* 提取AP支持20MHz Short-GI情况 */
2817 ht_hdl->ht_capinfo.short_gi_20mhz = ((us_ht_cap_info & BIT5) >> 5); /* 右移5位 */
2818
2819 /* 提取AP支持40MHz Short-GI情况 */
2820 ht_hdl->ht_capinfo.short_gi_40mhz = ((us_ht_cap_info & BIT6) >> 6); /* 右移6位 */
2821
2822 /* 提取AP支持STBC PPDU情况 */
2823 ht_hdl->ht_capinfo.rx_stbc = (hi_u8)((us_ht_cap_info & 0x30) >> 4); /* 右移4位 */
2824
2825 /* 提取AP 40M上DSSS/CCK的支持情况 */
2826 ht_hdl->ht_capinfo.dsss_cck_mode_40mhz = ((us_ht_cap_info & BIT12) >> 12); /* 右移12位 */
2827
2828 /* 提取AP L-SIG TXOP 保护的支持情况 */
2829 ht_hdl->ht_capinfo.lsig_txop_protection = ((us_ht_cap_info & BIT15) >> 15); /* 右移15位 */
2830
2831 us_offset += MAC_HT_CAPINFO_LEN;
2832
2833 /* ****************************************** */
2834 /* 解析 A-MPDU Parameters Field */
2835 /* ****************************************** */
2836 /* 提取 Maximum Rx A-MPDU factor (B1 - B0) */
2837 ht_hdl->max_rx_ampdu_factor = (puc_ht_cap_ie[us_offset] & 0x03);
2838
2839 /* 提取 Minmum Rx A-MPDU factor (B3 - B2) */
2840 ht_hdl->min_mpdu_start_spacing = (puc_ht_cap_ie[us_offset] >> 2) & 0x07;
2841
2842 us_offset += MAC_HT_AMPDU_PARAMS_LEN;
2843
2844 /* ****************************************** */
2845 /* 解析 Supported MCS Set Field */
2846 /* ****************************************** */
2847 for (mcs_bmp_index = 0; mcs_bmp_index < WLAN_HT_MCS_BITMASK_LEN; mcs_bmp_index++) {
2848 ht_hdl->rx_mcs_bitmask[mcs_bmp_index] =
2849 (mac_vap->mib_info->supported_mcstx.auc_dot11_supported_mcs_tx_value[mcs_bmp_index]) &
2850 (*(hi_u8 *)(puc_ht_cap_ie + us_offset + mcs_bmp_index));
2851 }
2852
2853 ht_hdl->rx_mcs_bitmask[WLAN_HT_MCS_BITMASK_LEN - 1] &= 0x1F;
2854
2855 us_offset += MAC_HT_SUP_MCS_SET_LEN;
2856
2857 /* ****************************************** */
2858 /* 解析 HT Extended Capabilities Info Field */
2859 /* ****************************************** */
2860 us_ht_cap_info = hi_makeu16(puc_ht_cap_ie[us_offset], puc_ht_cap_ie[us_offset + 1]);
2861
2862 /* 提取 HTC support Information */
2863 ht_hdl->htc_support = ((us_ht_cap_info & BIT10) >> 10); /* 右移10位 */
2864
2865 us_offset += MAC_HT_EXT_CAP_LEN;
2866
2867 /* ****************************************** */
2868 /* 解析 Tx Beamforming Field */
2869 /* ****************************************** */
2870 hi_u16 us_tmp_info_elem = hi_makeu16(puc_ht_cap_ie[us_offset], puc_ht_cap_ie[us_offset + 1]);
2871 hi_u16 us_tmp_txbf_low = hi_makeu16(puc_ht_cap_ie[us_offset + 2], puc_ht_cap_ie[us_offset + 3]); /* 2 3 偏置项 */
2872 hi_u32 tmp_txbf_elem = hi_makeu32(us_tmp_info_elem, us_tmp_txbf_low);
2873 mac_ie_txbf_set_ht_hdl(ht_hdl, tmp_txbf_elem);
2874
2875 return HI_SUCCESS;
2876 }
2877
2878 #ifdef __cplusplus
2879 #if __cplusplus
2880 }
2881 #endif
2882 #endif
2883