• 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 "hcc_hmac_if.h"
23 #include "hmac_ext_if.h"
24 #include "hcc_comm.h"
25 #include "hcc_host.h"
26 #include "hmac_tx_data.h"
27 #include "oam_ext_if.h"
28 #include "oal_util.h"
29 #ifndef _PRE_FEATURE_HCC_TASK
30 #include "flow_control.h"
31 #endif
32 #ifdef __cplusplus
33 #if __cplusplus
34 extern "C" {
35 #endif
36 #endif
37 
38 /* ****************************************************************************
39   2 全局变量定义
40 **************************************************************************** */
41 #define WIDTH_BIT32 2
42 static hcc_hmac_rx_event_handle g_s_handle = { NULL, NULL };
43 
44 /* ****************************************************************************
45   3 函数实现
46 **************************************************************************** */
47 #ifdef _PRE_LWIP_ZERO_COPY
hcc_is_data_frame(const frw_event_mem_stru * event_mem)48 static inline hi_bool hcc_is_data_frame(const frw_event_mem_stru *event_mem)
49 {
50     frw_event_hdr_stru *event_hdr = HI_NULL;
51 
52     event_hdr = frw_get_event_hdr(event_mem);
53     return (event_hdr->type == FRW_EVENT_TYPE_WLAN_DRX);
54 }
55 #endif
56 
57 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_DMAC)
hcc_hmac_rx_event_register(const hcc_hmac_rx_event_handle * handle)58 static hi_u32 hcc_hmac_rx_event_register(const hcc_hmac_rx_event_handle *handle)
59 {
60     if (handle == HI_NULL) {
61         return HI_ERR_CODE_PTR_NULL;
62     }
63 
64     if (memcpy_s(&g_s_handle, sizeof(hcc_hmac_rx_event_handle), handle, sizeof(hcc_hmac_rx_event_handle)) != EOK) {
65         oam_error_log0(0, OAM_SF_CFG, "hcc_hmac_rx_event_register:: handle memcpy_s fail.");
66         return HI_FAIL;
67     }
68     return HI_SUCCESS;
69 }
70 #endif
71 
hcc_hmac_rx_event_unregister(hi_void)72 static hi_void hcc_hmac_rx_event_unregister(hi_void)
73 {
74     /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
75     memset_s(&g_s_handle, sizeof(hcc_hmac_rx_event_handle), 0, sizeof(hcc_hmac_rx_event_handle));
76 }
77 
78 /* ****************************************************************************
79  功能描述  : HCC到HMAC的控制数据分发
80 
81  修改历史      :
82   1.日    期   : 2019-05-30
83     作    者   : HiSilicon
84     修改内容   : 新生成函数
85 **************************************************************************** */
hcc_to_hmac_control_event_dispatch(frw_event_mem_stru * event_mem)86 hi_u32 hcc_to_hmac_control_event_dispatch(frw_event_mem_stru *event_mem)
87 {
88     if (g_s_handle.control == NULL) {
89         oam_warning_log0(0, 0, "hcc_to_hmac_control_event_dispatch: control is NULL");
90         return HI_FAIL;
91     }
92 
93     return g_s_handle.control(event_mem);
94 }
95 
96 /* init extend head for sdio host tx */
hcc_hmac_tx_adapt_extend_hdr_init(const frw_event_mem_stru * hcc_event_mem,const oal_netbuf_stru * netbuf,hi_u8 config_frame)97 static hi_void hcc_hmac_tx_adapt_extend_hdr_init(const frw_event_mem_stru *hcc_event_mem,
98     const oal_netbuf_stru *netbuf, hi_u8 config_frame)
99 {
100     frw_hcc_extend_hdr_stru *ext_hdr = HI_NULL;
101     frw_event_hdr_stru *event_hdr = HI_NULL;
102 
103     event_hdr = frw_get_event_hdr(hcc_event_mem);
104 
105     ext_hdr = (frw_hcc_extend_hdr_stru *)oal_netbuf_data(netbuf);
106     ext_hdr->nest_type = event_hdr->type;
107     ext_hdr->nest_sub_type = event_hdr->sub_type;
108     ext_hdr->vap_id = event_hdr->vap_id;
109     ext_hdr->config_frame = config_frame;
110 }
111 
112 /* hcc sdio host init hcc hdr */
hcc_hmac_tx_hcc_hdr_init(oal_netbuf_stru * netbuf,const hcc_transfer_param * param)113 hi_u32 hcc_hmac_tx_hcc_hdr_init(oal_netbuf_stru *netbuf, const hcc_transfer_param *param)
114 {
115     hcc_header_stru *hcc_hdr = HI_NULL;
116     oal_netbuf_stru *netbuf_temp = netbuf;
117     hi_u32 pad_hdr;
118     hi_u32 headroom;
119     hi_u32 payload_len;
120 
121     /* calculate the pad length to ensure the hcc_total_len is 64Bytes */
122     pad_hdr = HCC_HDR_RESERVED_MAX_LEN - param->extend_len;
123     headroom = pad_hdr + HCC_HDR_LEN;
124     payload_len = oal_netbuf_len(netbuf) - param->extend_len;
125 
126     if (oal_netbuf_headroom(netbuf_temp) < headroom) {
127         oam_error_log2(0, 0, "hcc_hmac_tx_hcc_hdr_init:: headroom[%d] is not enough, need[%d]",
128             oal_netbuf_headroom(netbuf_temp), headroom);
129         return HI_FAIL;
130     }
131     hcc_hdr = (hcc_header_stru *)oal_netbuf_push(netbuf_temp, headroom);
132     if (hcc_hdr == HI_NULL) {
133         return HI_FAIL;
134     }
135 
136     hcc_hdr->main_type = param->main_type;
137     hcc_hdr->sub_type = param->sub_type;
138     hcc_hdr->pay_len = payload_len;
139     hcc_hdr->seq = g_sdio_txpkt_index++;
140     hcc_hdr->pad_hdr = HCC_HDR_RESERVED_MAX_LEN - param->extend_len;
141     hcc_hdr->pad_payload = 0; /* Device alloc netbuf's payload all 4B aligned! */
142 
143     return HI_SUCCESS;
144 }
145 
hcc_tx_netbuf_destroy(hcc_handler_stru * hcc_handler)146 static hi_void hcc_tx_netbuf_destroy(hcc_handler_stru *hcc_handler)
147 {
148     if (hcc_handler != HI_NULL) {
149         oal_wake_unlock(&hcc_handler->tx_wake_lock);
150     }
151 }
152 
hcc_sort_key_frame(hcc_trans_queue_stru * hcc_queue,oal_netbuf_stru * netbuf)153 hi_void hcc_sort_key_frame(hcc_trans_queue_stru *hcc_queue, oal_netbuf_stru *netbuf)
154 {
155     oal_netbuf_head_stru *head;
156     hi_u32 flags;
157     oal_netbuf_stru *netbuf_tmp = HI_NULL;
158     oal_netbuf_stru *netbuf_pos = HI_NULL;
159     hi_u8 is_insert = HI_FALSE;
160     head = &hcc_queue->data_queue;
161 
162     oal_spin_lock_irq_save((oal_spin_lock_stru *)&head->lock, (unsigned long *)&flags);
163     oal_skb_queue_walk_safe(head, netbuf_pos, netbuf_tmp)
164     {
165         dmac_tx_ctl_stru *dmac_tx_ctrl = HI_NULL;
166         hi_u8 *hcc_hdr = (hi_u8 *)oal_netbuf_data(netbuf_pos);
167         dmac_tx_ctrl = (dmac_tx_ctl_stru *)(hcc_hdr + HCC_HDR_LEN + sizeof(frw_hcc_extend_hdr_stru));
168         if (dmac_tx_ctrl != HI_NULL && dmac_tx_ctrl->is_vipframe != HI_TRUE &&
169             dmac_tx_ctrl->high_prio_sch != HI_TRUE) {
170             oal_netbuf_append(head, netbuf, netbuf_pos);
171             is_insert = HI_TRUE;
172             break;
173         }
174     }
175     oal_spin_unlock_irq_restore((oal_spin_lock_stru *)&head->lock, (unsigned long *)&flags);
176 
177     if (!is_insert) {
178         oal_netbuf_list_tail(head, netbuf);
179     }
180 }
181 
182 /* hcc sdio host tx */
hcc_host_tx(hcc_handler_stru * hcc_handler,oal_netbuf_stru * netbuf,const hcc_transfer_param * param)183 hi_u32 hcc_host_tx(hcc_handler_stru *hcc_handler, oal_netbuf_stru *netbuf, const hcc_transfer_param *param)
184 {
185     hi_u32 err_code;
186     hcc_tx_cb_stru *hcc_cb = HI_NULL;
187     hi_u8 is_vipframe = HI_FALSE;
188 #ifdef _PRE_FEATURE_HCC_TASK
189     hcc_trans_queue_stru *hcc_queue = HI_NULL;
190     hcc_queue = &hcc_handler->hcc_transer_info.hcc_queues[HCC_TX].queues[param->queue_id];
191 #else
192     struct FlowControlModule *fcm = HI_NULL;
193     hcc_convert_queue_para para;
194     (void)hcc_handler;
195 #endif
196     /* 1. build hcc header */
197     err_code = hcc_hmac_tx_hcc_hdr_init(netbuf, param);
198     if (err_code != HI_SUCCESS) {
199         return HI_FAIL;
200     }
201 
202     /* 2. init hcc cb ctrl */
203     hcc_cb = (hcc_tx_cb_stru *)oal_netbuf_cb(netbuf);
204     hcc_cb->destroy = hcc_tx_netbuf_destroy;
205     hcc_cb->magic = HCC_TX_WAKELOCK_MAGIC;
206     if (param->queue_id == DATA_LO_QUEUE) {
207         dmac_tx_ctl_stru *dmac_tx_ctrl = HI_NULL;
208         hi_u8 *hcc_hdr = (hi_u8 *)oal_netbuf_data(netbuf);
209         dmac_tx_ctrl = (dmac_tx_ctl_stru *)(hcc_hdr + HCC_HDR_LEN + sizeof(frw_hcc_extend_hdr_stru));
210         if (dmac_tx_ctrl != HI_NULL &&
211             dmac_tx_ctrl->is_vipframe != HI_TRUE && dmac_tx_ctrl->high_prio_sch != HI_TRUE &&
212             hcc_list_overflow()) {
213             /* 非关键帧 */
214             oal_netbuf_free(netbuf);
215             return HI_SUCCESS;
216         }
217 
218         if (dmac_tx_ctrl != HI_NULL &&
219             (dmac_tx_ctrl->is_vipframe == HI_TRUE || dmac_tx_ctrl->high_prio_sch == HI_TRUE)) {
220             is_vipframe = HI_TRUE;
221         }
222 
223         if (is_vipframe && hcc_discard_key_frame()) {
224             oal_netbuf_free(netbuf);
225             return HI_SUCCESS;
226         }
227     }
228 
229 #ifdef _PRE_FEATURE_HCC_TASK
230     if (is_vipframe) {
231         hcc_sort_key_frame(hcc_queue, netbuf);
232     } else {
233         /* 3. netbuf enqueue */
234         oal_netbuf_list_tail(&hcc_queue->data_queue, netbuf);
235     }
236 
237     /* 4. sched hcc tx */
238     hcc_sched_transfer(hcc_handler);
239 #else
240     fcm = GetFlowControlModule();
241     if (fcm != NULL && fcm->op != NULL && fcm->op->getTxQueueId != NULL) {
242         para.queueType = param->queue_id;
243         para.isVip = is_vipframe;
244         FlowControlQueueID id = fcm->op->getTxQueueId((void *)(&para));
245         fcm->interface->sendBuffToFCM(fcm, netbuf, id, FLOW_TX);
246         fcm->interface->schedFCM(fcm, FLOW_TX);
247     }
248 #endif
249     return HI_SUCCESS;
250 }
251 
252 #define HCC_NETBUF_RESERVED_ROOM_SIZE (HCC_HDR_TOTAL_LEN + HISDIO_H2D_SCATT_BUFFLEN_ALIGN)
253 /* ****************************************************************************
254  功能描述  : HMAC通过HCC SIDO发送到DMAC的控制数据事件
255  修改历史      :
256   1.日    期   : 2019-12-21
257     作    者   : HiSilicon
258     修改内容   : 新生成函数
259 **************************************************************************** */
hcc_tx_netbuf_normal(const frw_event_mem_stru * event_mem,oal_netbuf_stru * netbuf,hi_u32 hdr_len)260 hi_u32 hcc_tx_netbuf_normal(const frw_event_mem_stru *event_mem, oal_netbuf_stru *netbuf, hi_u32 hdr_len)
261 {
262     hcc_transfer_param param = { 0 };
263     hi_u32 err_code;
264     hi_u32 queue_id;
265     hi_u32 fc_type;
266     hi_u8 config_frame = 1;
267 
268     frw_event_stru *event = (frw_event_stru *)event_mem->puc_data;
269     if (event == HI_NULL) {
270         return HI_FAIL;
271     }
272     hi_u32 sub_type = (event->event_hdr.type == FRW_EVENT_TYPE_HOST_DRX) ? WIFI_DATA_TYPE : WIFI_CONTROL_TYPE;
273 
274     if (event->event_hdr.type >= FRW_EVENT_TYPE_BUTT) {
275         oam_error_log1(0, 0, "hcc_tx_netbuf_normal:: invalid event type[%d]!", event->event_hdr.type);
276         return HI_FAIL;
277     }
278     queue_id = g_hcc_sched_stat[event->event_hdr.type];
279     fc_type = g_hcc_flowctrl_stat[event->event_hdr.type];
280 
281     /* HMAC_TO_DMAC_SYN_CFG事件的SET_WPS_P2P_IE在sdio发送时申请管理帧 */
282     if (event->event_hdr.type == FRW_EVENT_TYPE_HOST_CRX && event->event_hdr.sub_type == HMAC_TO_DMAC_SYN_CFG) {
283         hmac_to_dmac_cfg_msg_stru *syn_msg = (hmac_to_dmac_cfg_msg_stru *)event->auc_event_data;
284         if (syn_msg != HI_NULL && syn_msg->syn_id == WLAN_CFGID_SET_WPS_P2P_IE) {
285             config_frame = 0;
286         }
287     }
288 
289     /* FRW_EVENT_TYPE_WLAN_CTX事件在sdio发送时申请管理帧 */
290     if (event->event_hdr.type == FRW_EVENT_TYPE_WLAN_CTX) {
291         config_frame = 0;
292     }
293 
294     /* 1. 初始化HCC头 */
295     hcc_hdr_param_init(&param, HCC_ACTION_TYPE_WIFI, sub_type,
296                        (hdr_len + (hi_u32)sizeof(frw_hcc_extend_hdr_stru)), fc_type, queue_id);
297     if (oal_netbuf_headroom(netbuf) < sizeof(frw_hcc_extend_hdr_stru)) {
298         oam_error_log2(0, 0, "hcc_hmac_tx_hcc_hdr_init:: headroom[%d] is not enough, need[%d]",
299             oal_netbuf_headroom(netbuf), sizeof(frw_hcc_extend_hdr_stru));
300         return HI_FAIL;
301     }
302 
303     /* 2. add extend area (extend head include HCC, MAC_HDR) */
304     oal_netbuf_push(netbuf, sizeof(frw_hcc_extend_hdr_stru));
305     /* 3. 初始化extent hdr */
306     hcc_hmac_tx_adapt_extend_hdr_init(event_mem, netbuf, config_frame);
307 
308     err_code = hcc_host_tx(hcc_host_get_handler(), netbuf, &param);
309     if (err_code != HI_SUCCESS) {
310         oam_error_log1(0, 0, "hcc_tx_netbuf_normal:: hcc_host_tx fail[%d]", err_code);
311         return HI_FAIL;
312     }
313 
314     return HI_SUCCESS;
315 }
316 
317 /* HCC 将控制事件中的payload 转换为netbuf */
hmac_hcc_tx_event_buf_to_netbuf(const frw_event_mem_stru * event_mem,hi_u16 payload_len)318 hi_u32 hmac_hcc_tx_event_buf_to_netbuf(const frw_event_mem_stru *event_mem, hi_u16 payload_len)
319 {
320     hi_u8 *event_payload = HI_NULL;
321     oal_netbuf_stru *netbuf = HI_NULL;
322 
323     event_payload = frw_get_event_payload(event_mem);
324     if (event_payload == HI_NULL) {
325         oam_error_log0(0, 0, "hmac_hcc_tx_netbuf_adapt:: event_payload is NULL");
326         return HI_FAIL;
327     }
328 
329     netbuf = oal_netbuf_alloc(payload_len + HCC_NETBUF_RESERVED_ROOM_SIZE, 0, 4); /* align 4 */
330     if (netbuf == HI_NULL) {
331         oam_error_log0(0, 0, "hmac_hcc_tx_event_buf_to_netbuf:: netbuf_alloc failed!");
332         return HI_FAIL;
333     }
334 
335     oal_netbuf_put(netbuf, payload_len);
336     if (memcpy_s(oal_netbuf_data(netbuf), payload_len, event_payload, payload_len) != EOK) {
337         oam_error_log0(0, 0, "hmac_hcc_tx_event_buf_to_netbuf:: memcpy_s failed!");
338         oal_netbuf_free(netbuf);
339         return HI_FAIL;
340     }
341 
342     return hcc_tx_netbuf_normal(event_mem, netbuf, 0);
343 }
344 
345 /* ****************************************************************************
346  功能描述  : HMAC通过HCC发送到DMAC的控制数据事件
347 
348  修改历史      :
349   1.日    期   : 2019-05-30
350     作    者   : HiSilicon
351     修改内容   : 新生成函数
352 **************************************************************************** */
hcc_hmac_tx_control_event(frw_event_mem_stru * event_mem,hi_u16 payload_len)353 hi_u32 hcc_hmac_tx_control_event(frw_event_mem_stru *event_mem, hi_u16 payload_len)
354 {
355     if (event_mem == HI_NULL) {
356         return HI_ERR_CODE_PTR_NULL;
357     }
358     return hmac_hcc_tx_event_buf_to_netbuf(event_mem, payload_len);
359 }
360 
361 /* hmac cb convert to dmac cb */
hcc_to_dmac_tx_ctr_convert(dmac_tx_ctl_stru * dst_cb,const hmac_tx_ctl_stru * src_cb)362 hi_void hcc_to_dmac_tx_ctr_convert(dmac_tx_ctl_stru *dst_cb, const hmac_tx_ctl_stru *src_cb)
363 {
364     dst_cb->alg_pktno           = (hi_u8)src_cb->alg_pktno;
365     dst_cb->en_event_type       = src_cb->event_type;
366     dst_cb->frame_header_length = src_cb->frame_header_length;
367     dst_cb->is_needretry        = src_cb->is_needretry;
368     dst_cb->is_vipframe         = src_cb->is_vipframe;
369     dst_cb->mpdu_num            = src_cb->mpdu_num;
370     dst_cb->netbuf_num          = src_cb->netbuf_num;
371     dst_cb->retried_num         = src_cb->retried_num;
372     dst_cb->tx_user_idx         = (hi_u8)src_cb->us_tx_user_idx;
373     dst_cb->tx_vap_index        = src_cb->tx_vap_index;
374     dst_cb->ismcast             = src_cb->ismcast;
375     dst_cb->is_eapol            = src_cb->is_eapol;
376     dst_cb->is_first_msdu       = src_cb->is_first_msdu;
377     dst_cb->is_get_from_ps_queue = src_cb->is_get_from_ps_queue;
378     dst_cb->is_probe_data       = src_cb->is_probe_data;
379     dst_cb->us_mpdu_bytes       = src_cb->us_mpdu_bytes;
380     dst_cb->mgmt_frame_id       = src_cb->mgmt_frame_id;
381     dst_cb->is_eapol_key_ptk    = src_cb->is_eapol_key_ptk;
382     dst_cb->need_rsp            = src_cb->need_rsp;
383     dst_cb->ac                  = src_cb->ac;
384     dst_cb->is_amsdu            = src_cb->is_amsdu;
385     dst_cb->ack_policy          = src_cb->ack_policy;
386     dst_cb->tid                 = (src_cb->tid & 0x0F);
387     dst_cb->high_prio_sch       = src_cb->high_prio_sch;
388     /* 解决STA user idx等于0的问题,此处用bit_reserved4作为user idx的备份 */
389     dst_cb->tx_user_idx_bak     = (hi_u8)src_cb->us_tx_user_idx;
390 }
391 
392 /* fill cb for hcc_hdr */
hcc_adjust_netbuf_data(oal_netbuf_stru * netbuf)393 hi_void hcc_adjust_netbuf_data(oal_netbuf_stru *netbuf)
394 {
395     dmac_tx_ctl_stru dmac_tx_ctrl;
396     hmac_tx_ctl_stru *hmac_tx_ctrl = (hmac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
397     hi_u8 *netbuf_hdr = (hi_u8 *)oal_netbuf_data(netbuf);
398 
399     if (memset_s(&dmac_tx_ctrl, sizeof(dmac_tx_ctl_stru), 0, sizeof(dmac_tx_ctl_stru)) != EOK) {
400         oam_error_log0(0, OAM_SF_ANY, "{hcc_adjust_netbuf_data:: memset_s is error.}");
401         return;
402     }
403 
404     hcc_to_dmac_tx_ctr_convert(&dmac_tx_ctrl, hmac_tx_ctrl);
405 
406     if (memcpy_s(netbuf_hdr, sizeof(dmac_tx_ctl_stru), (hi_u8 *)&dmac_tx_ctrl, sizeof(dmac_tx_ctl_stru)) != EOK) {
407         oam_error_log0(0, OAM_SF_ANY, "{hcc_adjust_netbuf_data:: memcpy_s is error.}");
408         return;
409     }
410 
411     if (memmove_s(netbuf_hdr + HI_MAX_DEV_CB_LEN, hmac_tx_ctrl->frame_header_length, hmac_tx_ctrl->frame_header,
412         hmac_tx_ctrl->frame_header_length) != EOK) {
413         oam_error_log0(0, OAM_SF_ANY, "{hcc_adjust_netbuf_data:: memmove_s is error.}");
414         return;
415     }
416 
417     if (hmac_tx_ctrl->mac_head_type == 0) {
418         oal_free(hmac_tx_ctrl->frame_header);
419     }
420 }
421 
422 /* calculate headroom add_length for hcc hdr */
hcc_check_headroom_add_length(const hmac_tx_ctl_stru * tx_ctrl)423 hi_u32 hcc_check_headroom_add_length(const hmac_tx_ctl_stru *tx_ctrl)
424 {
425     hi_u32 headroom_add;
426 
427     if (tx_ctrl->mac_head_type == 1) {
428         /* case 1: mac head is maintence in netbuff */
429         headroom_add = HI_MAX_DEV_CB_LEN + WLAN_MAX_MAC_HDR_LEN - tx_ctrl->frame_header_length;
430     } else {
431         /* case 2: mac head not maintence in netbuff */
432         headroom_add = HI_MAX_DEV_CB_LEN + WLAN_MAX_MAC_HDR_LEN;
433     }
434 
435     return headroom_add;
436 }
437 
hcc_host_tx_data_adapt(const frw_event_mem_stru * event_mem,oal_netbuf_stru * netbuf)438 hi_u32 hcc_host_tx_data_adapt(const frw_event_mem_stru *event_mem, oal_netbuf_stru *netbuf)
439 {
440     hmac_tx_ctl_stru                 *tx_ctrl = HI_NULL;
441     hi_u32                           headroom_add;
442     hi_s32                           err_code;
443     hi_u32                           netbuf_old_addr;
444     hi_u32                           netbuf_new_addr;
445     hi_u32                           addr_offset;
446 
447     tx_ctrl = (hmac_tx_ctl_stru *)oal_netbuf_cb(netbuf);
448     if (OAL_WARN_ON(tx_ctrl->use_4_addr)) {
449         oam_error_log0(0, OAM_SF_ANY, "{hcc_host_tx_data_adapt:: use 4 address.}");
450         return HI_FAIL;
451     }
452 
453     headroom_add = hcc_check_headroom_add_length(tx_ctrl);
454     if (headroom_add > oal_netbuf_headroom(netbuf)) {
455         err_code = oal_netbuf_expand_head(netbuf, (hi_s32)headroom_add - (hi_s32)oal_netbuf_headroom(netbuf),
456                                           0, GFP_ATOMIC);
457         if (OAL_WARN_ON(err_code != HI_SUCCESS)) {
458             oam_error_log0(0, OAM_SF_ANY, "{hcc_host_tx_data_adapt:: alloc headroom failed.}");
459             return HI_ERR_CODE_ALLOC_MEM_FAIL;
460         }
461 
462         if (tx_ctrl->mac_head_type == 1) {
463             tx_ctrl->frame_header = (mac_ieee80211_frame_stru *)oal_netbuf_data(netbuf);
464         }
465     }
466 
467     /* 修改netbuff的data指针和len */
468     oal_netbuf_push(netbuf, headroom_add);
469     hcc_adjust_netbuf_data(netbuf);
470 
471     /* 使netbuf四字节对齐 */
472     netbuf_old_addr = (uintptr_t)(oal_netbuf_data(netbuf) + HI_MAX_DEV_CB_LEN + WLAN_MAX_MAC_HDR_LEN);
473 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
474     netbuf_new_addr = oal_round_down(netbuf_old_addr, 32); /* boundary 32 */
475 #else
476     netbuf_new_addr = oal_round_down(netbuf_old_addr, 4);  /* boundary 4 */
477 #endif
478     addr_offset = netbuf_old_addr - netbuf_new_addr;
479 
480     /* 未对齐时在host侧做数据搬移,此处牺牲host,解放device */
481     if (addr_offset) {
482         if (addr_offset < oal_netbuf_headroom(netbuf)) {
483             if (memmove_s((hi_u8 *)oal_netbuf_data(netbuf) - addr_offset, oal_netbuf_len(netbuf),
484                 (hi_u8 *)oal_netbuf_data(netbuf), oal_netbuf_len(netbuf)) != EOK) {
485                 return HI_FAIL;
486             }
487             oal_netbuf_push(netbuf, addr_offset);
488             oal_netbuf_trim(netbuf, addr_offset);
489         }
490     }
491 
492     /* netbuf不管成功与否都由发送函数释放 */
493     return hcc_tx_netbuf_normal(event_mem, netbuf, HI_MAX_DEV_CB_LEN + WLAN_MAX_MAC_HDR_LEN);
494 }
495 
496 /* SDIO 传输帧类型适配预处理 */
hcc_host_tx_data_adapt_pre_do(frw_event_mem_stru * event_mem)497 hi_u32 hcc_host_tx_data_adapt_pre_do(frw_event_mem_stru *event_mem)
498 {
499     oal_netbuf_stru                 *netbuf_head = HI_NULL;
500     oal_netbuf_stru                 *current_netbuf = HI_NULL;
501     oal_netbuf_stru                 *netbuf_original = HI_NULL;
502     dmac_tx_event_stru              *event_payload = HI_NULL;
503     hi_u32                           err_code;
504 
505     /* 取业务事件信息 */
506     event_payload = (dmac_tx_event_stru *)frw_get_event_payload(event_mem);
507     netbuf_head = event_payload->netbuf;
508     netbuf_original = netbuf_head;
509 
510     while (netbuf_head != HI_NULL) {
511         /* 必须在netbuf抛出之前指向下一个netbuf,防止frw_event_dispatch_event 中重置 netbuf->next */
512         current_netbuf = netbuf_head;
513         netbuf_head = oal_netbuf_next(netbuf_head);
514 
515         err_code = hcc_host_tx_data_adapt(event_mem, current_netbuf);
516         if (err_code != HI_SUCCESS) {
517             oam_warning_log1(0, 0, "hcc_host_tx_data_adapt_pre_do:: tx_data_adapt failed[%d]", err_code);
518             if (netbuf_original == current_netbuf) {
519                 set_oal_netbuf_next(netbuf_original, HI_NULL);
520                 hmac_free_netbuf_list(netbuf_head);
521                 return err_code;
522             } else {
523                 hmac_free_netbuf_list(current_netbuf);
524                 return HI_SUCCESS;
525             }
526         }
527     }
528     return HI_SUCCESS;
529 }
530 
531 /* ****************************************************************************
532  功能描述  : HMAC通过HCC发送到DMAC的用户数据事件
533  修改历史      :
534   1.日    期   : 2019-05-30
535     作    者   : HiSilicon
536     修改内容   : 新生成函数
537 **************************************************************************** */
538 /* hcc_hmac_tx_data_event->hcc_to_dmac_data_event_dispatch->hcc_to_dmac_data_event_post
539    ->frw_event_dispatch_event->frw_event_post_event,452行进行了修改,lin_t e818告警屏蔽 */
hcc_hmac_tx_data_event(frw_event_mem_stru * event_mem,oal_netbuf_stru * netbuf,hi_bool mgmt)540 hi_u32 hcc_hmac_tx_data_event(frw_event_mem_stru *event_mem, oal_netbuf_stru *netbuf, hi_bool mgmt)
541 {
542     hi_unref_param(netbuf);
543     hi_unref_param(mgmt);
544     if (event_mem == HI_NULL) {
545         return HI_ERR_CODE_PTR_NULL;
546     }
547 
548     return hcc_host_tx_data_adapt_pre_do(event_mem);
549 }
550 
551 /* ****************************************************************************
552  功能描述  : HCC-HMAC初始化
553 
554  修改历史      :
555   1.日    期   : 2019-05-30
556     作    者   : HiSilicon
557     修改内容   : 新生成函数
558 **************************************************************************** */
hcc_hmac_init(struct BusDev * bus)559 hi_u32 hcc_hmac_init(struct BusDev *bus)
560 {
561 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_DMAC)
562     hcc_hmac_rx_event_handle handle;
563 
564     handle.control = hmac_from_dmac_rx_control_handle;
565     handle.data = hmac_from_dmac_rx_data_handle;
566 
567     return hcc_hmac_rx_event_register(&handle);
568 #else
569     hi_u32 err_code = hcc_host_init(bus);
570     if (err_code != HI_SUCCESS) {
571         oam_error_log1(0, 0, "hcc_host_init fail![%d]", err_code);
572         return err_code;
573     }
574 
575     hi_s32 adapt_err_code = hcc_hmac_adapt_init();
576     if (adapt_err_code != HI_SUCCESS) {
577         oam_error_log1(0, 0, "hcc_hmac_adapt_init fail![%d]", adapt_err_code);
578         return adapt_err_code;
579     }
580 
581     printk("hcc_hmac_init SUCCESSFULLY\r\n");
582     return HI_SUCCESS;
583 #endif
584 }
585 
586 /* ****************************************************************************
587  功能描述  : HCC-HMAC卸载
588 
589  修改历史      :
590   1.日    期   : 2019-05-30
591     作    者   : HiSilicon
592     修改内容   : 新生成函数
593 **************************************************************************** */
hcc_hmac_exit(hi_void)594 hi_void hcc_hmac_exit(hi_void)
595 {
596     hcc_hmac_rx_event_unregister();
597     hcc_host_exit(hcc_host_get_handler());
598 }
599 
600 #ifdef __cplusplus
601 #if __cplusplus
602 }
603 #endif
604 #endif
605