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 *)(¶));
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(¶m, 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, ¶m);
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