• 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 "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