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 "oal_ext_if.h"
23 #include "frw_timer.h"
24 #include "mac_vap.h"
25 #include "hmac_blockack.h"
26 #include "hmac_main.h"
27 #include "hmac_rx_data.h"
28 #include "hmac_mgmt_bss_comm.h"
29 #include "hmac_user.h"
30 #include "mac_pm_driver.h"
31 #include "hmac_tx_data.h"
32
33 #ifdef __cplusplus
34 #if __cplusplus
35 extern "C" {
36 #endif
37 #endif
38
39 /* ****************************************************************************
40 2 函数实现
41 **************************************************************************** */
42 /* ****************************************************************************
43 功能描述 : 判断seq1是否小于seq2
44 修改历史 :
45 1.日 期 : 2013年4月11日
46 作 者 : HiSilicon
47 修改内容 : 新生成函数
48 **************************************************************************** */
hmac_ba_seqno_lt(hi_u16 us_seq1,hi_u16 us_seq2)49 static hi_u8 hmac_ba_seqno_lt(hi_u16 us_seq1, hi_u16 us_seq2)
50 {
51 if (((us_seq1 < us_seq2) && ((us_seq2 - us_seq1) < DMAC_BA_MAX_SEQNO_BY_TWO)) ||
52 ((us_seq1 > us_seq2) && ((us_seq1 - us_seq2) > DMAC_BA_MAX_SEQNO_BY_TWO))) {
53 return HI_TRUE;
54 }
55 return HI_FALSE;
56 }
57
58 /* ****************************************************************************
59 功能描述 : 判断seq1是否小于或等于seq2
60 修改历史 :
61 1.日 期 : 2014年8月15日
62 作 者 : HiSilicon
63 修改内容 : 新生成函数
64 **************************************************************************** */
hmac_ba_rx_seqno_leq(hi_u16 us_seq1,hi_u16 us_seq2)65 static hi_u8 hmac_ba_rx_seqno_leq(hi_u16 us_seq1, hi_u16 us_seq2)
66 {
67 if (((us_seq1 <= us_seq2) && ((us_seq2 - us_seq1) < DMAC_BA_MAX_SEQNO_BY_TWO)) ||
68 ((us_seq1 > us_seq2) && ((us_seq1 - us_seq2) > DMAC_BA_MAX_SEQNO_BY_TWO))) {
69 return HI_TRUE;
70 }
71 return HI_FALSE;
72 }
73
74 /* ****************************************************************************
75 功能描述 : 判断 us_seqno在bitmap中的bit为是否为1
76 修改历史 :
77 1.日 期 : 2015年5月4日
78 作 者 : HiSilicon
79 修改内容 : 新生成函数
80 **************************************************************************** */
hmac_ba_isset(const hmac_ba_rx_stru * ba_rx_hdl,hi_u16 us_seqno)81 static hi_u8 hmac_ba_isset(const hmac_ba_rx_stru *ba_rx_hdl, hi_u16 us_seqno)
82 {
83 hi_u16 us_index;
84
85 if (hmac_baw_within(ba_rx_hdl->us_baw_head, HMAC_BA_BMP_SIZE, us_seqno)) {
86 us_index = us_seqno & (HMAC_BA_BMP_SIZE - 1);
87
88 if (hmac_ba_bit_isset(ba_rx_hdl->aul_rx_buf_bitmap, us_index)) {
89 return HI_TRUE;
90 }
91 }
92 return HI_FALSE;
93 }
94
95 /* ****************************************************************************
96 功能描述 : 置位 us_seqno对应的 BA rx_bitmap
97 修改历史 :
98 1.日 期 : 2016年3月11日
99 作 者 : HiSilicon
100 修改内容 : 新生成函数
101 **************************************************************************** */
hmac_ba_addto_rx_bitmap(hmac_ba_rx_stru * ba_rx_hdl,hi_u16 us_seqno)102 static hi_void hmac_ba_addto_rx_bitmap(hmac_ba_rx_stru *ba_rx_hdl, hi_u16 us_seqno)
103 {
104 hi_u16 us_index;
105
106 if (hmac_baw_within(ba_rx_hdl->us_baw_head, HMAC_BA_BMP_SIZE, us_seqno)) {
107 us_index = us_seqno & (HMAC_BA_BMP_SIZE - 1);
108 hmac_tx_buf_bitmap_set(ba_rx_hdl->aul_rx_buf_bitmap, us_index);
109 }
110 }
111
112 /* ****************************************************************************
113 功能描述 : 清除 BA会话 rx_bitmap位
114 修改历史 :
115 1.日 期 : 2016年3月11日
116 作 者 : HiSilicon
117 修改内容 : 新生成函数
118 **************************************************************************** */
hmac_ba_clear_rx_bitmap(hmac_ba_rx_stru * ba_rx_hdl)119 static hi_void hmac_ba_clear_rx_bitmap(hmac_ba_rx_stru *ba_rx_hdl)
120 {
121 hi_u16 us_index;
122
123 us_index = dmac_ba_seqno_sub(ba_rx_hdl->us_baw_head, 1) & (HMAC_BA_BMP_SIZE - 1);
124 hmac_tx_buf_bitmap_clr(ba_rx_hdl->aul_rx_buf_bitmap, us_index);
125 }
126
127 /* ****************************************************************************
128 功能描述 : updata rx bitmap
129 修改历史 :
130 1.日 期 : 2016年3月11日
131 作 者 : HiSilicon
132 修改内容 : 新生成函数
133 **************************************************************************** */
hmac_ba_update_rx_bitmap(const hmac_user_stru * hmac_user,const mac_ieee80211_frame_stru * frame_hdr)134 hi_void hmac_ba_update_rx_bitmap(const hmac_user_stru *hmac_user, const mac_ieee80211_frame_stru *frame_hdr)
135 {
136 hi_u8 is_4addr;
137 hi_u8 is_tods;
138 hi_u8 is_from_ds;
139 hi_u8 tid;
140 hmac_ba_rx_stru *ba_rx_hdl = HI_NULL;
141
142 /* 考虑四地址情况获取报文的tid */
143 is_tods = mac_hdr_get_to_ds((hi_u8 *)frame_hdr);
144 is_from_ds = mac_hdr_get_from_ds((hi_u8 *)frame_hdr);
145 is_4addr = is_tods && is_from_ds;
146 tid = mac_get_tid_value((hi_u8 *)frame_hdr, is_4addr);
147
148 ba_rx_hdl = hmac_user->ast_tid_info[tid].ba_rx_info;
149 if (ba_rx_hdl == HI_NULL) {
150 return;
151 }
152 if (ba_rx_hdl->ba_status != DMAC_BA_COMPLETE) {
153 return;
154 }
155
156 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
157 oal_spin_lock(&ba_rx_hdl->st_ba_lock);
158 #endif
159
160 while (hmac_ba_seqno_lt(ba_rx_hdl->us_baw_head,
161 dmac_ba_seqno_sub(ba_rx_hdl->us_baw_start, (HMAC_BA_BMP_SIZE - 1))) == HI_TRUE) {
162 ba_rx_hdl->us_baw_head = dmac_ba_seqno_add(ba_rx_hdl->us_baw_head, 1);
163 hmac_ba_clear_rx_bitmap(ba_rx_hdl);
164 }
165
166 hmac_ba_addto_rx_bitmap(ba_rx_hdl, mac_get_seq_num((hi_u8 *)frame_hdr));
167
168 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
169 oal_spin_unlock(&ba_rx_hdl->st_ba_lock);
170 #endif
171
172 return;
173 }
174
175 /* ****************************************************************************
176 功能描述 : This function compares the given sequence number with the specified
177 upper and lower bounds and returns its position relative to them. 调用函数 :
178 修改历史 :
179 1.日 期 : 2013年4月11日
180 作 者 : HiSilicon
181 修改内容 : 新生成函数
182 **************************************************************************** */
hmac_ba_seqno_bound_chk(hi_u16 us_seq_lo,hi_u16 us_seq_hi,hi_u16 us_seq)183 static hi_u8 hmac_ba_seqno_bound_chk(hi_u16 us_seq_lo, hi_u16 us_seq_hi, hi_u16 us_seq)
184 {
185 hi_u8 lo_chk;
186 hi_u8 en_hi_chk;
187 hi_u8 chk_res = 0;
188
189 lo_chk = hmac_ba_rx_seqno_leq(us_seq_lo, us_seq);
190 en_hi_chk = hmac_ba_rx_seqno_leq(us_seq, us_seq_hi);
191 if ((lo_chk == HI_TRUE) && (en_hi_chk == HI_TRUE)) {
192 chk_res = DMAC_BA_BETWEEN_SEQLO_SEQHI;
193 } else if (en_hi_chk == HI_FALSE) {
194 chk_res = DMAC_BA_GREATER_THAN_SEQHI;
195 }
196 return chk_res;
197 }
198
199
200 /* ****************************************************************************
201 功能描述 : 根据us_seq_num从Re-order 中取出对应buff
202 修改历史 :
203 1.日 期 : 2013年4月11日
204 作 者 : HiSilicon
205 修改内容 : 新生成函数
206 **************************************************************************** */
hmac_remove_frame_from_reorder_q(hmac_ba_rx_stru * ba_rx_hdl,hi_u16 us_seq_num)207 static hmac_rx_buf_stru *hmac_remove_frame_from_reorder_q(hmac_ba_rx_stru *ba_rx_hdl, hi_u16 us_seq_num)
208 {
209 hi_u16 us_idx;
210 hmac_rx_buf_stru *rx_buff = HI_NULL;
211
212 us_idx = (us_seq_num & (WLAN_AMPDU_RX_BUFFER_SIZE - 1));
213 rx_buff = &(ba_rx_hdl->ast_re_order_list[us_idx]);
214 if ((rx_buff->in_use == 0) || (rx_buff->us_seq_num != us_seq_num)) {
215 return HI_NULL;
216 }
217 rx_buff->in_use = 0;
218 return rx_buff;
219 }
220
221 /* ****************************************************************************
222 功能描述 :This function reads out the TX-Dscr indexed by the specified sequence number in
223 the Retry-Q Ring-Buffer.
224 修改历史 :
225 1.日 期 : 2013年4月11日
226 作 者 : HiSilicon
227 修改内容 : 新生成函数
228 **************************************************************************** */
hmac_get_frame_from_reorder_q(hmac_ba_rx_stru * ba_rx_hdl,hi_u16 us_seq_num)229 static hmac_rx_buf_stru *hmac_get_frame_from_reorder_q(hmac_ba_rx_stru *ba_rx_hdl, hi_u16 us_seq_num)
230 {
231 hi_u16 us_idx;
232 hmac_rx_buf_stru *rx_buff = HI_NULL;
233
234 us_idx = (us_seq_num & (WLAN_AMPDU_RX_BUFFER_SIZE - 1));
235
236 rx_buff = &(ba_rx_hdl->ast_re_order_list[us_idx]);
237
238 if ((rx_buff->in_use == 0) || (rx_buff->us_seq_num != us_seq_num)) {
239 return HI_NULL;
240 }
241 return rx_buff;
242 }
243
244 /* ****************************************************************************
245 功能描述 : 获取Re-Order队列中的ba_buffer_frame
246 修改历史 :
247 1.日 期 : 2013年4月11日
248 作 者 : HiSilicon
249 修改内容 : 新生成函数
250 **************************************************************************** */
hmac_ba_buffer_frame_in_reorder(hmac_ba_rx_stru * ba_rx_hdl,hi_u16 us_seq_num)251 static hmac_rx_buf_stru *hmac_ba_buffer_frame_in_reorder(hmac_ba_rx_stru *ba_rx_hdl, hi_u16 us_seq_num)
252 {
253 hi_u16 us_buf_index;
254 hmac_rx_buf_stru *rx_buf = HI_NULL;
255
256 us_buf_index = (us_seq_num & (WLAN_AMPDU_RX_BUFFER_SIZE - 1));
257
258 rx_buf = &(ba_rx_hdl->ast_re_order_list[us_buf_index]);
259
260 if (rx_buf->in_use == 1) {
261 hmac_rx_free_netbuf_list(&rx_buf->netbuf_head, rx_buf->num_buf);
262 oam_info_log1(0, OAM_SF_BA, "{hmac_ba_buffer_frame_in_reorder::slot already used, seq[%d].}", us_seq_num);
263 } else {
264 ba_rx_hdl->mpdu_cnt++;
265 }
266
267 rx_buf->in_use = 1;
268
269 return rx_buf;
270 }
271
272 /* ****************************************************************************
273 功能描述 : 冲刷重排序缓冲区至给定的sequence number位置
274 修改历史 :
275 1.日 期 : 2014年11月25日
276 作 者 : HiSilicon
277 修改内容 : 新生成函数
278 **************************************************************************** */
hmac_ba_send_frames_with_gap(hmac_ba_rx_stru * ba_rx_hdl,oal_netbuf_head_stru * netbuf_header,hi_u16 us_last_seqnum,const mac_vap_stru * mac_vap)279 static hi_u32 hmac_ba_send_frames_with_gap(hmac_ba_rx_stru *ba_rx_hdl, oal_netbuf_head_stru *netbuf_header,
280 hi_u16 us_last_seqnum, const mac_vap_stru *mac_vap)
281 {
282 hi_u8 num_frms = 0;
283 hi_u16 us_seq_num;
284 hmac_rx_buf_stru *rx_buf = HI_NULL;
285 hi_u8 loop_index;
286 oal_netbuf_stru *netbuf = HI_NULL;
287
288 us_seq_num = ba_rx_hdl->us_baw_start;
289
290 while (us_seq_num != us_last_seqnum) {
291 rx_buf = hmac_remove_frame_from_reorder_q(ba_rx_hdl, us_seq_num);
292 if (rx_buf == HI_NULL) {
293 us_seq_num = dmac_ba_seqno_add(us_seq_num, 1);
294 continue;
295 }
296 ba_rx_hdl->mpdu_cnt--;
297 netbuf = oal_netbuf_peek(&rx_buf->netbuf_head);
298 if (oal_unlikely(netbuf == HI_NULL) && (mac_vap != HI_NULL)) {
299 us_seq_num = dmac_ba_seqno_add(us_seq_num, 1);
300 rx_buf->num_buf = 0;
301
302 continue;
303 }
304
305 for (loop_index = 0; loop_index < rx_buf->num_buf; loop_index++) {
306 netbuf = oal_netbuf_delist(&rx_buf->netbuf_head);
307 if (netbuf != HI_NULL) {
308 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
309 }
310 }
311 rx_buf->num_buf = 0;
312 num_frms++;
313 us_seq_num = dmac_ba_seqno_add(us_seq_num, 1);
314 }
315
316 if (ba_rx_hdl->mpdu_cnt != 0) {
317 oam_info_log1(0, OAM_SF_BA, "{hmac_ba_send_frames_with_gap::uc_mpdu_cnt=%d.}", ba_rx_hdl->mpdu_cnt);
318 }
319 return num_frms;
320 }
321
322 /* ****************************************************************************
323 功能描述 : All MSDUs with sequence number starting from the
324 start of the BA-Rx window are processed in order and
325 are added to the list which will be passed up to hmac.
326 Processing is stopped when the first missing MSDU is encountered.
327 修改历史 :
328 1.日 期 : 2013年4月11日
329 作 者 : HiSilicon
330 修改内容 : 新生成函数
331 **************************************************************************** */
hmac_ba_send_frames_in_order(hmac_ba_rx_stru * ba_rx_hdl,oal_netbuf_head_stru * netbuf_header,const mac_vap_stru * mac_vap)332 static hi_u16 hmac_ba_send_frames_in_order(hmac_ba_rx_stru *ba_rx_hdl, oal_netbuf_head_stru *netbuf_header,
333 const mac_vap_stru *mac_vap)
334 {
335 hi_u16 us_seq_num;
336 hmac_rx_buf_stru *rx_buf = HI_NULL;
337 hi_u8 loop_index;
338 oal_netbuf_stru *netbuf = HI_NULL;
339
340 us_seq_num = ba_rx_hdl->us_baw_start;
341 rx_buf = hmac_remove_frame_from_reorder_q(ba_rx_hdl, us_seq_num);
342 while (rx_buf != HI_NULL) {
343 ba_rx_hdl->mpdu_cnt--;
344 us_seq_num = hmac_ba_seqno_add(us_seq_num, 1);
345
346 netbuf = oal_netbuf_peek(&rx_buf->netbuf_head);
347 if ((netbuf == HI_NULL) && (mac_vap != HI_NULL)) {
348 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_send_frames_in_order::[%d] slot error.}",
349 us_seq_num);
350 rx_buf->num_buf = 0;
351 rx_buf = hmac_remove_frame_from_reorder_q(ba_rx_hdl, us_seq_num);
352 continue;
353 }
354
355 for (loop_index = 0; loop_index < rx_buf->num_buf; loop_index++) {
356 netbuf = oal_netbuf_delist(&rx_buf->netbuf_head);
357 if (netbuf != HI_NULL) {
358 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
359 }
360 }
361
362 rx_buf->num_buf = 0;
363 rx_buf = hmac_remove_frame_from_reorder_q(ba_rx_hdl, us_seq_num);
364 }
365
366 return us_seq_num;
367 }
368
369 /* ****************************************************************************
370 功能描述 : 处理接收到Blockack Req帧需要触发delba的处理函数
371 **************************************************************************** */
hmac_rx_bar_delba(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hi_u8 tidno,hi_u8 * puc_da)372 hi_void hmac_rx_bar_delba(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, hi_u8 tidno, hi_u8 *puc_da)
373 {
374 mac_action_mgmt_args_stru action_args;
375 hi_u32 ret;
376
377 action_args.category = MAC_ACTION_CATEGORY_BA;
378 action_args.action = MAC_BA_ACTION_DELBA;
379 action_args.arg1 = tidno; /* 该数据帧对应的TID号 */
380 action_args.arg2 = MAC_RECIPIENT_DELBA; /* DELBA中,触发删除BA会话的发起端 */
381 action_args.arg3 = MAC_POOR_CHANNEL; /* DELBA中代表删除reason */
382 action_args.puc_arg5 = puc_da; /* DELBA中代表目的地址 */
383
384 ret = hmac_mgmt_tx_action(hmac_vap, hmac_user, &action_args);
385 if (ret != HI_SUCCESS) {
386 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA, "hmac_rx_bar_delba return NON SUCCESS.");
387 }
388 }
389
390 /* ****************************************************************************
391 功能描述 : 将报文缓存至重排序队列
392 修改历史 :
393 1.日 期 : 2014年11月25日
394 作 者 : HiSilicon
395 修改内容 : 新生成函数
396 **************************************************************************** */
hmac_ba_buffer_rx_frame(hmac_ba_rx_stru * ba_rx_hdl,const hmac_rx_ctl_stru * cb_ctrl,oal_netbuf_head_stru * netbuf_header,hi_u16 us_seq_num,const mac_vap_stru * mac_vap)397 static hi_void hmac_ba_buffer_rx_frame(hmac_ba_rx_stru *ba_rx_hdl, const hmac_rx_ctl_stru *cb_ctrl,
398 oal_netbuf_head_stru *netbuf_header, hi_u16 us_seq_num, const mac_vap_stru *mac_vap)
399 {
400 hmac_rx_buf_stru *rx_netbuf = HI_NULL;
401 oal_netbuf_stru *netbuf = HI_NULL;
402 hi_u8 netbuf_index;
403
404 /* Get the pointer to the buffered packet */
405 rx_netbuf = hmac_ba_buffer_frame_in_reorder(ba_rx_hdl, us_seq_num);
406
407 /* Update the buffered receive packet details */
408 rx_netbuf->us_seq_num = us_seq_num;
409 rx_netbuf->num_buf = cb_ctrl->buff_nums; /* 标识该MPDU占用的netbuff个数,一般用于AMSDU */
410 rx_netbuf->rx_time = (hi_u32)hi_get_milli_seconds();
411
412 /* all buffers of this frame must be deleted from the buf list */
413 for (netbuf_index = rx_netbuf->num_buf; netbuf_index > 0; netbuf_index--) {
414 netbuf = oal_netbuf_delist(netbuf_header);
415 if (oal_unlikely(netbuf != HI_NULL)) {
416 oal_netbuf_add_to_list_tail(netbuf, &rx_netbuf->netbuf_head);
417 } else {
418 if (mac_vap != HI_NULL) {
419 oam_error_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_buffer_rx_frame:netbuff error in amsdu.}");
420 }
421 }
422 }
423 }
424
425 /* ****************************************************************************
426 功能描述 : 将重排序队列中可以上传的报文加到buf链表的尾部
427 修改历史 :
428 1.日 期 : 2013年4月11日
429 作 者 : HiSilicon
430 修改内容 : 新生成函数
431 **************************************************************************** */
hmac_ba_reorder_rx_data(hmac_ba_rx_stru * ba_rx_hdl,oal_netbuf_head_stru * netbuf_header,const mac_vap_stru * mac_vap,hi_u16 us_seq_num)432 static hi_void hmac_ba_reorder_rx_data(hmac_ba_rx_stru *ba_rx_hdl, oal_netbuf_head_stru *netbuf_header,
433 const mac_vap_stru *mac_vap, hi_u16 us_seq_num)
434 {
435 hi_u8 seqnum_pos;
436 hi_u16 us_temp_winend;
437 hi_u16 us_temp_winstart;
438
439 seqnum_pos = hmac_ba_seqno_bound_chk(ba_rx_hdl->us_baw_start, ba_rx_hdl->us_baw_end, us_seq_num);
440 if (seqnum_pos == DMAC_BA_BETWEEN_SEQLO_SEQHI) {
441 ba_rx_hdl->us_baw_start = hmac_ba_send_frames_in_order(ba_rx_hdl, netbuf_header, mac_vap);
442 ba_rx_hdl->us_baw_end = dmac_ba_seqno_add(ba_rx_hdl->us_baw_start, (ba_rx_hdl->us_baw_size - 1));
443 } else if (seqnum_pos == DMAC_BA_GREATER_THAN_SEQHI) {
444 us_temp_winend = us_seq_num;
445 us_temp_winstart = hmac_ba_seqno_sub(us_temp_winend, (ba_rx_hdl->us_baw_size - 1));
446
447 hmac_ba_send_frames_with_gap(ba_rx_hdl, netbuf_header, us_temp_winstart, mac_vap);
448 ba_rx_hdl->us_baw_start = us_temp_winstart;
449 ba_rx_hdl->us_baw_start = hmac_ba_send_frames_in_order(ba_rx_hdl, netbuf_header, mac_vap);
450 ba_rx_hdl->us_baw_end = hmac_ba_seqno_add(ba_rx_hdl->us_baw_start, (ba_rx_hdl->us_baw_size - 1));
451 } else {
452 oam_info_log3(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_reorder_rx_data::else branch seqno[%d] ws[%d] we[%d].}",
453 us_seq_num, ba_rx_hdl->us_baw_start, ba_rx_hdl->us_baw_end);
454 }
455 }
456
457 /* ****************************************************************************
458 功能描述 : 冲刷重排序队列
459 输入参数 : pst_rx_ba: 接收会话句柄
460 输出参数 : pst_rx_ba: 接收会话句柄
461 修改历史 :
462 1.日 期 : 2013年4月15日
463 作 者 : HiSilicon
464 修改内容 : 新生成函数
465 **************************************************************************** */
hmac_ba_flush_reorder_q(hmac_ba_rx_stru * rx_ba)466 static hi_void hmac_ba_flush_reorder_q(hmac_ba_rx_stru *rx_ba)
467 {
468 hmac_rx_buf_stru *rx_buf = HI_NULL;
469 hi_u16 us_index;
470
471 for (us_index = 0; us_index < WLAN_AMPDU_RX_BUFFER_SIZE; us_index++) {
472 rx_buf = &(rx_ba->ast_re_order_list[us_index]);
473
474 if (rx_buf->in_use == HI_TRUE) {
475 hmac_rx_free_netbuf_list(&rx_buf->netbuf_head, rx_buf->num_buf);
476
477 rx_buf->in_use = HI_FALSE;
478 rx_buf->num_buf = 0;
479 rx_ba->mpdu_cnt--;
480 }
481 }
482
483 if (rx_ba->mpdu_cnt != 0) {
484 oam_warning_log1(0, OAM_SF_BA, "{hmac_ba_flush_reorder_q:: %d mpdu cnt left.}", rx_ba->mpdu_cnt);
485 }
486 }
487
488 /* ****************************************************************************
489 功能描述 : 检查是否能做ba重排序处理
490 修改历史 :
491 1.日 期 : 2013年11月28日
492 作 者 : HiSilicon
493 修改内容 : 新生成函数
494 **************************************************************************** */
hmac_ba_check_rx_aggr(const mac_vap_stru * mac_vap,const mac_ieee80211_frame_stru * frame_hdr)495 static hi_u32 hmac_ba_check_rx_aggr(const mac_vap_stru *mac_vap, const mac_ieee80211_frame_stru *frame_hdr)
496 {
497 /* 该vap是否是ht */
498 if (mac_vap->mib_info->wlan_mib_sta_config.dot11_high_throughput_option_implemented == HI_FALSE) {
499 return HI_FAIL;
500 }
501 /* 判断该帧是不是qos帧 */
502 if (((hi_u8 *)frame_hdr)[0] != (WLAN_FC0_SUBTYPE_QOS | WLAN_FC0_TYPE_DATA)) {
503 return HI_FAIL;
504 }
505 return HI_SUCCESS;
506 }
507
508 /* ****************************************************************************
509 功能描述 : 过滤ampdu的每一个mpdu 有未确认报文需要入重传队列
510 返 回 值 : 非HI_SUCCESS:表示异常,后面处理直接Drop
511 修改历史 :
512 1.日 期 : 2014年11月25日
513 作 者 : HiSilicon
514 修改内容 : 新生成函数
515 **************************************************************************** */
hmac_ba_filter_serv(const mac_vap_stru * mac_vap,const hmac_user_stru * hmac_user,const hmac_rx_ctl_stru * cb_ctrl,const mac_ieee80211_frame_stru * frame_hdr,const hmac_filter_serv_info_stru * filter_serv_info)516 hi_u32 hmac_ba_filter_serv(const mac_vap_stru *mac_vap, const hmac_user_stru *hmac_user,
517 const hmac_rx_ctl_stru *cb_ctrl, const mac_ieee80211_frame_stru *frame_hdr,
518 const hmac_filter_serv_info_stru *filter_serv_info)
519 {
520 hi_u8 is_tods = mac_hdr_get_to_ds((hi_u8 *)frame_hdr);
521 hi_u8 is_from_ds = mac_hdr_get_from_ds((hi_u8 *)frame_hdr);
522 hi_u8 is_4addr = is_tods && is_from_ds;
523 hi_u8 tid = mac_get_tid_value((hi_u8 *)frame_hdr, is_4addr);
524
525 if (hmac_ba_check_rx_aggr(mac_vap, frame_hdr) != HI_SUCCESS) {
526 return HI_SUCCESS;
527 }
528
529 /* 考虑四地址情况获取报文的tid */
530 hmac_ba_rx_stru *ba_rx_hdl = hmac_user->ast_tid_info[tid].ba_rx_info;
531 if (ba_rx_hdl == HI_NULL) {
532 return HI_SUCCESS;
533 } else if (ba_rx_hdl->ba_status != DMAC_BA_COMPLETE) {
534 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_filter_serv::ba_status = %d.", ba_rx_hdl->ba_status);
535 return HI_SUCCESS;
536 }
537
538 /* 暂时保存BA窗口的序列号,用于鉴别是否有帧上报 */
539 hi_u16 us_baw_start_temp = ba_rx_hdl->us_baw_start;
540
541 hi_u16 us_seq_num = mac_get_seq_num((hi_u8 *)frame_hdr);
542
543 /* 兼容接收方向聚合和分片共存的情况 */
544 if ((hi_u8)frame_hdr->frame_control.more_frag == HI_TRUE) {
545 oam_warning_log1(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_filter_serv::[seq_num=%d] BA set UP!", us_seq_num);
546 return HI_SUCCESS;
547 }
548
549 /* duplicate frame判断 */
550 if (hmac_ba_seqno_lt(us_seq_num, ba_rx_hdl->us_baw_start) == HI_TRUE) {
551 /* 上次非定时器上报,直接删除duplicate frame帧,否则,直接上报 */
552 if ((ba_rx_hdl->timer_triggered == HI_FALSE) && (hmac_ba_isset(ba_rx_hdl, us_seq_num) == HI_TRUE)) {
553 /* 确实已经收到该帧 */
554 return HI_FAIL;
555 }
556 return HI_SUCCESS;
557 }
558
559 if (hmac_ba_seqno_lt(ba_rx_hdl->us_baw_tail, us_seq_num) == HI_TRUE) {
560 ba_rx_hdl->us_baw_tail = us_seq_num;
561 }
562
563 /* 接收到的帧的序列号等于BAW_START,并且缓存队列帧个数为0,则直接上报给HMAC */
564 if ((us_seq_num == ba_rx_hdl->us_baw_start) && (ba_rx_hdl->mpdu_cnt == 0)) {
565 ba_rx_hdl->us_baw_start = dmac_ba_seqno_add(ba_rx_hdl->us_baw_start, 1);
566 ba_rx_hdl->us_baw_end = dmac_ba_seqno_add(ba_rx_hdl->us_baw_end, 1);
567 } else {
568 /* Buffer the new MSDU */
569 *(filter_serv_info->pen_is_ba_buf) = HI_TRUE;
570
571 hmac_ba_buffer_rx_frame(ba_rx_hdl, cb_ctrl, filter_serv_info->netbuf_header, us_seq_num, mac_vap);
572
573 /* put the reordered netbufs to the end of the list */
574 hmac_ba_reorder_rx_data(ba_rx_hdl, filter_serv_info->netbuf_header, mac_vap, us_seq_num);
575
576 /* Check for Sync loss and flush the reorder queue when one is detected */
577 if ((ba_rx_hdl->us_baw_tail == dmac_ba_seqno_sub(ba_rx_hdl->us_baw_start, 1)) && (ba_rx_hdl->mpdu_cnt > 0)) {
578 oam_warning_log0(mac_vap->vap_id, OAM_SF_BA, "{hmac_ba_filter_serv::Sync loss flush the reorder queue.}");
579 hmac_ba_flush_reorder_q(ba_rx_hdl);
580 }
581 }
582
583 if (us_baw_start_temp != ba_rx_hdl->us_baw_start) {
584 ba_rx_hdl->timer_triggered = HI_FALSE;
585 }
586 return HI_SUCCESS;
587 }
588
589 /* ****************************************************************************
590 功能描述 : This function reorders the Reciver buffer and sends frames to the higher
591 layer on reception of a Block-Ack-Request frame. It also updates the
592 receiver buffer window.
593 修改历史 :
594 1.日 期 : 2014年11月29日
595 作 者 : HiSilicon
596 修改内容 : 新生成函数
597 **************************************************************************** */
hmac_reorder_ba_rx_buffer_bar(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hi_u8 tidno,hi_u16 us_start_seq_num,hi_u8 * puc_sa_addr)598 hi_void hmac_reorder_ba_rx_buffer_bar(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user, hi_u8 tidno,
599 hi_u16 us_start_seq_num, hi_u8 *puc_sa_addr)
600 {
601 oal_netbuf_head_stru netbuf_head;
602 hi_u8 seqnum_pos;
603 hmac_ba_rx_stru *rx_ba = HI_NULL;
604
605 rx_ba = hmac_user->ast_tid_info[tidno].ba_rx_info;
606 if (rx_ba == HI_NULL) {
607 hmac_rx_bar_delba(hmac_vap, hmac_user, tidno, puc_sa_addr);
608 return;
609 }
610 /* 针对 BAR 的SSN和窗口的start_num相等时,不需要移窗 */
611 if (rx_ba->us_baw_start == us_start_seq_num) {
612 return;
613 }
614
615 oal_netbuf_list_head_init(&netbuf_head);
616 seqnum_pos = hmac_ba_seqno_bound_chk(rx_ba->us_baw_start, rx_ba->us_baw_end, us_start_seq_num);
617 /* 针对BAR的SSN在窗口内才移窗 */
618 if (seqnum_pos == DMAC_BA_BETWEEN_SEQLO_SEQHI) {
619 hmac_ba_send_frames_with_gap(rx_ba, &netbuf_head, us_start_seq_num, hmac_vap->base_vap);
620 rx_ba->us_baw_start = us_start_seq_num;
621 rx_ba->us_baw_start = hmac_ba_send_frames_in_order(rx_ba, &netbuf_head, hmac_vap->base_vap);
622 rx_ba->us_baw_end = hmac_ba_seqno_add(rx_ba->us_baw_start, (rx_ba->us_baw_size - 1));
623
624 hmac_rx_lan_frame(&netbuf_head);
625 } else if (seqnum_pos == DMAC_BA_GREATER_THAN_SEQHI) {
626 /* 异常 */
627 oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_BA,
628 "{hmac_reorder_ba_rx_buffer_bar::receive a sn out of winsize bar, baw_start=%d baw_end=%d, seq_num=%d.}",
629 rx_ba->us_baw_start, rx_ba->us_baw_end, us_start_seq_num);
630 }
631 }
632
633 /* ****************************************************************************
634 功能描述 : 从重排序队列中获取skb链
635 修改历史 :
636 1.日 期 : 2014年5月21日
637 作 者 : HiSilicon
638 修改内容 : 新生成函数
639 **************************************************************************** */
hmac_ba_rx_prepare_bufflist(const hmac_vap_stru * hmac_vap,hmac_rx_buf_stru * rx_buf,oal_netbuf_head_stru * netbuf_head)640 static hi_u32 hmac_ba_rx_prepare_bufflist(const hmac_vap_stru *hmac_vap, hmac_rx_buf_stru *rx_buf,
641 oal_netbuf_head_stru *netbuf_head)
642 {
643 oal_netbuf_stru *netbuf = HI_NULL;
644 hi_u8 loop_index;
645
646 netbuf = oal_netbuf_peek(&rx_buf->netbuf_head);
647 if ((netbuf == HI_NULL) && (hmac_vap != HI_NULL)) {
648 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA, "{hmac_ba_rx_prepare_bufflist::pst_netbuf null.}");
649 return HI_ERR_CODE_PTR_NULL;
650 }
651
652 for (loop_index = 0; loop_index < rx_buf->num_buf; loop_index++) {
653 netbuf = oal_netbuf_delist(&rx_buf->netbuf_head);
654 if (netbuf != HI_NULL) {
655 oal_netbuf_add_to_list_tail(netbuf, netbuf_head);
656 } else {
657 if (hmac_vap != HI_NULL) {
658 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
659 "{hmac_ba_rx_prepare_bufflist::uc_num_buf in reorder list is error.}");
660 }
661 }
662 }
663 return HI_SUCCESS;
664 }
665
666 /* ****************************************************************************
667 功能描述 : 上报重排序队列中超时的报文
668 修改历史 :
669 1.日 期 : 2014年5月19日
670 作 者 : HiSilicon
671 修改内容 : 新生成函数
672 **************************************************************************** */
hmac_ba_send_reorder_timeout(hmac_ba_rx_stru * rx_ba,const hmac_vap_stru * hmac_vap,const hmac_ba_alarm_stru * alarm_data,hi_u16 * pus_timeout)673 static hi_u32 hmac_ba_send_reorder_timeout(hmac_ba_rx_stru *rx_ba, const hmac_vap_stru *hmac_vap,
674 const hmac_ba_alarm_stru *alarm_data, hi_u16 *pus_timeout)
675 {
676 hmac_rx_buf_stru *rx_buf = HI_NULL;
677 hi_u32 time_diff;
678 hi_u16 aus_rx_timeout[WLAN_WME_AC_BUTT] = {HMAC_BA_RX_BE_TIMEOUT, HMAC_BA_RX_BK_TIMEOUT,
679 HMAC_BA_RX_VI_TIMEOUT, HMAC_BA_RX_VO_TIMEOUT};
680
681 hi_u16 us_baw_head = rx_ba->us_baw_start;
682 hi_u16 us_baw_start = rx_ba->us_baw_start; /* 保存最初的窗口起始序列号 */
683 hi_u32 rx_timeout = (hi_u32)aus_rx_timeout[wlan_wme_tid_to_ac(alarm_data->tid)];
684 hi_u16 us_baw_end = hmac_ba_seqno_add(rx_ba->us_baw_tail, 1);
685 hi_u8 buff_count = 0;
686
687 oal_netbuf_head_stru netbuf_head;
688 oal_netbuf_list_head_init(&netbuf_head);
689
690 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
691 oal_spin_lock(&rx_ba->st_ba_lock);
692 #endif
693
694 while (us_baw_head != us_baw_end) {
695 rx_buf = hmac_get_frame_from_reorder_q(rx_ba, us_baw_head);
696 if (rx_buf == HI_NULL) {
697 buff_count++;
698 us_baw_head = hmac_ba_seqno_add(us_baw_head, 1);
699 continue;
700 }
701
702 time_diff = (hi_u32)hi_get_milli_seconds() - rx_buf->rx_time;
703 if (time_diff < rx_timeout) {
704 *pus_timeout = (hi_u16)(rx_timeout - time_diff);
705 break;
706 }
707
708 rx_ba->mpdu_cnt--;
709 rx_buf->in_use = 0;
710 buff_count++;
711 if (hmac_ba_rx_prepare_bufflist(hmac_vap, rx_buf, &netbuf_head) != HI_SUCCESS) {
712 us_baw_head = hmac_ba_seqno_add(us_baw_head, 1);
713 continue;
714 }
715 us_baw_head = hmac_ba_seqno_add(us_baw_head, 1);
716 rx_ba->us_baw_start = hmac_ba_seqno_add(rx_ba->us_baw_start, buff_count);
717 rx_ba->us_baw_end = hmac_ba_seqno_add(rx_ba->us_baw_start, (rx_ba->us_baw_size - 1));
718
719 buff_count = 0;
720 }
721
722 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
723 oal_spin_unlock(&rx_ba->st_ba_lock);
724 #endif
725
726 /* 判断本次定时器超时是否有帧上报 */
727 rx_ba->timer_triggered = (us_baw_start != rx_ba->us_baw_start) ? HI_TRUE : rx_ba->timer_triggered;
728 hmac_rx_lan_frame(&netbuf_head);
729
730 return HI_SUCCESS;
731 }
732
733 /* ****************************************************************************
734 功能描述 : ba会话超时处理
735 修改历史 :
736 1.日 期 : 2013年4月12日
737 作 者 : HiSilicon
738 修改内容 : 新生成函数
739 **************************************************************************** */
hmac_ba_timeout_fn(hi_void * arg)740 hi_u32 hmac_ba_timeout_fn(hi_void *arg)
741 {
742 hi_u8 *pm_wlan_need_stop_ba = mac_get_pm_wlan_need_stop_ba();
743 hi_u16 aus_rx_timeout[WLAN_WME_AC_BUTT] = {HMAC_BA_RX_BE_TIMEOUT, HMAC_BA_RX_BK_TIMEOUT,
744 HMAC_BA_RX_VI_TIMEOUT, HMAC_BA_RX_VO_TIMEOUT};
745
746 hmac_ba_alarm_stru *alarm_data = (hmac_ba_alarm_stru *)arg;
747 if ((alarm_data == HI_NULL) || (alarm_data->tid >= WLAN_TID_MAX_NUM)) {
748 oam_error_log1(0, OAM_SF_BA, "{hmac_ba_timeout_fn::invalid param,%p.}", (uintptr_t)alarm_data);
749 return HI_ERR_CODE_ARRAY_OVERFLOW;
750 }
751 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(alarm_data->vap_id);
752 if (hmac_vap == HI_NULL) {
753 oam_error_log1(0, OAM_SF_BA, "{hmac_ba_timeout_fn::pst_vap null. vap id %d.}", alarm_data->vap_id);
754 return HI_ERR_CODE_PTR_NULL;
755 }
756 hmac_ba_rx_stru *rx_ba = (hmac_ba_rx_stru *)alarm_data->ba;
757 if (rx_ba == HI_NULL) {
758 oam_error_log0(0, OAM_SF_BA, "{hmac_ba_timeout_fn::pst_rx_ba is null.}");
759 return HI_ERR_CODE_PTR_NULL;
760 }
761 hi_u16 us_timeout = aus_rx_timeout[wlan_wme_tid_to_ac(alarm_data->tid)];
762 if (rx_ba->mpdu_cnt > 0) {
763 hmac_ba_send_reorder_timeout(rx_ba, hmac_vap, alarm_data, &us_timeout);
764 }
765 if ((*pm_wlan_need_stop_ba) == HI_TRUE) {
766 return HI_SUCCESS;
767 }
768 frw_timer_restart_timer(&(rx_ba->ba_timer), us_timeout, HI_FALSE);
769 return HI_SUCCESS;
770 }
771
772 /* ****************************************************************************
773 功能描述 : 重置rx ba结构体
774 修改历史 :
775 1.日 期 : 2014年12月5日
776 作 者 : HiSilicon
777 修改内容 : 新生成函数
778 **************************************************************************** */
hmac_ba_reset_rx_handle(hmac_ba_rx_stru ** rx_ba,hi_u8 tid)779 hi_void hmac_ba_reset_rx_handle(hmac_ba_rx_stru **rx_ba, hi_u8 tid)
780 {
781 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
782 hmac_vap_stru *hmac_vap = HI_NULL;
783 #else
784 hmac_device_stru *hmac_dev = hmac_get_device_stru();
785 #endif
786 hi_bool need_del_lut = HI_TRUE;
787
788 if (oal_unlikely((*rx_ba == HI_NULL) || ((*rx_ba)->is_ba) != HI_TRUE)) {
789 oam_warning_log0(0, OAM_SF_BA, "{hmac_ba_reset_rx_handle::rx ba not set yet.}");
790 return;
791 }
792 if (tid >= WLAN_TID_MAX_NUM) {
793 oam_error_log1(0, OAM_SF_BA, "{hmac_ba_reset_rx_handle::tid %d overflow.}", tid);
794 return;
795 }
796
797 /* Step1: disable the flag of ba session */
798 (*rx_ba)->is_ba = HI_FALSE;
799
800 /* Step2: flush reorder q */
801 hmac_ba_flush_reorder_q(*rx_ba);
802 if ((*rx_ba)->lut_index == DMAC_INVALID_BA_LUT_INDEX) {
803 need_del_lut = HI_FALSE;
804 oam_warning_log1(0, OAM_SF_BA, "{hmac_ba_reset_rx_handle::no del, lut idx[%d]}\n", (*rx_ba)->lut_index);
805 }
806
807 /* Step3: if lut index is valid, del lut index alloc before */
808 if (((*rx_ba)->ba_policy == MAC_BA_POLICY_IMMEDIATE) && (need_del_lut == HI_TRUE)) {
809 oal_del_lut_index(hmac_dev->auc_rx_ba_lut_idx_table, (*rx_ba)->lut_index);
810 }
811
812 /* Step4: dec the ba session cnt maitence in device struc */
813 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
814 hmac_vap = hmac_vap_get_vap_stru((*rx_ba)->alarm_data.vap_id);
815 if (oal_unlikely(hmac_vap == HI_NULL)) {
816 oam_error_log0(0, OAM_SF_BA, "{hmac_ba_reset_rx_handle::pst_hmac_vap is null.}");
817 oal_mem_free(*rx_ba);
818 *rx_ba = HI_NULL;
819 return;
820 }
821 hmac_rx_ba_session_decr(hmac_vap);
822 #else
823 hmac_rx_ba_session_decr(hmac_dev);
824 #endif
825 /* Step5: Del Timer */
826 if ((*rx_ba)->ba_timer.is_registerd == HI_TRUE) {
827 frw_timer_immediate_destroy_timer(&((*rx_ba)->ba_timer));
828 }
829 /* Step6: Free rx handle */
830 oal_mem_free(*rx_ba);
831 *rx_ba = HI_NULL;
832 }
833
834 /* ****************************************************************************
835 功能描述 : 重置tx ba结构体
836 修改历史 :
837 1.日 期 : 2019年5月29日
838 作 者 : HiSilicon
839 修改内容 : 新生成函数
840 **************************************************************************** */
hmac_ba_reset_tx_handle(hmac_ba_tx_stru ** tx_ba)841 hi_void hmac_ba_reset_tx_handle(hmac_ba_tx_stru **tx_ba)
842 {
843 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
844 hmac_vap_stru *hmac_vap = HI_NULL;
845 #else
846 hmac_device_stru *hmac_dev = hmac_get_device_stru();
847 #endif
848
849 if (oal_unlikely(*tx_ba == HI_NULL)) {
850 oam_warning_log0(0, OAM_SF_BA, "{hmac_ba_reset_tx_handle::tx ba not set yet.}");
851 return;
852 }
853 /* 清除发送方向会话句柄 */
854 if ((*tx_ba)->addba_timer.is_registerd == HI_TRUE) {
855 frw_timer_immediate_destroy_timer(&((*tx_ba)->addba_timer));
856 }
857 /* 存在TX BA会话句柄,要-- */
858 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
859 hmac_vap = hmac_vap_get_vap_stru((*tx_ba)->alarm_data.vap_id);
860 if (oal_unlikely(hmac_vap == HI_NULL)) {
861 oam_error_log0(0, OAM_SF_BA, "{hmac_ba_reset_tx_handle::pst_hmac_vap is null.}");
862 oal_mem_free(*tx_ba);
863 *tx_ba = HI_NULL;
864 return;
865 }
866 hmac_tx_ba_session_decr(hmac_vap);
867 #else
868 hmac_tx_ba_session_decr(hmac_dev);
869 #endif
870 oal_mem_free(*tx_ba);
871 *tx_ba = HI_NULL;
872 }
873
874 /* ****************************************************************************
875 功能描述 : 从空口接收ADDBA_REQ帧的处理函数
876 修改历史 :
877 1.日 期 : 2014年11月28日
878 作 者 : HiSilicon
879 修改内容 : 新生成函数
880 **************************************************************************** */
hmac_mgmt_check_set_rx_ba_ok(const hmac_vap_stru * hmac_vap,hmac_ba_rx_stru * ba_rx_info,hmac_device_stru * hmac_dev)881 hi_u8 hmac_mgmt_check_set_rx_ba_ok(const hmac_vap_stru *hmac_vap, hmac_ba_rx_stru *ba_rx_info,
882 hmac_device_stru *hmac_dev)
883 {
884 /* 立即块确认判断 */
885 if (ba_rx_info->ba_policy == MAC_BA_POLICY_IMMEDIATE) {
886 if (hmac_vap->base_vap->mib_info->wlan_mib_sta_config.dot11_immediate_block_ack_option_implemented ==
887 HI_FALSE) {
888 /* 不支持立即块确认 */
889 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
890 "{hmac_mgmt_check_set_rx_ba_ok::not support immediate Block Ack.}");
891 return MAC_INVALID_REQ_PARAMS;
892 } else {
893 if (ba_rx_info->back_var != MAC_BACK_COMPRESSED) {
894 /* 不支持非压缩块确认 */
895 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
896 "{hmac_mgmt_check_set_rx_ba_ok::not support non-Compressed Block Ack.}");
897 return MAC_REQ_DECLINED;
898 }
899 }
900 } else if (ba_rx_info->ba_policy == MAC_BA_POLICY_DELAYED) {
901 /* 延迟块确认不支持 */
902 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
903 "{hmac_mgmt_check_set_rx_ba_ok::not support delayed Block Ack.}");
904 return MAC_INVALID_REQ_PARAMS;
905 }
906 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
907 if (hmac_vap->rx_ba_session_num > WLAN_MAX_RX_BA) {
908 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_BA,
909 "{hmac_mgmt_check_set_rx_ba_ok::uc_rx_ba_session_num[%d] is up to max.}\r\n", hmac_vap->rx_ba_session_num);
910 return MAC_REQ_DECLINED;
911 }
912 #else
913 if (hmac_dev->rx_ba_session_num > WLAN_MAX_RX_BA) {
914 oam_warning_log1(hmac_vap->base_vap->vap_id, OAM_SF_BA,
915 "{hmac_mgmt_check_set_rx_ba_ok::uc_rx_ba_session_num[%d] is up to max.}\r\n", hmac_dev->rx_ba_session_num);
916 return MAC_REQ_DECLINED;
917 }
918 #endif
919 /* 获取BA LUT INDEX */
920 ba_rx_info->lut_index = oal_get_lut_index(hmac_dev->auc_rx_ba_lut_idx_table,
921 HMAC_BA_LUT_IDX_BMAP_LEN, HAL_MAX_BA_LUT_SIZE);
922 /* LUT index表已满 */
923 if (ba_rx_info->lut_index == DMAC_INVALID_BA_LUT_INDEX) {
924 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_BA,
925 "{hmac_mgmt_check_set_rx_ba_ok::ba lut index table full.}\n");
926 return MAC_REQ_DECLINED;
927 }
928
929 return MAC_SUCCESSFUL_STATUSCODE;
930 }
931
932 /* ****************************************************************************
933 功能描述 : 接收到Blockack Req帧的处理函数
934 修改历史 :
935 1.日 期 : 2015年1月3日
936 作 者 : HiSilicon
937 修改内容 : 新生成函数
938 **************************************************************************** */
hmac_up_rx_bar(hmac_vap_stru * hmac_vap,const hmac_rx_ctl_stru * rx_ctl)939 hi_void hmac_up_rx_bar(hmac_vap_stru *hmac_vap, const hmac_rx_ctl_stru *rx_ctl)
940 {
941 hi_u8 *puc_payload = HI_NULL;
942 mac_ieee80211_frame_stru *frame_hdr = HI_NULL;
943 hi_u8 *sa_mac_addr = HI_NULL;
944 hi_u8 tidno;
945 hmac_user_stru *hmac_user = HI_NULL;
946 hi_u16 us_start_seqnum;
947
948 frame_hdr = (mac_ieee80211_frame_stru *)(rx_ctl->pul_mac_hdr_start_addr);
949 sa_mac_addr = frame_hdr->auc_address2;
950
951 /* 获取用户指针 */
952 hmac_user = mac_vap_get_hmac_user_by_addr(hmac_vap->base_vap, sa_mac_addr, WLAN_MAC_ADDR_LEN);
953 if (hmac_user == HI_NULL) {
954 oam_warning_log0(0, OAM_SF_ANY, "{hmac_up_rx_bar::pst_ta_user is null.}");
955 return;
956 }
957
958 /* 获取帧头和payload指针 */
959 puc_payload = (hi_u8 *)(rx_ctl->pul_mac_hdr_start_addr) + rx_ctl->mac_header_len;
960
961 /* *********************************************************************** */
962 /* BlockAck Request Frame Format */
963 /* -------------------------------------------------------------------- */
964 /* |Frame Control|Duration|DA|SA|BAR Control|BlockAck Starting |FCS| */
965 /* | | | | | |Sequence number | | */
966 /* -------------------------------------------------------------------- */
967 /* | 2 |2 |6 |6 |2 |2 |4 | */
968 /* -------------------------------------------------------------------- */
969 /* */
970 /* *********************************************************************** */
971 tidno = (puc_payload[1] & 0xF0) >> 4; /* 1:下标,4:右移4位 */
972 us_start_seqnum = mac_get_bar_start_seq_num(puc_payload);
973
974 hmac_reorder_ba_rx_buffer_bar(hmac_vap, hmac_user, tidno, us_start_seqnum, sa_mac_addr);
975 }
976
977 #ifdef _PRE_WLAN_FEATURE_AMPDU_VAP
hmac_is_device_ba_setup(hi_void)978 hi_u8 hmac_is_device_ba_setup(hi_void)
979 {
980 hi_u8 vap_id;
981 hmac_vap_stru *hmac_vap = HI_NULL;
982
983 for (vap_id = 0; vap_id < WLAN_VAP_NUM_PER_DEVICE; vap_id++) {
984 hmac_vap = hmac_vap_get_vap_stru(vap_id);
985 if (hmac_vap == HI_NULL) {
986 oam_error_log0(0, OAM_SF_ANY, "{hmac_is_device_ba_setup pst_mac_vap is null.}");
987 continue;
988 }
989 if ((hmac_vap->base_vap->vap_state != MAC_VAP_STATE_UP) &&
990 (hmac_vap->base_vap->vap_state != MAC_VAP_STATE_PAUSE)) {
991 continue;
992 }
993 if ((hmac_vap->tx_ba_session_num != 0) || (hmac_vap->rx_ba_session_num != 0)) {
994 return HI_TRUE;
995 }
996 }
997 return HI_FALSE;
998 }
999 #else
hmac_is_device_ba_setup(hi_void)1000 hi_u8 hmac_is_device_ba_setup(hi_void)
1001 {
1002 hmac_device_stru *hmac_dev = hmac_get_device_stru();
1003
1004 if ((hmac_dev->tx_ba_session_num != 0) || (hmac_dev->rx_ba_session_num != 0)) {
1005 return HI_TRUE;
1006 }
1007 return HI_FALSE;
1008 }
1009 #endif
1010
1011 /* ****************************************************************************
1012 功能描述 : 创建BA 会话事件处理函数
1013 修改历史 :
1014 1.日 期 : 2013年11月21日
1015 作 者 : HiSilicon
1016 修改内容 : 新生成函数
1017 **************************************************************************** */
hmac_create_ba_event(frw_event_mem_stru * event_mem)1018 hi_u32 hmac_create_ba_event(frw_event_mem_stru *event_mem)
1019 {
1020 frw_event_stru *event = HI_NULL;
1021 hmac_user_stru *hmac_user = HI_NULL;
1022 hmac_vap_stru *hmac_vap = HI_NULL;
1023 hmac_tx_ctl_stru cb;
1024 dmac_to_hmac_ctx_event_stru *create_ba_event = HI_NULL;
1025
1026 event = (frw_event_stru *)event_mem->puc_data;
1027
1028 create_ba_event = (dmac_to_hmac_ctx_event_stru *)event->auc_event_data;
1029
1030 hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(create_ba_event->user_index);
1031 if (hmac_user == HI_NULL) {
1032 oam_error_log0(event->event_hdr.vap_id, OAM_SF_ANY, "{hmac_create_ba_event::pst_hmac_user null.}");
1033 return HI_ERR_CODE_PTR_NULL;
1034 }
1035
1036 hmac_vap = hmac_vap_get_vap_stru(create_ba_event->vap_id);
1037 if (hmac_vap == HI_NULL) {
1038 oam_error_log0(event->event_hdr.vap_id, OAM_SF_ANY, "{hmac_create_ba_event::pst_hmac_vap null.}");
1039 return HI_ERR_CODE_PTR_NULL;
1040 }
1041 cb.tid = create_ba_event->tid;
1042
1043 hmac_tx_ba_setup(hmac_vap, hmac_user, cb.tid);
1044
1045 return HI_SUCCESS;
1046 }
1047
1048 /* ****************************************************************************
1049 功能描述 : 删除 BA会话事件处理函数
1050 修改历史 :
1051 1.日 期 : 2013年11月21日
1052 作 者 : HiSilicon
1053 修改内容 : 新生成函数
1054 **************************************************************************** */
hmac_del_ba_event(frw_event_mem_stru * event_mem)1055 hi_u32 hmac_del_ba_event(frw_event_mem_stru *event_mem)
1056 {
1057 hi_u8 del_fail_flag = HI_FALSE;
1058 mac_action_mgmt_args_stru action_args; /* 用于填写ACTION帧的参数 */
1059 hmac_tid_stru *hmac_tid = HI_NULL;
1060 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
1061 dmac_to_hmac_ctx_event_stru *del_ba_event = (dmac_to_hmac_ctx_event_stru *)event->auc_event_data;
1062 hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(del_ba_event->user_index);
1063 hi_u8 tid;
1064
1065 if ((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL)) {
1066 oam_error_log0(0, OAM_SF_ANY, "{hmac_del_ba_event::pst_hmac_user null.}");
1067 return HI_ERR_CODE_PTR_NULL;
1068 }
1069
1070 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(del_ba_event->vap_id);
1071 if (hmac_vap == HI_NULL) {
1072 oam_error_log0(0, OAM_SF_ANY, "{hmac_del_ba_event::pst_hmac_vap null.}");
1073 return HI_ERR_CODE_PTR_NULL;
1074 }
1075
1076 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1077 hmac_user->base_user->cur_protocol_mode = del_ba_event->cur_protocol;
1078 hi_u32 ret = hmac_config_user_info_syn(hmac_vap->base_vap, hmac_user->base_user);
1079 if (ret != HI_SUCCESS) {
1080 return ret;
1081 }
1082 #endif
1083
1084 for (tid = 0; tid < WLAN_TID_MAX_NUM; tid++) {
1085 hmac_tid = &hmac_user->ast_tid_info[tid];
1086 if (hmac_tid->ba_tx_info == HI_NULL) {
1087 continue; /* 指针为空 未建立BA */
1088 }
1089 action_args.category = MAC_ACTION_CATEGORY_BA;
1090 action_args.action = MAC_BA_ACTION_DELBA;
1091 action_args.arg1 = tid; /* 该数据帧对应的TID号 */
1092 action_args.arg2 = MAC_ORIGINATOR_DELBA; /* ADDBA_REQ中,buffer_size的默认大小 */
1093 action_args.arg3 = MAC_UNSPEC_REASON; /* BA会话的确认策略 */
1094 action_args.puc_arg5 = hmac_user->base_user->user_mac_addr; /* ba会话对应的user */
1095
1096 /* 删除BA会话 */
1097 if (hmac_mgmt_tx_action(hmac_vap, hmac_user, &action_args) != HI_SUCCESS) {
1098 oam_warning_log2(hmac_vap->base_vap->vap_id, OAM_SF_ANY,
1099 "{hmac_del_ba_event::hmac_mgmt_tx_action failed,tid[%d],user id[%d].}", tid, del_ba_event->user_index);
1100 del_fail_flag = HI_TRUE;
1101 continue;
1102 }
1103 }
1104
1105 if (del_fail_flag) {
1106 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_ANY,
1107 "{hmac_del_ba_event::send delba occur fail, notify alg resume old protocol!.}");
1108 return HI_FAIL;
1109 }
1110 return HI_SUCCESS;
1111 }
1112
1113 #ifdef __cplusplus
1114 #if __cplusplus
1115 }
1116 #endif
1117 #endif
1118