• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 /* ****************************************************************************
20   1 头文件包含
21 **************************************************************************** */
22 #include "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