1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "mac_frame.h"
23 #include "mac_data.h"
24 #include "hmac_rx_data.h"
25 #include "dmac_ext_if.h"
26 #include "hmac_vap.h"
27 #include "hmac_ext_if.h"
28 #include "oam_ext_if.h"
29 #include "oal_ext_if.h"
30 #include "oal_net.h"
31 #include "hmac_frag.h"
32 #include "hmac_11i.h"
33 #include "mac_vap.h"
34 #include "hmac_blockack.h"
35 #include "hmac_mgmt_bss_comm.h"
36 #include "hcc_hmac_if.h"
37 #include "wal_cfg80211_apt.h"
38 #ifdef _PRE_WLAN_FEATURE_WAPI
39 #include "hmac_wapi.h"
40 #endif
41 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
42 #include "hmac_edca_opt.h"
43 #endif
44 #ifdef _PRE_HDF_LINUX
45 #include <linux/netdevice.h>
46 #endif
47
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif
52 #endif
53
54 /* ****************************************************************************
55 2 函数实现
56 **************************************************************************** */
57 #ifdef _PRE_WLAN_FEATURE_MESH
58 hi_void hmac_rx_process_data_mesh_tcp_ack_opt(hmac_vap_stru *hmac_vap, const oal_netbuf_head_stru *netbuf_header);
59 #endif
60
61 /* ****************************************************************************
62 功能描述 : 将MSDU转化为以太网格式的帧
63 输入参数 : pst_netbuf : 指向含有MSDU的netbuf的指针
64 puc_da : 目的地址
65 puc_sa : 源地址
66 修改历史 :
67 1.日 期 : 2013年12月19日
68 作 者 : HiSilicon
69 修改内容 : 新生成函数
70 **************************************************************************** */
hmac_rx_frame_80211_to_eth(oal_netbuf_stru * netbuf,const hi_u8 * da_mac_addr,hi_u8 da_addr_len,const hi_u8 * sa_mac_addr,hi_u8 sa_addr_len)71 static hi_void hmac_rx_frame_80211_to_eth(oal_netbuf_stru *netbuf, const hi_u8 *da_mac_addr, hi_u8 da_addr_len,
72 const hi_u8 *sa_mac_addr, hi_u8 sa_addr_len)
73 {
74 mac_ether_header_stru *ether_hdr = HI_NULL;
75 mac_llc_snap_stru *snap = HI_NULL;
76 hi_u16 us_ether_type;
77
78 snap = (mac_llc_snap_stru *)oal_netbuf_data(netbuf);
79 us_ether_type = snap->us_ether_type;
80
81 /* 将payload向前扩充6个字节,加上后面8个字节的snap头空间,构成以太网头的14字节空间 */
82 oal_netbuf_push(netbuf, HMAC_RX_DATA_ETHER_OFFSET_LENGTH);
83 ether_hdr = (mac_ether_header_stru *)oal_netbuf_data(netbuf);
84
85 ether_hdr->us_ether_type = us_ether_type;
86 if (memcpy_s(ether_hdr->auc_ether_shost, ETHER_ADDR_LEN, sa_mac_addr, sa_addr_len) != EOK) {
87 return;
88 }
89 if (memcpy_s(ether_hdr->auc_ether_dhost, ETHER_ADDR_LEN, da_mac_addr, da_addr_len) != EOK) {
90 return;
91 }
92 }
93
94 /* ****************************************************************************
95 功能描述 : 释放指定个数的netbuf
96 输入参数 : (1)期望删除的netbuf的起始指针
97 (2)需要删除的netbuf的个数
98 返 回 值 : 成功或者失败原因
99 修改历史 :
100 1.日 期 : 2012年12月6日
101 作 者 : HiSilicon
102 修改内容 : 新生成函数
103 **************************************************************************** */
hmac_rx_free_netbuf(oal_netbuf_stru * netbuf,hi_u16 us_nums)104 hi_void hmac_rx_free_netbuf(oal_netbuf_stru *netbuf, hi_u16 us_nums)
105 {
106 oal_netbuf_stru *netbuf_temp = HI_NULL;
107 hi_u16 us_netbuf_num;
108
109 if (oal_unlikely(netbuf == HI_NULL)) {
110 oam_error_log0(0, OAM_SF_RX, "{hmac_rx_free_netbuf::pst_netbuf null.}\r\n");
111 return;
112 }
113
114 for (us_netbuf_num = us_nums; us_netbuf_num > 0; us_netbuf_num--) {
115 netbuf_temp = oal_netbuf_next(netbuf);
116
117 /* 减少netbuf对应的user引用计数 */
118 oal_netbuf_free(netbuf);
119
120 netbuf = netbuf_temp;
121 if (netbuf == HI_NULL) {
122 if (oal_unlikely(us_netbuf_num != 1)) {
123 oam_error_log2(0, OAM_SF_RX,
124 "{hmac_rx_free_netbuf::pst_netbuf list broken, us_netbuf_num[%d]us_nums[%d].}", us_netbuf_num,
125 us_nums);
126 return;
127 }
128
129 break;
130 }
131 }
132 }
133
134 /* ****************************************************************************
135 功能描述 : free netbuff list
136 修改历史 :
137 1.日 期 : 2015年1月3日
138 作 者 : HiSilicon
139 修改内容 : 新生成函数
140 **************************************************************************** */
hmac_rx_free_netbuf_list(oal_netbuf_head_stru * netbuf_hdr,hi_u16 num_buf)141 hi_void hmac_rx_free_netbuf_list(oal_netbuf_head_stru *netbuf_hdr, hi_u16 num_buf)
142 {
143 oal_netbuf_stru *netbuf = HI_NULL;
144 hi_u16 us_idx;
145
146 if (oal_unlikely(netbuf_hdr == HI_NULL)) {
147 oam_info_log0(0, OAM_SF_RX, "{hmac_rx_free_netbuf_list::pst_netbuf null.}");
148 return;
149 }
150
151 for (us_idx = num_buf; us_idx > 0; us_idx--) {
152 netbuf = oal_netbuf_delist(netbuf_hdr);
153 if (netbuf != HI_NULL) {
154 oal_netbuf_free(netbuf);
155 }
156 }
157 }
158
159 /* ****************************************************************************
160 功能描述 : 将数据帧发送到WLAN侧的接口函数,将一个netbuf链抛给发送流程,每个
161 netbuf的内容都是一个以太网格式的MSDU
162 输入参数 : (1)指向事件头的指针
163 (2)指向需要发送的netbuf的第一个元素的指针
164 返 回 值 : 成功或者失败原因
165 修改历史 :
166 1.日 期 : 2012年11月19日
167 作 者 : HiSilicon
168 修改内容 : 新生成函数
169 2.日 期 : 2016年06月20日
170 作 者 : HiSilicon
171 **************************************************************************** */
hmac_rx_transmit_to_wlan(frw_event_hdr_stru * event_hdr,oal_netbuf_head_stru * netbuf_head)172 static hi_u32 hmac_rx_transmit_to_wlan(frw_event_hdr_stru *event_hdr, oal_netbuf_head_stru *netbuf_head)
173 {
174 oal_netbuf_stru *netbuf = HI_NULL; /* 从netbuf链上取下来的指向netbuf的指针 */
175 hi_u32 netbuf_num;
176 hi_u32 ret;
177 oal_netbuf_stru *buf_tmp = HI_NULL; /* 暂存netbuf指针,用于while循环 */
178 hmac_tx_ctl_stru *tx_ctl = HI_NULL;
179 mac_vap_stru *mac_vap = HI_NULL;
180
181 if (oal_unlikely((event_hdr == HI_NULL) || (netbuf_head == HI_NULL))) {
182 oam_error_log2(0, OAM_SF_RX, "{hmac_rx_transmit_to_wlan::param null, %p %p.}", (uintptr_t)event_hdr,
183 (uintptr_t)netbuf_head);
184 return HI_ERR_CODE_PTR_NULL;
185 }
186
187 /* 获取链头的net buffer */
188 netbuf = oal_netbuf_peek(netbuf_head);
189
190 /* 获取mac vap 结构 */
191 ret = hmac_tx_get_mac_vap(event_hdr->vap_id, &mac_vap);
192 if (oal_unlikely(ret != HI_SUCCESS)) {
193 netbuf_num = oal_netbuf_list_num(netbuf_head);
194 hmac_rx_free_netbuf(netbuf, (hi_u16)netbuf_num);
195 oam_warning_log3(event_hdr->vap_id, OAM_SF_RX,
196 "{hmac_rx_transmit_to_wlan::find vap [%d] failed[%d], free [%d] netbuffer.}", event_hdr->vap_id, ret,
197 netbuf_num);
198 return ret;
199 }
200
201 /* 循环处理每一个netbuf,按照以太网帧的方式处理 */
202 while (netbuf != HI_NULL) {
203 buf_tmp = oal_netbuf_next(netbuf);
204 set_oal_netbuf_next(netbuf, HI_NULL);
205 set_oal_netbuf_prev(netbuf, HI_NULL);
206
207 /* 转WLAN的报文长度必须大于ETHER_HDR_LEN,否则异常丢弃 */
208 if (oal_netbuf_len(netbuf) < ETHER_HDR_LEN) {
209 hmac_free_netbuf_list(netbuf);
210 netbuf = buf_tmp;
211 continue;
212 }
213
214 tx_ctl = (hmac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
215 if (memset_s(tx_ctl, sizeof(hmac_tx_ctl_stru), 0, sizeof(hmac_tx_ctl_stru)) != EOK) {
216 hmac_free_netbuf_list(netbuf);
217 netbuf = buf_tmp;
218 continue;
219 }
220
221 tx_ctl->event_type = FRW_EVENT_TYPE_WLAN_DTX;
222 tx_ctl->event_sub_type = DMAC_TX_WLAN_DTX;
223
224 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
225 /* set the queue map id when wlan to wlan */
226 oal_skb_set_queue_mapping(netbuf, WLAN_NORMAL_QUEUE);
227 #endif
228
229 ret = hmac_tx_lan_to_wlan(mac_vap, netbuf);
230 if (oal_unlikely(ret != HI_SUCCESS)) {
231 hmac_free_netbuf_list(netbuf);
232 }
233 netbuf = buf_tmp;
234 }
235
236 return HI_SUCCESS;
237 }
238
hmac_rx_set_msdu_state(oal_netbuf_stru * netbuf,hmac_msdu_proc_state_stru * msdu_state)239 hi_void hmac_rx_set_msdu_state(oal_netbuf_stru *netbuf, hmac_msdu_proc_state_stru *msdu_state)
240 {
241 if (msdu_state->procd_msdu_in_netbuf == 0) {
242 msdu_state->curr_netbuf = netbuf;
243
244 /* AMSDU时,首个netbuf的中包含802.11头,对应的payload需要偏移 */
245 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(msdu_state->curr_netbuf);
246
247 msdu_state->puc_curr_netbuf_data = (hi_u8 *)(rx_ctrl->pul_mac_hdr_start_addr) + rx_ctrl->mac_header_len;
248 msdu_state->msdu_nums_in_netbuf = rx_ctrl->msdu_in_buffer;
249 msdu_state->us_submsdu_offset = 0;
250 }
251 }
252
hmac_rx_msdu_proc(const hmac_vap_stru * hmac_vap,oal_netbuf_head_stru * netbuf_header,oal_netbuf_stru * netbuf,mac_ieee80211_frame_stru * frame_hdr,const hmac_rx_ctl_stru * rx_ctrl)253 hi_u32 hmac_rx_msdu_proc(const hmac_vap_stru *hmac_vap, oal_netbuf_head_stru *netbuf_header, oal_netbuf_stru *netbuf,
254 mac_ieee80211_frame_stru *frame_hdr, const hmac_rx_ctl_stru *rx_ctrl)
255 {
256 hi_u8 sa_mac_addr[WLAN_MAC_ADDR_LEN];
257 hi_u8 da_mac_addr[WLAN_MAC_ADDR_LEN];
258 hi_u8 *source_mac_addr = HI_NULL;
259 hi_u8 *dest_mac_addr = HI_NULL;
260
261 hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(rx_ctrl->us_ta_user_idx);
262 if (oal_unlikely(hmac_user == HI_NULL)) {
263 return HI_ERR_CODE_PTR_NULL;
264 }
265
266 netbuf = hmac_defrag_process(hmac_user, netbuf, rx_ctrl->mac_header_len);
267 if (netbuf == HI_NULL) {
268 return HI_SUCCESS;
269 }
270
271 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
272 frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
273
274 /* 从MAC头中获取源地址和目的地址 */
275 mac_rx_get_sa(frame_hdr, &source_mac_addr);
276 mac_rx_get_da(frame_hdr, &dest_mac_addr);
277 if ((memcpy_s(sa_mac_addr, WLAN_MAC_ADDR_LEN, source_mac_addr, WLAN_MAC_ADDR_LEN) != EOK) ||
278 (memcpy_s(da_mac_addr, WLAN_MAC_ADDR_LEN, dest_mac_addr, WLAN_MAC_ADDR_LEN) != EOK)) {
279 return HI_FAIL;
280 }
281
282 /* 将netbuf的data指针指向mac frame的payload处,也就是指向了8字节的snap头 */
283 oal_netbuf_pull(netbuf, rx_ctrl->mac_header_len);
284
285 /* 将MSDU转化为以太网格式的帧 */
286 hmac_rx_frame_80211_to_eth(netbuf, da_mac_addr, WLAN_MAC_ADDR_LEN, sa_mac_addr, WLAN_MAC_ADDR_LEN);
287
288 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化 */
289 memset_s(oal_netbuf_cb(netbuf), oal_netbuf_cb_size(), 0, oal_netbuf_cb_size());
290
291 #if defined(_PRE_WLAN_FEATURE_WPA) || defined(_PRE_WLAN_FEATURE_WPA2)
292 mac_ether_header_stru *ether = (mac_ether_header_stru *)oal_netbuf_data(netbuf);
293 if (ether == HI_NULL) {
294 return HI_FAIL;
295 }
296 if (hmac_11i_ether_type_filter(hmac_vap, ether->auc_ether_shost, ether->us_ether_type) != HI_SUCCESS) {
297 return HI_FAIL;
298 } else {
299 /* 将MSDU加入到netbuf链的最后 */
300 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
301 }
302 #else
303 /* 将MSDU加入到netbuf链的最后 */
304 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
305 #endif
306
307 return HI_SUCCESS;
308 }
309
310 /* ****************************************************************************
311 功能描述 : 解析MPDU,如果是非AMSDU,则将MSDU还原为以太网格式的帧,并加入到
312 netbuf链的最后,如果该MPDU是AMSDU,则解析出每一个MSDU,并且每一
313 个MSDU占用一个netbuf
314 输入参数 : pst_netbuf_header: 要交给发送流程的netbuf链表头
315 pst_netbuf : 当前要处理的MPDU的第一个netbuf
316 pst_frame_hdr : 当前要处理的MPDU的MAC头
317 返 回 值 : 成功或者错误码
318 修改历史 :
319 1.日 期 : 2013年12月17日
320 作 者 : HiSilicon
321 修改内容 : 新生成函数
322 **************************************************************************** */
hmac_rx_prepare_msdu_list_to_wlan(const hmac_vap_stru * hmac_vap,oal_netbuf_head_stru * netbuf_header,oal_netbuf_stru * netbuf,mac_ieee80211_frame_stru * frame_hdr)323 static hi_u32 hmac_rx_prepare_msdu_list_to_wlan(const hmac_vap_stru *hmac_vap, oal_netbuf_head_stru *netbuf_header,
324 oal_netbuf_stru *netbuf, mac_ieee80211_frame_stru *frame_hdr)
325 {
326 hi_u32 ret;
327 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf); /* 获取该MPDU的控制信息 */
328
329 /* 情况一:不是AMSDU聚合,则该MPDU对应一个MSDU,同时对应一个NETBUF,将MSDU还原
330 成以太网格式帧以后直接加入到netbuf链表最后
331 */
332 if (rx_ctrl->amsdu_enable == HI_FALSE) {
333 ret = hmac_rx_msdu_proc(hmac_vap, netbuf_header, netbuf, frame_hdr, rx_ctrl);
334 return ret;
335 } else { /* 情况二:AMSDU聚合 */
336 return HI_FAIL;
337 }
338 }
339
340 #ifdef _PRE_WLAN_FEATURE_PKT_MEM_OPT
hmac_pkt_mem_opt_stat_reset(hmac_device_stru * hmac_dev,hi_u8 dscr_opt_state)341 static hi_void hmac_pkt_mem_opt_stat_reset(hmac_device_stru *hmac_dev, hi_u8 dscr_opt_state)
342 {
343 frw_event_mem_stru *event_mem = HI_NULL;
344 frw_event_stru *event = HI_NULL;
345 hmac_rx_dscr_opt_stru *dscr_opt = &hmac_dev->rx_dscr_opt;
346
347 dscr_opt->dscr_opt_state = dscr_opt_state;
348 dscr_opt->rx_pkt_num = 0;
349 /* **************************************************************************
350 抛事件到dmac模块,将统计信息报给dmac
351 ************************************************************************** */
352 event_mem = frw_event_alloc(0);
353 if (oal_unlikely(event_mem == HI_NULL)) {
354 oam_error_log0(0, OAM_SF_ANY, "{hmac_rx_dscr_opt_timeout_fn::event_mem null.}");
355 return;
356 }
357
358 event = (frw_event_stru *)event_mem->puc_data;
359
360 /* 填写事件头 */
361 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_WLAN_CTX, DMAC_WLAN_CTX_EVENT_SUB_TYPE_DSCR_OPT, 0,
362 FRW_EVENT_PIPELINE_STAGE_1, 0);
363
364 /* 拷贝参数 */
365 event->auc_event_data[0] = dscr_opt->dscr_opt_state;
366
367 /* 分发事件 */
368 hcc_hmac_tx_control_event(event_mem, 0);
369 frw_event_free(event_mem);
370 }
371
372 /* ****************************************************************************
373 功能描述 : 配置hmac_pkt_mem_opt_cfg参数
374 输入参数 : ul_cfg_type:0 enable使能开关
375 1 opt_limit
376 2 reset_limit
377 修改历史 :
378 1.日 期 : 2015年10月14日
379 作 者 : HiSilicon
380 修改内容 : 新生成函数
381 **************************************************************************** */
hmac_pkt_mem_opt_cfg(hi_u32 cfg_tpye,hi_u32 cfg_value)382 hi_void hmac_pkt_mem_opt_cfg(hi_u32 cfg_tpye, hi_u32 cfg_value)
383 {
384 hmac_device_stru *hmac_dev = hmac_get_device_stru();
385 hmac_rx_dscr_opt_stru *dscr_opt = HI_NULL;
386
387 if (cfg_tpye > 2) { /* 大于2 无效类型 */
388 oam_warning_log0(0, OAM_SF_ANY, "{hmac_rx_dscr_opt_cfg::invalid cfg tpye.}");
389 return;
390 }
391
392 oam_warning_log2(0, OAM_SF_ANY, "{hmac_rx_dscr_opt_cfg::cfg type[%d], cfg value[%d].}", cfg_tpye, cfg_value);
393 dscr_opt = &hmac_dev->rx_dscr_opt;
394 if (cfg_tpye == 0) {
395 dscr_opt->dscr_opt_enable = (hi_u8)cfg_value;
396 if (dscr_opt->dscr_opt_enable == HI_FALSE && dscr_opt->dscr_opt_state == HI_TRUE) {
397 hmac_pkt_mem_opt_stat_reset(hmac_dev, HI_FALSE);
398 }
399 } else if (cfg_tpye == 1) {
400 dscr_opt->rx_pkt_opt_limit = cfg_value;
401 } else if (cfg_tpye == 2) { /* 等于2 reset */
402 dscr_opt->rx_pkt_reset_limit = cfg_value;
403 }
404 }
405
hmac_pkt_mem_opt_timeout_fn(hi_void * arg)406 hi_u32 hmac_pkt_mem_opt_timeout_fn(hi_void *arg)
407 {
408 hmac_device_stru *hmac_dev = HI_NULL;
409 hmac_rx_dscr_opt_stru *dscr_opt = HI_NULL;
410
411 if (oal_unlikely(arg == HI_NULL)) {
412 oam_warning_log0(0, OAM_SF_ANY, "{hmac_rx_dscr_opt_timeout_fn::p_arg is null.}");
413 return HI_ERR_CODE_PTR_NULL;
414 }
415
416 hmac_dev = (hmac_device_stru *)arg;
417 dscr_opt = &hmac_dev->rx_dscr_opt;
418
419 if (dscr_opt->dscr_opt_enable != HI_TRUE) {
420 return HI_SUCCESS;
421 }
422
423 oam_info_log2(0, OAM_SF_ANY, "{hmac_rx_dscr_opt_timeout_fn::state[%d], pkt_num[%d]}", dscr_opt->dscr_opt_state,
424 dscr_opt->rx_pkt_num);
425
426 /* rx_dscr未调整状态时, 检测到RX业务,调整描述符 */
427 if (dscr_opt->dscr_opt_state == HI_FALSE && dscr_opt->rx_pkt_num > dscr_opt->rx_pkt_opt_limit) {
428 hmac_pkt_mem_opt_stat_reset(hmac_dev, HI_TRUE);
429 } else if (dscr_opt->dscr_opt_state == HI_TRUE && dscr_opt->rx_pkt_num < dscr_opt->rx_pkt_reset_limit) {
430 /* rx_dscr已调整状态时, 未检测到RX业务, 调整回描述符,保证TX性能 */
431 hmac_pkt_mem_opt_stat_reset(hmac_dev, HI_FALSE);
432 } else {
433 dscr_opt->rx_pkt_num = 0;
434 }
435
436 return HI_SUCCESS;
437 }
438
hmac_pkt_mem_opt_init(hmac_device_stru * hmac_dev)439 hi_void hmac_pkt_mem_opt_init(hmac_device_stru *hmac_dev)
440 {
441 hmac_dev->rx_dscr_opt.dscr_opt_state = HI_FALSE;
442 hmac_dev->rx_dscr_opt.rx_pkt_num = 0;
443 hmac_dev->rx_dscr_opt.rx_pkt_opt_limit = WLAN_PKT_MEM_PKT_OPT_LIMIT;
444 hmac_dev->rx_dscr_opt.rx_pkt_reset_limit = WLAN_PKT_MEM_PKT_RESET_LIMIT;
445 /* 功能无效,暂时关闭 */
446 hmac_dev->rx_dscr_opt.dscr_opt_enable = HI_FALSE;
447
448 frw_timer_create_timer(&(hmac_dev->rx_dscr_opt.rx_dscr_opt_timer), hmac_pkt_mem_opt_timeout_fn,
449 WLAN_PKT_MEM_OPT_TIME_MS, hmac_dev, HI_TRUE);
450 }
451
hmac_pkt_mem_opt_exit(hmac_device_stru * hmac_dev)452 hi_void hmac_pkt_mem_opt_exit(hmac_device_stru *hmac_dev)
453 {
454 if (hmac_dev->rx_dscr_opt.rx_dscr_opt_timer.is_registerd == HI_TRUE) {
455 frw_timer_immediate_destroy_timer(&(hmac_dev->rx_dscr_opt.rx_dscr_opt_timer));
456 }
457 }
458
hmac_pkt_mem_opt_rx_pkts_stat(const oal_ip_header_stru * ip)459 static hi_void hmac_pkt_mem_opt_rx_pkts_stat(const oal_ip_header_stru *ip)
460 {
461 hmac_device_stru *hmac_dev = hmac_get_device_stru();
462 /* 过滤IP_LEN 小于 WLAN_SHORT_NETBUF_SIZE的报文 */
463 if (oal_net2host_short(ip->us_tot_len) < WLAN_SHORT_NETBUF_SIZE) {
464 return;
465 }
466
467 if ((ip->protocol == MAC_UDP_PROTOCAL) || (ip->protocol == MAC_TCP_PROTOCAL)) {
468 hmac_dev->rx_dscr_opt.rx_pkt_num++;
469 }
470 }
471 #endif
472
473 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
hmac_rx_transmit_edca_opt_ap(const hmac_vap_stru * hmac_vap,mac_ether_header_stru * ether_hdr)474 static hi_u32 hmac_rx_transmit_edca_opt_ap(const hmac_vap_stru *hmac_vap, mac_ether_header_stru *ether_hdr)
475 {
476 mac_vap_stru *mac_vap = hmac_vap->base_vap;
477 hmac_user_stru *hmac_user = HI_NULL;
478 mac_ip_header_stru *ip = HI_NULL;
479 hi_u8 assoc_id = 0xff;
480
481 if (((mac_vap->vap_mode == WLAN_VAP_MODE_BSS_AP)
482 #ifdef _PRE_WLAN_FEATURE_MESH
483 || (mac_vap->vap_mode == WLAN_VAP_MODE_MESH)
484 #endif
485 ) && (hmac_vap->edca_opt_flag_ap == HI_TRUE)) {
486 /* Mesh IPv6可能进行报头压缩,暂不纳入此处处理 */
487 if (oal_host2net_short(ETHER_TYPE_IP) == ether_hdr->us_ether_type) {
488 if (mac_vap_find_user_by_macaddr(mac_vap, ether_hdr->auc_ether_shost, ETHER_ADDR_LEN, &assoc_id) !=
489 HI_SUCCESS) {
490 oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_M2U,
491 "{hmac_rx_transmit_edca_opt_ap::find_user_by_macaddr[XX:XX:XX:%02x:%02x:%02x]failed}",
492 (hi_u32)(ether_hdr->auc_ether_shost[3]), /* 3 元素索引 */
493 (hi_u32)(ether_hdr->auc_ether_shost[4]), /* 4 元素索引 */
494 (hi_u32)(ether_hdr->auc_ether_shost[5])); /* 5 元素索引 */
495 return HI_FAIL;
496 }
497 hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(assoc_id);
498 if (hmac_user == HI_NULL) {
499 oam_error_log1(hmac_vap->base_vap->vap_id, OAM_SF_RX,
500 "{hmac_rx_transmit_edca_opt_ap::hmac_user_get_user_stru fail. assoc_id: %u}", assoc_id);
501 return HI_FAIL;
502 }
503
504 ip = (mac_ip_header_stru *)(ether_hdr + 1);
505
506 /* mips优化:解决开启业务统计性能差10M问题 */
507 if (((ip->protocol == MAC_UDP_PROTOCAL) && (hmac_user->txrx_data_stat[WLAN_WME_AC_BE][WLAN_RX_UDP_DATA] <
508 (HMAC_EDCA_OPT_PKT_NUM + 10))) || /* 10 用于计算 */
509 ((ip->protocol == MAC_TCP_PROTOCAL) && (hmac_user->txrx_data_stat[WLAN_WME_AC_BE][WLAN_RX_TCP_DATA] <
510 (HMAC_EDCA_OPT_PKT_NUM + 10)))) { /* 10 用于计算 */
511 hmac_edca_opt_rx_pkts_stat(hmac_user, WLAN_TIDNO_BEST_EFFORT, ip);
512 }
513 }
514 }
515
516 return HI_SUCCESS;
517 }
518 #endif
519
520 /* ****************************************************************************
521 功能描述 : 将MSDU转发到LAN的接口,包括地址转换等信息的设置
522 说明:本函数接收到的netbuf数据域是从snap头开始
523 输入参数 : (1)指向vap的指针
524 (2)指向需要发送的msdu的指针
525 返 回 值 : 成功或者失败原因
526 修改历史 :
527 1.日 期 : 2012年11月14日
528 作 者 : HiSilicon
529 修改内容 : 新生成函数
530 **************************************************************************** */
hmac_rx_transmit_msdu_to_lan(const hmac_vap_stru * hmac_vap,hmac_msdu_stru * msdu)531 static hi_void hmac_rx_transmit_msdu_to_lan(const hmac_vap_stru *hmac_vap, hmac_msdu_stru *msdu)
532 {
533 /* 获取netbuf,该netbuf的data指针已经指向payload处 */
534 oal_netbuf_stru *netbuf = msdu->netbuf;
535
536 set_oal_netbuf_prev(netbuf, HI_NULL);
537 set_oal_netbuf_next(netbuf, HI_NULL);
538
539 hmac_rx_frame_80211_to_eth(netbuf, msdu->auc_da, WLAN_MAC_ADDR_LEN, msdu->auc_sa, WLAN_MAC_ADDR_LEN);
540
541 mac_ether_header_stru *ether_hdr = (mac_ether_header_stru *)oal_netbuf_data(netbuf);
542 if (oal_unlikely(ether_hdr == HI_NULL)) {
543 oal_netbuf_free(netbuf);
544 oam_error_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_transmit_msdu_to_lan::pst_ether_hdr null.}");
545 return;
546 }
547 #if defined(_PRE_WLAN_FEATURE_WPA) || defined(_PRE_WLAN_FEATURE_WPA2)
548 hi_u8 *mac_addr = msdu->auc_ta;
549
550 if (HI_SUCCESS != hmac_11i_ether_type_filter(hmac_vap, mac_addr, ether_hdr->us_ether_type)) {
551 /* 接收安全数据过滤 */
552 oal_netbuf_free(netbuf);
553 return;
554 }
555 #endif
556 /* 获取net device hmac创建的时候,需要记录netdevice指针 */
557 oal_net_device_stru *netdev = hmac_vap->net_device;
558
559 /* 对protocol模式赋值 */
560 oal_eth_type_trans(netbuf, netdev);
561
562 #ifdef _PRE_WLAN_FEATURE_EDCA_OPT_AP
563 if (hmac_rx_transmit_edca_opt_ap(hmac_vap, ether_hdr) != HI_SUCCESS) {
564 oal_netbuf_free(netbuf);
565 return;
566 }
567 #endif
568
569 #ifdef _PRE_WLAN_FEATURE_PKT_MEM_OPT
570 hmac_pkt_mem_opt_rx_pkts_stat((oal_ip_header_stru *)(ether_hdr + 1));
571 #endif
572
573 /* 将skb转发给桥 */
574 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
575 netbuf->dev = netdev;
576
577 /* 将skb的data指针指向以太网的帧头 */
578 /* 由于前面pull了14字节,这个地方要push回去 */
579 oal_netbuf_push(netbuf, ETHER_HDR_LEN);
580 #endif
581
582 #ifdef _PRE_HDF_LINUX
583 netbuf->dev = (struct net_device *)netdev;
584 #endif
585
586 if (HI_TRUE == hmac_get_rxthread_enable()) {
587 hmac_rxdata_netbuf_enqueue(netbuf);
588
589 hmac_rxdata_sched();
590 } else {
591 oal_netif_rx_ni(netbuf);
592 }
593
594 /* 置位net_dev->jiffies变量 */
595 oal_netdevice_last_rx(netdev) = OAL_TIME_JIFFY;
596 }
597
hmac_rx_msdu_frame_classify(const hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,mac_ieee80211_frame_stru * frame_hdr,hmac_msdu_stru * msdu,hmac_user_stru * hmac_user)598 hi_void hmac_rx_msdu_frame_classify(const hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf,
599 mac_ieee80211_frame_stru *frame_hdr, hmac_msdu_stru *msdu, hmac_user_stru *hmac_user)
600 {
601 hi_u8 *mac_addr = HI_NULL;
602 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
603
604 #ifdef _PRE_WLAN_FEATURE_WAPI
605 hi_bool pairwise = !ether_is_multicast(frame_hdr->auc_address1);
606 hmac_wapi_stru *wapi = hmac_user_get_wapi_ptr(hmac_vap->base_vap, pairwise, hmac_user->base_user->us_assoc_id);
607
608 if (wapi == HI_NULL) {
609 oam_warning_log0(0, OAM_SF_WPA, "{hmac_rx_lan_frame_classify:: get pst_wapi Err!.}");
610 return;
611 }
612
613 if ((wapi_is_port_valid(wapi) == HI_TRUE) && (wapi->wapi_netbuff_rxhandle != HI_NULL)) {
614 netbuf = wapi->wapi_netbuff_rxhandle(wapi, netbuf);
615 if (netbuf == HI_NULL) {
616 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_lan_frame_classify:WapiDecrypt Err}");
617 return;
618 }
619
620 /* 重新获取该MPDU的控制信息 */
621 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
622 }
623 #endif
624
625 netbuf = hmac_defrag_process(hmac_user, netbuf, rx_ctrl->mac_header_len);
626 if (netbuf == HI_NULL) {
627 return;
628 }
629
630 /* 打印出关键帧(dhcp)信息 */
631 hi_u8 datatype = mac_get_data_type_from_80211(netbuf, rx_ctrl->mac_header_len);
632 if (datatype <= MAC_DATA_VIP) {
633 oam_warning_log3(hmac_vap->base_vap->vap_id, OAM_SF_RX,
634 "{hmac_rx_lan_frame_classify:user=%d,type=%u,len=%u}[0~3dhcp 4arp_req 5arp_rsp 6eapol]",
635 rx_ctrl->us_ta_user_idx, datatype, rx_ctrl->us_frame_len);
636 }
637
638 /* 对当前的msdu进行赋值 */
639 msdu->netbuf = netbuf;
640
641 /* 将netbuf的data指针指向mac frame的payload处 */
642 oal_netbuf_pull(netbuf, rx_ctrl->mac_header_len);
643
644 /* 获取源地址和目的地址 */
645 mac_rx_get_sa(frame_hdr, &mac_addr);
646 if (memcpy_s(msdu->auc_sa, WLAN_MAC_ADDR_LEN, mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
647 return;
648 }
649
650 mac_rx_get_da(frame_hdr, &mac_addr);
651 if (memcpy_s(msdu->auc_da, WLAN_MAC_ADDR_LEN, mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
652 return;
653 }
654
655 /* 将MSDU转发到LAN */
656 hmac_rx_transmit_msdu_to_lan(hmac_vap, msdu);
657 }
658
659 /* ****************************************************************************
660 功能描述 : HMAC接收模块,WLAN到LAN的转发接口
661 输入参数 : (1)对应MPDU的第一个netbuf的指针
662 (2)对应的MPDU占用的netbuf的数目
663 返 回 值 : 成功或者失败原因
664 修改历史 :
665 1.日 期 : 2012年12月6日
666 作 者 : HiSilicon
667 修改内容 : 新生成函数
668 **************************************************************************** */
hmac_rx_lan_frame_classify(const hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,mac_ieee80211_frame_stru * frame_hdr)669 hi_u32 hmac_rx_lan_frame_classify(const hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf,
670 mac_ieee80211_frame_stru *frame_hdr)
671 {
672 hmac_msdu_stru msdu = { 0 }; /* 保存解析出来的每一个MSDU */
673 hi_u8 *mac_addr = HI_NULL;
674
675 if (oal_unlikely(frame_hdr == HI_NULL)) {
676 oam_error_log0(0, OAM_SF_RX, "{hmac_rx_lan_frame_classify::params null.}");
677 return HI_FAIL;
678 }
679
680 /* 获取该MPDU的控制信息 */
681 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
682
683 mac_get_transmit_addr(frame_hdr, &mac_addr);
684 if (memcpy_s(msdu.auc_ta, WLAN_MAC_ADDR_LEN, mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
685 return HI_FAIL;
686 }
687
688 hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(rx_ctrl->us_ta_user_idx);
689 if (oal_unlikely((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL))) {
690 oam_error_log3(hmac_vap->base_vap->vap_id, OAM_SF_RX,
691 "{hmac_rx_lan_frame_classify::hmac_user null,user_idx=%d,net_buf ptr addr=%p,cb ptr addr=%p}",
692 rx_ctrl->us_ta_user_idx, (uintptr_t)netbuf, (uintptr_t)rx_ctrl);
693
694 /* 打印此net buf相关信息 */
695 oam_error_log4(hmac_vap->base_vap->vap_id, OAM_SF_RX,
696 "{hmac_rx_lan_frame_classify:vap id=%d,mac_hdr_len=%d,frame_len=%d,mac_hdr_start_addr=%p}", rx_ctrl->vap_id,
697 rx_ctrl->mac_header_len, rx_ctrl->us_frame_len, (uintptr_t)rx_ctrl->pul_mac_hdr_start_addr);
698
699 return HI_FAIL;
700 }
701
702 hmac_ba_update_rx_bitmap(hmac_user, frame_hdr);
703
704 /* 情况一:不是AMSDU聚合,则该MPDU对应一个MSDU,同时对应一个NETBUF */
705 if (rx_ctrl->amsdu_enable == HI_FALSE) {
706 hmac_rx_msdu_frame_classify(hmac_vap, netbuf, frame_hdr, &msdu, hmac_user);
707 } else { /* 情况二:AMSDU聚合 */
708 return HI_FAIL;
709 }
710 return HI_SUCCESS;
711 }
712
713 /* ****************************************************************************
714 功能描述 : copy netbuff
715 修改历史 :
716 1.日 期 : 2015年1月3日
717 作 者 : HiSilicon
718 修改内容 : 新生成函数
719 **************************************************************************** */
hmac_rx_copy_netbuff(oal_netbuf_stru ** dest_netbuf,const oal_netbuf_stru * src_netbuf,hi_u8 vap_id,mac_ieee80211_frame_stru ** ppul_mac_hdr_start_addr)720 hi_u32 hmac_rx_copy_netbuff(oal_netbuf_stru **dest_netbuf, const oal_netbuf_stru *src_netbuf, hi_u8 vap_id,
721 mac_ieee80211_frame_stru **ppul_mac_hdr_start_addr)
722 {
723 hmac_rx_ctl_stru *rx_ctrl = HI_NULL;
724
725 hi_unref_param(vap_id);
726 *dest_netbuf = oal_netbuf_alloc(WLAN_LARGE_NETBUF_SIZE, 0, 4); /* align 4 */
727 if (oal_unlikely(*dest_netbuf == HI_NULL)) {
728 oam_warning_log0(vap_id, OAM_SF_RX, "{hmac_rx_copy_netbuff::pst_netbuf_copy null.}");
729 return HI_ERR_CODE_ALLOC_MEM_FAIL;
730 }
731
732 /* 信息复制 */
733 if (memcpy_s(oal_netbuf_cb(*dest_netbuf), oal_netbuf_cb_size(), oal_netbuf_cb(src_netbuf),
734 sizeof(hmac_rx_ctl_stru)) != EOK) {
735 oal_netbuf_free(*dest_netbuf);
736 oam_error_log0(0, OAM_SF_CFG, "hmac_rx_copy_netbuff:: pst_src_netbuf memcpy_s fail.");
737 return HI_FAIL;
738 }
739 if (memcpy_s(oal_netbuf_data(*dest_netbuf), oal_netbuf_tailroom(*dest_netbuf), oal_netbuf_data(src_netbuf),
740 oal_netbuf_len(src_netbuf)) != EOK) {
741 oal_netbuf_free(*dest_netbuf);
742 oam_error_log0(0, OAM_SF_CFG, "hmac_rx_copy_netbuff:: pst_src_netbuf memcpy_s fail.");
743 return HI_FAIL;
744 }
745 /* 设置netbuf长度、TAIL指针 */
746 oal_netbuf_put(*dest_netbuf, oal_netbuf_len(src_netbuf));
747 /* 调整MAC帧头的指针copy后,对应的mac header的头已经发生变化) */
748 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(*dest_netbuf);
749 rx_ctrl->pul_mac_hdr_start_addr = (hi_u32 *)oal_netbuf_data(*dest_netbuf);
750 *ppul_mac_hdr_start_addr = (mac_ieee80211_frame_stru *)oal_netbuf_data(*dest_netbuf);
751
752 return HI_SUCCESS;
753 }
754
hmac_rx_netbuf_add_to_list_tail(oal_netbuf_head_stru * netbuf_header,hmac_rx_ctl_stru * rx_ctrl,hi_u32 ret,hi_u8 buf_nums,hi_u8 is_ba_buf)755 hi_void hmac_rx_netbuf_add_to_list_tail(oal_netbuf_head_stru *netbuf_header, hmac_rx_ctl_stru *rx_ctrl, hi_u32 ret,
756 hi_u8 buf_nums, hi_u8 is_ba_buf)
757 {
758 oal_netbuf_stru *netbuf = HI_NULL;
759 hi_u8 netbuf_num;
760
761 hi_unref_param(rx_ctrl);
762
763 if (ret != HI_SUCCESS) {
764 hmac_rx_free_netbuf_list(netbuf_header, buf_nums);
765 return;
766 }
767
768 if (is_ba_buf == HI_TRUE) {
769 return;
770 }
771
772 /* 如果不buff进reorder队列,则重新挂到链表尾,保序 */
773 for (netbuf_num = 0; netbuf_num < buf_nums; netbuf_num++) {
774 netbuf = oal_netbuf_delist(netbuf_header);
775 if (oal_likely(netbuf != HI_NULL)) {
776 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
777 } else {
778 oam_warning_log0(rx_ctrl->vap_id, OAM_SF_RX, "{hmac_rx_netbuf_add_to_list_tail::no buff error.}");
779 }
780 }
781 }
782
783 /* ****************************************************************************
784 功能描述 :
785 修改历史 :
786 1.日 期 : 2015年1月3日
787 作 者 : HiSilicon
788 修改内容 : 新生成函数
789 **************************************************************************** */
hmac_rx_process_data_filter(oal_netbuf_head_stru * netbuf_header,oal_netbuf_stru * temp_netbuf,hi_u16 us_netbuf_num)790 hi_void hmac_rx_process_data_filter(oal_netbuf_head_stru *netbuf_header, oal_netbuf_stru *temp_netbuf,
791 hi_u16 us_netbuf_num)
792 {
793 hi_u8 buf_nums;
794 hi_u32 ret = HI_SUCCESS;
795
796 while (us_netbuf_num != 0) {
797 hi_u8 is_ba_buf = HI_FALSE;
798 oal_netbuf_stru *netbuf = temp_netbuf;
799 if (netbuf == HI_NULL) {
800 oam_warning_log1(0, OAM_SF_RX, "{hmac_rx_process_data_filter::us_netbuf_num = %d}", us_netbuf_num);
801 break;
802 }
803
804 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
805 buf_nums = rx_ctrl->buff_nums;
806
807 /* 获取下一个要处理的MPDU */
808 oal_netbuf_get_appointed_netbuf(netbuf, buf_nums, &temp_netbuf);
809 us_netbuf_num = hi_sub(us_netbuf_num, buf_nums);
810 #ifdef _PRE_WLAN_FEATURE_AMPDU
811 hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(rx_ctrl->us_ta_user_idx);
812 if (oal_unlikely((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL) ||
813 (hmac_user->base_user->is_user_alloced != MAC_USER_ALLOCED))) {
814 hmac_rx_free_netbuf_list(netbuf_header, buf_nums);
815 oam_info_log0(rx_ctrl->vap_id, OAM_SF_RX, "{hmac_rx_process_data_filter::user null.}");
816 continue;
817 }
818 mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
819 #endif
820
821 mac_vap_stru *mac_vap = mac_vap_get_vap_stru(rx_ctrl->mac_vap_id);
822 if (oal_unlikely(mac_vap == HI_NULL)) {
823 hmac_rx_free_netbuf_list(netbuf_header, buf_nums);
824 oam_warning_log0(rx_ctrl->vap_id, OAM_SF_RX, "{hmac_rx_process_data_filter::pst_vap null.}");
825 continue;
826 }
827
828 if (mac_vap->vap_id == 0 || mac_vap->vap_id > WLAN_VAP_NUM_PER_DEVICE) {
829 oam_error_log1(0, OAM_SF_RX, "{hmac_rx_process_data_filter::Invalid vap_id.vap_id[%u]}", mac_vap->vap_id);
830 hmac_rx_free_netbuf_list(netbuf_header, buf_nums);
831 continue;
832 }
833
834 #ifdef _PRE_WLAN_FEATURE_AMPDU
835 hmac_filter_serv_info_stru filter_serv_info;
836 filter_serv_info.netbuf_header = netbuf_header;
837 filter_serv_info.pen_is_ba_buf = &is_ba_buf;
838 ret = HI_SUCCESS;
839 if (rx_ctrl->amsdu_enable == HI_FALSE) {
840 ret = hmac_ba_filter_serv(mac_vap, hmac_user, rx_ctrl, frame_hdr, &filter_serv_info);
841 }
842 #endif
843
844 hmac_rx_netbuf_add_to_list_tail(netbuf_header, rx_ctrl, ret, buf_nums, is_ba_buf);
845 }
846 }
847
848 /* ****************************************************************************
849 功能描述 : 逐一处理需要上报的帧
850 修改历史 :
851 1.日 期 : 2015年1月3日
852 作 者 : HiSilicon
853 修改内容 : 新生成函数
854 **************************************************************************** */
hmac_rx_lan_frame(const oal_netbuf_head_stru * netbuf_header)855 hi_void hmac_rx_lan_frame(const oal_netbuf_head_stru *netbuf_header)
856 {
857 hi_u32 netbuf_num;
858 oal_netbuf_stru *temp_netbuf = HI_NULL;
859 oal_netbuf_stru *netbuf = HI_NULL;
860 hi_u8 buf_nums;
861 hmac_rx_ctl_stru *rx_ctrl = HI_NULL;
862 mac_ieee80211_frame_stru *frame_hdr = HI_NULL;
863 hmac_vap_stru *hmac_vap = HI_NULL;
864 hi_u32 err_code;
865
866 netbuf_num = oal_netbuf_get_buf_num(netbuf_header);
867 temp_netbuf = oal_netbuf_peek(netbuf_header);
868
869 while (netbuf_num != 0) {
870 netbuf = temp_netbuf;
871 if (netbuf == NULL) {
872 break;
873 }
874
875 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
876 frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
877 buf_nums = rx_ctrl->buff_nums;
878
879 netbuf_num = hi_sub(netbuf_num, buf_nums);
880 oal_netbuf_get_appointed_netbuf(netbuf, buf_nums, &temp_netbuf);
881
882 hmac_vap = hmac_vap_get_vap_stru(rx_ctrl->mac_vap_id);
883 if (hmac_vap == HI_NULL) {
884 oam_error_log1(0, OAM_SF_RX, "{hmac_rx_lan_frame::hmac_vap_get_vap_stru null. vap_id:%u}",
885 rx_ctrl->mac_vap_id);
886 continue;
887 }
888 rx_ctrl->us_da_user_idx = hmac_vap->base_vap->assoc_vap_id;
889
890 err_code = hmac_rx_lan_frame_classify(hmac_vap, netbuf, frame_hdr);
891 if (err_code != HI_SUCCESS) {
892 hmac_rx_free_netbuf(netbuf, (hi_u16)buf_nums);
893 }
894 }
895 }
896
hmac_rx_process_data_insert_list(hi_u16 us_netbuf_num,oal_netbuf_stru * temp_netbuf,oal_netbuf_head_stru * netbuf_header,const hmac_vap_stru * hmac_vap)897 static hi_void hmac_rx_process_data_insert_list(hi_u16 us_netbuf_num, oal_netbuf_stru *temp_netbuf,
898 oal_netbuf_head_stru *netbuf_header, const hmac_vap_stru *hmac_vap)
899 {
900 oal_netbuf_stru *netbuf = HI_NULL; /* 用于保存当前处理的MPDU的第一个netbuf指针 */
901 #ifdef _PRE_WLAN_FEATURE_PROMIS
902 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
903 hmac_rx_ctl_stru *rx_ctrl = HI_NULL;
904 hi_u8 bssid[WLAN_MAC_ADDR_LEN] = {0};
905 mac_ieee80211_frame_stru *mac_frame = HI_NULL;
906 #endif
907 #endif
908 while (us_netbuf_num != 0) {
909 netbuf = temp_netbuf;
910 if (netbuf == HI_NULL) {
911 break;
912 }
913 temp_netbuf = oal_netbuf_next(netbuf);
914 #ifdef _PRE_WLAN_FEATURE_PROMIS
915 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
916 mac_device_stru *mac_dev = mac_res_get_dev();
917 if (mac_dev->promis_switch) {
918 /* 处理上报的其他BSS组播数据包 */
919 hi_u32 ret = hwal_send_others_bss_data(netbuf);
920 if (ret != HI_SUCCESS) {
921 oam_error_log1(0, OAM_SF_RX, "hwal_send_others_bss_data failed! ul_ret=%d", ret);
922 }
923 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
924 if (rx_ctrl == HI_NULL) {
925 oal_netbuf_free(netbuf);
926 us_netbuf_num--;
927 continue;
928 }
929 mac_frame = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
930 mac_get_bssid((const hi_u8 *)mac_frame, (hi_u8 *)bssid, WLAN_MAC_ADDR_LEN);
931 if (memcmp(bssid, hmac_vap->base_vap->auc_bssid, WLAN_MAC_ADDR_LEN) != 0) {
932 oal_netbuf_free(netbuf);
933 us_netbuf_num--;
934 continue;
935 }
936 }
937 #endif
938 #endif
939 oal_netbuf_add_to_list_tail(netbuf, netbuf_header);
940 us_netbuf_num--;
941 }
942 if (us_netbuf_num != 0) {
943 oam_error_log1(0, OAM_SF_RX, "{hmac_rx_process_data_insert_list::us_netbuf_num[%d].}", us_netbuf_num);
944 }
945 }
946
947 /* ****************************************************************************
948 功能描述 : AP模式下,HMAC模块接收WLAN_DRX事件(数据帧)的处理函数
949 输入参数 : 事件结构体指针
950 返 回 值 : 成功或者失败原因
951 修改历史 :
952 1.日 期 : 2013年3月05日
953 作 者 : HiSilicon
954 修改内容 : 新生成函数
955 **************************************************************************** */
hmac_rx_process_data_ap(frw_event_mem_stru * event_mem)956 hi_u32 hmac_rx_process_data_ap(frw_event_mem_stru *event_mem)
957 {
958 if (event_mem == HI_NULL) {
959 oam_error_log0(0, OAM_SF_ANY, "{hmac_rx_process_data_ap::evenevent_memt is NULL!}\r\n");
960 return HI_ERR_CODE_PTR_NULL;
961 }
962 /* 获取事件头和事件结构体指针 */
963 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
964 frw_event_hdr_stru *event_hdr = &(event->event_hdr);
965 dmac_wlan_drx_event_stru *wlan_rx_event = (dmac_wlan_drx_event_stru *)(event->auc_event_data);
966 /* 用于临时保存下一个需要处理的netbuf指针 */
967 oal_netbuf_stru *temp_netbuf = (oal_netbuf_stru *)wlan_rx_event->netbuf;
968 hi_u16 us_netbuf_num = wlan_rx_event->us_netbuf_num; /* netbuf链表的个数 */
969 oal_netbuf_head_stru netbuf_header; /* 存储上报给网络层的数据 */
970
971 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(event_hdr->vap_id);
972 if (hmac_vap == HI_NULL || hmac_vap->base_vap == HI_NULL) {
973 oam_error_log0(0, OAM_SF_RX, "{hmac_rx_process_data_ap::hmac_vap/mac_vap null.}");
974 return HI_ERR_CODE_PTR_NULL;
975 }
976 /* 将所有netbuff全部入链表 */
977 oal_netbuf_list_head_init(&netbuf_header);
978 hmac_rx_process_data_insert_list(us_netbuf_num, temp_netbuf, &netbuf_header, hmac_vap);
979
980 if (oal_netbuf_list_empty(&netbuf_header) == HI_TRUE) {
981 return HI_SUCCESS;
982 }
983
984 /* 将Dmac上报的帧进入reorder队列过滤一下 */
985 hmac_rx_process_data_filter(&netbuf_header, (oal_netbuf_stru *)wlan_rx_event->netbuf, wlan_rx_event->us_netbuf_num);
986
987 #ifdef _PRE_WLAN_FEATURE_MESH
988 if (hmac_vap->base_vap->vap_mode == WLAN_VAP_MODE_MESH) {
989 /* 将需要上报的帧逐一出队处理 */
990 hmac_rx_process_data_mesh_tcp_ack_opt(hmac_vap, &netbuf_header);
991 } else {
992 hmac_rx_process_data_ap_tcp_ack_opt(hmac_vap, &netbuf_header);
993 }
994 #else
995 hmac_rx_process_data_ap_tcp_ack_opt(hmac_vap, &netbuf_header);
996 #endif
997
998 return HI_SUCCESS;
999 }
1000
hmac_rx_process_no_multicast_proc(const hmac_vap_stru * hmac_vap,const hi_u8 * mac_addr,oal_netbuf_stru * netbuf,oal_netbuf_head_stru * w2w_netbuf_hdr)1001 hi_void hmac_rx_process_no_multicast_proc(const hmac_vap_stru *hmac_vap, const hi_u8 *mac_addr,
1002 oal_netbuf_stru *netbuf, oal_netbuf_head_stru *w2w_netbuf_hdr)
1003 {
1004 hi_u8 user_idx;
1005 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
1006 mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
1007
1008 /* 获取目的地址对应的用户指针 */
1009 hi_u32 rslt = mac_vap_find_user_by_macaddr(hmac_vap->base_vap, mac_addr, WLAN_MAC_ADDR_LEN, &user_idx);
1010 if (rslt == HI_ERR_CODE_PTR_NULL) { /* 查找用户失败 */
1011 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_process_no_multicast_proc::get user Err}");
1012
1013 /* 释放当前处理的MPDU占用的netbuf */
1014 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1015 return;
1016 }
1017
1018 /* 没有找到对应的用户 */
1019 if (rslt != HI_SUCCESS) {
1020 /* 目的用户不在AP的用户表中,调用wlan_to_lan转发接口 */
1021 rslt = hmac_rx_lan_frame_classify(hmac_vap, netbuf, frame_hdr);
1022 if (rslt != HI_SUCCESS) {
1023 oam_warning_log1(rx_ctrl->vap_id, OAM_SF_RX, "hmac_rx_process_data_ap_tcp_ack_opt:: rx_lan_frame_fail[%d]",
1024 rslt);
1025 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1026 }
1027 return;
1028 }
1029
1030 /* 目的用户已在AP的用户表中,进行WLAN_TO_WLAN转发 */
1031 hmac_user_stru *hmac_user = (hmac_user_stru *)hmac_user_get_user_stru(user_idx);
1032 if ((hmac_user == HI_NULL) || (hmac_user->base_user == HI_NULL)) {
1033 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "{hmac_rx_process_no_multicast_proc::hmac_user null}");
1034
1035 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1036 return;
1037 }
1038
1039 if (hmac_user->base_user->user_asoc_state != MAC_USER_STATE_ASSOC) {
1040 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX,
1041 "{hmac_rx_process_no_multicast_proc::the station is not associated with ap.}");
1042
1043 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1044 hmac_mgmt_send_deauth_frame(hmac_vap->base_vap, mac_addr, WLAN_MAC_ADDR_LEN, MAC_NOT_AUTHED);
1045 return;
1046 }
1047
1048 /* 将目的地址的资源池索引值放到cb字段中,user的asoc id会在关联的时候被赋值 */
1049 rx_ctrl->us_da_user_idx = hmac_user->base_user->us_assoc_id;
1050
1051 /* 将MPDU解析成单个MSDU,把所有的MSDU组成一个netbuf链 */
1052 if (hmac_rx_prepare_msdu_list_to_wlan(hmac_vap, w2w_netbuf_hdr, netbuf, frame_hdr) != HI_SUCCESS) {
1053 oam_warning_log0(hmac_vap->base_vap->vap_id, OAM_SF_RX, "hmac_rx_prepare_msdu_list_to_wlan return NON SUCCESS");
1054 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1055 }
1056 }
1057
1058 /* ****************************************************************************
1059 功能描述 : AP模式下,HMAC模块接收WLAN_DRX事件(数据帧)的处理函数
1060 输入参数 : 事件结构体指针
1061 返 回 值 : 成功或者失败原因
1062 修改历史 :
1063 1.日 期 : 2013年3月5日
1064 作 者 : HiSilicon
1065 修改内容 : 新生成函数
1066 **************************************************************************** */
hmac_rx_process_data_ap_tcp_ack_opt(const hmac_vap_stru * hmac_vap,const oal_netbuf_head_stru * netbuf_header)1067 hi_void hmac_rx_process_data_ap_tcp_ack_opt(const hmac_vap_stru *hmac_vap, const oal_netbuf_head_stru *netbuf_header)
1068 {
1069 mac_ieee80211_frame_stru *copy_frame_hdr = HI_NULL; /* 保存mac帧的指针 */
1070 oal_netbuf_stru *netbuf_copy = HI_NULL; /* 用于保存组播帧copy */
1071 oal_netbuf_stru *temp_netbuf = oal_netbuf_peek(netbuf_header);
1072 hi_u8 *mac_addr = HI_NULL; /* 保存用户目的地址的指针 */
1073 hi_u16 us_netbuf_num = (hi_u16)oal_netbuf_get_buf_num(netbuf_header);
1074 oal_netbuf_head_stru w2w_netbuf_hdr; /* 保存wlan to wlan的netbuf链表的头 */
1075 frw_event_hdr_stru event_hdr;
1076
1077 event_hdr.vap_id = hmac_vap->base_vap->vap_id;
1078 /* 循环收到的每一个MPDU,处情况如下:
1079 1、组播帧时,调用WLAN TO WLAN和WLAN TO LAN接口
1080 2、其他,根据实际情况,调用WLAN TO LAN接口或者WLAN TO WLAN接口 */
1081 oal_netbuf_list_head_init(&w2w_netbuf_hdr);
1082 while (us_netbuf_num != 0) {
1083 oal_netbuf_stru *netbuf = temp_netbuf;
1084 if (netbuf == HI_NULL) {
1085 break;
1086 }
1087 hmac_rx_ctl_stru *rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
1088 /* 获取帧头信息 */
1089 mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
1090 /* 获取下一个要处理的MPDU */
1091 oal_netbuf_get_appointed_netbuf(netbuf, rx_ctrl->buff_nums, &temp_netbuf);
1092 us_netbuf_num = hi_sub(us_netbuf_num, rx_ctrl->buff_nums);
1093 hmac_vap = hmac_vap_get_vap_stru(rx_ctrl->mac_vap_id);
1094 if (oal_unlikely(hmac_vap == HI_NULL)) {
1095 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1096 continue;
1097 }
1098
1099 /* 获取接收端地址 */
1100 mac_rx_get_da(frame_hdr, &mac_addr);
1101 /* 单播报文处理 */
1102 if (ether_is_multicast(mac_addr) == HI_FALSE) {
1103 hmac_rx_process_no_multicast_proc(hmac_vap, mac_addr, netbuf, &w2w_netbuf_hdr);
1104 continue;
1105 }
1106 /* 目的地址为组播地址时,进行WLAN_TO_WLAN和WLAN_TO_LAN的转发 */
1107 if (hmac_rx_copy_netbuff(&netbuf_copy, netbuf, rx_ctrl->mac_vap_id, ©_frame_hdr) == HI_SUCCESS) {
1108 /* 将MPDU解析成单个MSDU,把所有的MSDU组成一个netbuf链 */
1109 if (hmac_rx_prepare_msdu_list_to_wlan(hmac_vap, &w2w_netbuf_hdr, netbuf_copy, copy_frame_hdr) !=
1110 HI_SUCCESS) {
1111 oam_warning_log0(0, OAM_SF_RX, "hmac_rx_prepare_msdu_list_to_wlan return NON SUCCESS");
1112 oal_netbuf_free(netbuf_copy);
1113 }
1114 }
1115 /* 上报网络层 WLAN_TO_LAN */
1116 hi_u32 err_code = hmac_rx_lan_frame_classify(hmac_vap, netbuf, frame_hdr);
1117 if (err_code != HI_SUCCESS) {
1118 hmac_rx_free_netbuf(netbuf, (hi_u16)rx_ctrl->buff_nums);
1119 }
1120 }
1121
1122 /* 将MSDU链表交给发送流程处理 WLAN_TO_WLAN */
1123 if ((oal_netbuf_list_empty(&w2w_netbuf_hdr) == HI_FALSE) && (oal_netbuf_tail(&w2w_netbuf_hdr) != HI_NULL) &&
1124 (oal_netbuf_peek(&w2w_netbuf_hdr) != HI_NULL)) {
1125 set_oal_netbuf_next((oal_netbuf_tail(&w2w_netbuf_hdr)), HI_NULL);
1126 set_oal_netbuf_prev((oal_netbuf_peek(&w2w_netbuf_hdr)), HI_NULL);
1127
1128 hmac_rx_transmit_to_wlan(&event_hdr, &w2w_netbuf_hdr);
1129 }
1130 }
1131
1132 /* ****************************************************************************
1133 功能描述 : STA模式下,HMAC模块接收WLAN_DRX事件(数据帧)的处理函数
1134 输入参数 : 事件结构体指针
1135 返 回 值 : 成功或者失败原因
1136 修改历史 :
1137 1.日 期 : 2013年3月5日
1138 作 者 : HiSilicon
1139 修改内容 : 新生成函数
1140 ************************ **************************************************** */
hmac_rx_process_data_sta(frw_event_mem_stru * event_mem)1141 hi_u32 hmac_rx_process_data_sta(frw_event_mem_stru *event_mem)
1142 {
1143 hi_u16 us_netbuf_num; /* netbuf链表的个数 */
1144 oal_netbuf_head_stru netbuf_header; /* 存储上报给网络层的数据 */
1145
1146 if (oal_unlikely(event_mem == HI_NULL)) {
1147 oam_error_log0(0, OAM_SF_RX, "{hmac_rx_process_data_sta::event_mem null.}");
1148 return HI_ERR_CODE_PTR_NULL;
1149 }
1150
1151 /* 获取事件头和事件结构体指针 */
1152 frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
1153 frw_event_hdr_stru *event_hdr = &(event->event_hdr);
1154 dmac_wlan_drx_event_stru *wlan_rx_event = (dmac_wlan_drx_event_stru *)(event->auc_event_data);
1155 oal_netbuf_stru *temp_netbuf = (oal_netbuf_stru *)wlan_rx_event->netbuf;
1156 us_netbuf_num = wlan_rx_event->us_netbuf_num;
1157
1158 hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(event_hdr->vap_id);
1159 if (hmac_vap == HI_NULL || hmac_vap->base_vap == HI_NULL) {
1160 oam_error_log0(0, OAM_SF_RX, "{hmac_rx_process_data_sta::hmac_vap/mac_vap null.}");
1161 hmac_rx_free_netbuf(temp_netbuf, us_netbuf_num);
1162 return HI_ERR_CODE_PTR_NULL;
1163 }
1164 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
1165 /* If mib info is null ptr,release the netbuf */
1166 if (hmac_vap->base_vap->mib_info == NULL) {
1167 oam_warning_log0(0, OAM_SF_ANY, "{hmac_rx_process_data_sta::pst_mib_info null.}");
1168 hmac_rx_free_netbuf(temp_netbuf, us_netbuf_num);
1169 return HI_SUCCESS;
1170 }
1171 #endif
1172
1173 /* 将所有netbuff全部入链表 */
1174 oal_netbuf_list_head_init(&netbuf_header);
1175 hmac_rx_process_data_insert_list(us_netbuf_num, temp_netbuf, &netbuf_header, hmac_vap);
1176
1177 if (oal_netbuf_list_empty(&netbuf_header) == HI_TRUE) {
1178 return HI_SUCCESS;
1179 }
1180
1181 hmac_rx_process_data_filter(&netbuf_header, (oal_netbuf_stru *)wlan_rx_event->netbuf, wlan_rx_event->us_netbuf_num);
1182 hmac_rx_lan_frame(&netbuf_header);
1183 return HI_SUCCESS;
1184 }
1185
1186 #ifdef _PRE_WLAN_FEATURE_MESH
1187 /* ****************************************************************************
1188 功能描述 : mesh模式下,HMAC模块接收WLAN_DRX事件(数据帧)的处理函数
1189 输入参数 : 事件结构体指针
1190 返 回 值 : 成功或者失败原因
1191 修改历史 :
1192 1.日 期 : 2019年2月23日
1193 作 者 : HiSilicon
1194 修改内容 : 新生成函数
1195 **************************************************************************** */
hmac_rx_process_data_mesh_tcp_ack_opt(hmac_vap_stru * hmac_vap,const oal_netbuf_head_stru * netbuf_header)1196 hi_void hmac_rx_process_data_mesh_tcp_ack_opt(hmac_vap_stru *hmac_vap, const oal_netbuf_head_stru *netbuf_header)
1197 {
1198 mac_ieee80211_frame_stru *frame_hdr = HI_NULL; /* 保存mac帧的指针 */
1199 hi_u8 *da_mac_addr = HI_NULL; /* 保存用户目的地址的指针 */
1200 hmac_rx_ctl_stru *rx_ctrl = HI_NULL; /* 每一个MPDU的控制信息 */
1201 hi_u16 us_netbuf_num; /* netbuf链表的个数 */
1202 hi_u8 buf_nums; /* 每个mpdu占有buf的个数 */
1203 oal_netbuf_stru *netbuf = HI_NULL; /* 用于保存当前处理的MPDU的第一个netbuf指针 */
1204 oal_netbuf_stru *temp_netbuf = HI_NULL; /* 用于临时保存下一个需要处理的netbuf指针 */
1205 hi_u32 err_code;
1206
1207 temp_netbuf = oal_netbuf_peek(netbuf_header);
1208 us_netbuf_num = (hi_u16)oal_netbuf_get_buf_num(netbuf_header);
1209
1210 while (us_netbuf_num != 0) {
1211 netbuf = temp_netbuf;
1212 if (netbuf == HI_NULL) {
1213 break;
1214 }
1215
1216 rx_ctrl = (hmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
1217
1218 /* 获取帧头信息 */
1219 frame_hdr = (mac_ieee80211_frame_stru *)rx_ctrl->pul_mac_hdr_start_addr;
1220
1221 /* 获取当前MPDU占用的netbuf数目 */
1222 buf_nums = rx_ctrl->buff_nums;
1223
1224 /* 获取下一个要处理的MPDU */
1225 oal_netbuf_get_appointed_netbuf(netbuf, buf_nums, &temp_netbuf);
1226 us_netbuf_num = hi_sub(us_netbuf_num, buf_nums);
1227
1228 hmac_vap = hmac_vap_get_vap_stru(rx_ctrl->mac_vap_id);
1229 if (oal_unlikely(hmac_vap == HI_NULL)) {
1230 oam_warning_log0(rx_ctrl->vap_id, OAM_SF_RX, "{hmac_rx_process_data_mesh_tcp_ack_opt::pst_vap null.}");
1231 hmac_rx_free_netbuf(netbuf, (hi_u16)buf_nums);
1232 continue;
1233 }
1234 /* 获取接收端地址 */
1235 mac_rx_get_da(frame_hdr, &da_mac_addr);
1236
1237 err_code = hmac_rx_lan_frame_classify(hmac_vap, netbuf, frame_hdr); /* 上报网络层 */
1238 if (err_code != HI_SUCCESS) {
1239 oam_warning_log1(rx_ctrl->vap_id, OAM_SF_RX,
1240 "hmac_rx_process_data_ap_tcp_ack_opt:: rx_lan_frame_fail[%d]", err_code);
1241 hmac_rx_free_netbuf(netbuf, (hi_u16)buf_nums);
1242 }
1243 }
1244
1245 return;
1246 }
1247 #endif
1248
1249 #ifdef __cplusplus
1250 #if __cplusplus
1251 }
1252 #endif
1253 #endif
1254