1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "oal_net.h"
23 #include "mac_data.h"
24 #include "securec.h"
25 #include "osal_mem.h"
26 #include "hdf_wlan_utils.h"
27
28 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
29 #include <net/genetlink.h>
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/init.h>
33 #endif
34
35 #ifdef __cplusplus
36 #if __cplusplus
37 extern "C" {
38 #endif
39 #endif
40
41 #ifdef _PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL
42 #define WLAN_DATA_VIP_QUEUE (WLAN_HI_QUEUE)
43 #endif
44
45 /* ****************************************************************************
46 2 全局变量定义
47 **************************************************************************** */
48 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
49 oal_net_stru g_init_net;
50 oal_sock_stru g_sock;
51 #endif
52 oal_wiphy_stru *g_wiphy = HI_NULL;
53
54 oal_net_device_stru *g_past_net_device[WLAN_VAP_NUM_PER_BOARD] = {HI_NULL};
55
56 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
57 struct dev_excp_globals g_dev_excp_handler_data;
58 #endif
59
60 /* ****************************************************************************
61 3 函数实现
62 **************************************************************************** */
63 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_netlink_kernel_create(hi_void)64 oal_sock_stru *oal_netlink_kernel_create(hi_void)
65 {
66 return &g_sock;
67 }
68
oal_netlink_kernel_release(hi_void)69 hi_void oal_netlink_kernel_release(hi_void)
70 {
71 return;
72 }
73 #endif /* #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) */
74
75 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
76 /*
77 * 功能描述 : 注册wiphy
78 */
oal_wiphy_register(oal_wiphy_stru * wiphy)79 hi_void oal_wiphy_register(oal_wiphy_stru *wiphy)
80 {
81 g_wiphy = wiphy;
82 }
83
84 #endif /* #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) */
85
oal_wiphy_get(hi_void)86 oal_wiphy_stru *oal_wiphy_get(hi_void)
87 {
88 return g_wiphy;
89 }
90
91 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
92 /* ****************************************************************************
93 功能描述 : receive netlink date from app
94 **************************************************************************** */
oal_dev_netlink_rev(oal_netbuf_stru * netbuf)95 hi_void oal_dev_netlink_rev(oal_netbuf_stru *netbuf)
96 {
97 oal_netbuf_stru *skb_info = HI_NULL;
98 oal_nlmsghdr_stru *nlh = HI_NULL;
99 struct dev_netlink_msg_hdr_stru msg_hdr = {0};
100 hi_u32 len;
101
102 if (netbuf == NULL) {
103 oal_io_print0("WIFI DFR:para fail\n");
104 return;
105 }
106
107 oal_io_print0("WIFI DFR:dev_kernel_netlink_recv.\n");
108
109 if (memset_s(g_dev_excp_handler_data.data, OAL_EXCP_DATA_BUF_LEN, 0, OAL_EXCP_DATA_BUF_LEN) != EOK) {
110 oal_io_print0("dev_netlink_rev::mem safe function err!}");
111 return;
112 }
113
114 skb_info = oal_netbuf_get(netbuf);
115 if (skb_info->len >= oal_nlmsg_space(0)) {
116 nlh = oal_nlmsg_hdr(skb_info);
117 /* 检测报文长度正确性 */
118 if (!oal_nlmsg_ok(nlh, skb_info->len)) {
119 oal_io_print2("[ERROR]invalid netlink buff data package data len = :%u,skb_buff data len = %u\n",
120 nlh->nlmsg_len, skb_info->len);
121 kfree_skb(skb_info);
122 return;
123 }
124 len = oal_nlmsg_payload(nlh, 0);
125 if (len < OAL_EXCP_DATA_BUF_LEN && len >= sizeof(msg_hdr)) {
126 if (memcpy_s(g_dev_excp_handler_data.data, len, oal_nlmsg_data(nlh), len) != EOK) {
127 oal_io_print0("dev_netlink_rev::mem safe function err!}");
128 kfree_skb(skb_info);
129 return;
130 }
131 } else {
132 oal_io_print2("[ERROR]invalid netlink buff len:%u,max len:%u\n", len, OAL_EXCP_DATA_BUF_LEN);
133 kfree_skb(skb_info);
134 return;
135 }
136 if (memcpy_s((hi_void *)&msg_hdr, sizeof(msg_hdr), g_dev_excp_handler_data.data, sizeof(msg_hdr)) != EOK) {
137 oal_io_print0("dev_netlink_rev::mem safe function err!}");
138 kfree_skb(skb_info);
139 return;
140 }
141 if (0 == msg_hdr.cmd) {
142 g_dev_excp_handler_data.usepid = nlh->nlmsg_pid; /* pid of sending process */
143 oal_io_print1("WIFI DFR:pid is [%d]\n", g_dev_excp_handler_data.usepid);
144 }
145 }
146 kfree_skb(skb_info);
147 return;
148 }
149
150 /* ****************************************************************************
151 功能描述 : create netlink for device exception
152 **************************************************************************** */
oal_dev_netlink_create(hi_void)153 hi_s32 oal_dev_netlink_create(hi_void)
154 {
155 g_dev_excp_handler_data.nlsk = oal_netlink_kernel_create(oal_dev_netlink_rev);
156 if (g_dev_excp_handler_data.nlsk == HI_NULL) {
157 oal_io_print0("WIFI DFR:fail to create netlink socket \n");
158 return HI_FAIL;
159 }
160
161 oal_io_print1("WIFI DFR:suceed to create netlink socket,%p \n", g_dev_excp_handler_data.nlsk);
162 return HI_SUCCESS;
163 }
164
165 /* ****************************************************************************
166 功能描述 : send netlink data
167 **************************************************************************** */
oal_dev_netlink_send(hi_u8 * data,hi_s32 data_len)168 hi_s32 oal_dev_netlink_send(hi_u8 *data, hi_s32 data_len)
169 {
170 oal_netbuf_stru *netbuf = HI_NULL;
171 oal_nlmsghdr_stru *nlh = HI_NULL;
172 hi_u32 ret;
173 hi_u32 len;
174
175 len = oal_nlmsg_space(data_len);
176 netbuf = alloc_skb(len, GFP_KERNEL);
177 if (netbuf == HI_NULL) {
178 oal_io_print1("WIFI DFR:dev error: allocate failed, len[%d].\n", len);
179 return HI_FAIL;
180 }
181 nlh = oal_nlmsg_put(netbuf, 0, 0, 0, data_len, 0);
182 oal_io_print1("WIFI DFR: data[%p].\n", (uintptr_t)data);
183
184 if (data != HI_NULL) {
185 if (memcpy_s(oal_nlmsg_data(nlh), data_len, data, data_len) != EOK) {
186 oal_io_print0("dev_netlink_send::mem safe function err!");
187 kfree_skb(netbuf);
188 return HI_FAIL;
189 }
190 }
191 oal_netlink_cb(netbuf).portid = 0; /* from kernel */
192
193 if (g_dev_excp_handler_data.nlsk == HI_NULL) {
194 oal_io_print0("WIFI DFR: NULL Pointer_sock.\n");
195 kfree_skb(netbuf);
196 return HI_FAIL;
197 }
198
199 ret = oal_netlink_unicast(g_dev_excp_handler_data.nlsk, netbuf, g_dev_excp_handler_data.usepid, MSG_DONTWAIT);
200 if (ret <= 0) {
201 oal_io_print1("WIFI DFR:send dev error netlink msg, ret = %d \n", ret);
202 }
203
204 return ret;
205 }
206
207 /* ****************************************************************************
208 功能描述 : init dev exception handler
209 **************************************************************************** */
oal_init_dev_excp_handler(hi_void)210 hi_s32 oal_init_dev_excp_handler(hi_void)
211 {
212 hi_s32 ret;
213
214 oal_io_print0("DFR: into init_exception_enable_handler\n");
215
216 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
217 memset_s((hi_u8 *)&g_dev_excp_handler_data, sizeof(g_dev_excp_handler_data), 0, sizeof(g_dev_excp_handler_data));
218
219 g_dev_excp_handler_data.data = (hi_u8 *)kzalloc(OAL_EXCP_DATA_BUF_LEN, GFP_KERNEL);
220 if (g_dev_excp_handler_data.data == HI_NULL) {
221 oal_io_print1("DFR: alloc dev_excp_handler_data.puc_data fail, len = %d.\n", OAL_EXCP_DATA_BUF_LEN);
222 g_dev_excp_handler_data.data = HI_NULL;
223 return HI_FAIL;
224 }
225 if (memset_s(g_dev_excp_handler_data.data, OAL_EXCP_DATA_BUF_LEN, 0, OAL_EXCP_DATA_BUF_LEN) != EOK) {
226 oal_io_print0("oal_init_dev_excp_handler: memset_s fail.");
227 }
228
229 ret = oal_dev_netlink_create();
230 if (ret < 0) {
231 kfree(g_dev_excp_handler_data.data);
232 oal_io_print0("init_dev_err_kernel init is ERR!\n");
233 return HI_FAIL;
234 }
235
236 oal_io_print0("DFR: init_exception_enable_handler init ok.\n");
237
238 return HI_SUCCESS;
239 }
240
241 /* ****************************************************************************
242 功能描述 : deinit dev exception handler
243 **************************************************************************** */
oal_deinit_dev_excp_handler(hi_void)244 hi_void oal_deinit_dev_excp_handler(hi_void)
245 {
246 if (g_dev_excp_handler_data.nlsk != HI_NULL) {
247 oal_netlink_kernel_release();
248 g_dev_excp_handler_data.usepid = 0;
249 }
250
251 if (g_dev_excp_handler_data.data != HI_NULL) {
252 kfree(g_dev_excp_handler_data.data);
253 }
254
255 oal_io_print0("DFR: deinit ok.\n");
256
257 return;
258 }
259 #endif
260
261 /* ****************************************************************************
262 功能描述 : 将信道转换成频率
263 输入参数 : hi_s32 l_channel :信道号
264 enum ieee80211_band band :频段
265 **************************************************************************** */
oal_ieee80211_channel_to_frequency(hi_s32 l_channel,wlan_channel_band_enum_uint8 band)266 hi_s32 oal_ieee80211_channel_to_frequency(hi_s32 l_channel, wlan_channel_band_enum_uint8 band)
267 {
268 /* see 802.11 17.3.8.3.2 and Annex J
269 * there are overlapping channel numbers in 5GHz and 2GHz bands */
270 if (l_channel <= 0) {
271 return 0; /* not supported */
272 }
273
274 switch (band) {
275 case IEEE80211_BAND_2GHZ: {
276 if (l_channel == 14) { /* 14:信道号 */
277 return 2484; /* 2484: 返回值 */
278 } else if (l_channel < 14) { /* 14:信道号 */
279 return 2407 + l_channel * 5; /* 2407: 返回值 5: 乘以5 */
280 }
281 break;
282 }
283
284 case IEEE80211_BAND_5GHZ: {
285 if (l_channel >= 182 && l_channel <= 196) { /* 182,196:信道号 */
286 return 4000 + l_channel * 5; /* 4000: 返回值 5: 乘以5 */
287 } else {
288 return 5000 + l_channel * 5; /* 5000: 返回值 5: 乘以5 */
289 }
290 }
291 default:
292 /* not supported other BAND */
293 return 0;
294 }
295
296 /* not supported */
297 return 0;
298 }
299
300 /* ****************************************************************************
301 功能描述 : 频率转信道
302 **************************************************************************** */
oal_ieee80211_frequency_to_channel(hi_s32 l_center_freq)303 hi_s32 oal_ieee80211_frequency_to_channel(hi_s32 l_center_freq)
304 {
305 hi_s32 l_channel;
306
307 /* see 802.11 17.3.8.3.2 and Annex J */
308 if (l_center_freq == 2484) { /* 2484:代表频率 */
309 l_channel = 14; /* 14: channel number */
310 } else if (l_center_freq < 2484) { /* 2484:代表频率 */
311 l_channel = (l_center_freq - 2407) / 5; /* 2407:代表频率 5: 除以5 */
312 } else if (l_center_freq >= 4910 && l_center_freq <= 4980) { /* 4910,4980:代表频率 */
313 l_channel = (l_center_freq - 4000) / 5; /* 4000:代表频率 5: 除以5 */
314 } else if (l_center_freq <= 45000) { /* DMG band lower limit */ /* 45000:代表频率 */
315 l_channel = (l_center_freq - 5000) / 5; /* 5000:代表频率 5: 除以5 */
316 } else if (l_center_freq >= 58320 && l_center_freq <= 64800) { /* 58320,64800:代表频率 */
317 l_channel = (l_center_freq - 56160) / 2160; /* 56160:代表频率 2160: 除以2160 */
318 } else {
319 l_channel = 0;
320 }
321 return l_channel;
322 }
323
324 /* ****************************************************************************
325 功能描述 : 获取信道
326 **************************************************************************** */
oal_ieee80211_get_channel(const oal_wiphy_stru * wiphy,hi_s32 freq)327 oal_ieee80211_channel_stru *oal_ieee80211_get_channel(const oal_wiphy_stru *wiphy, hi_s32 freq)
328 {
329 int i;
330 ieee80211_band_uint8 band;
331 struct ieee80211_supported_band *sband = HI_NULL;
332
333 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
334 sband = wiphy->bands[band];
335
336 if (sband == HI_NULL) {
337 continue;
338 }
339
340 for (i = 0; i < sband->n_channels; i++) {
341 if (sband->channels[i].center_freq == freq) {
342 return &sband->channels[i];
343 }
344 }
345 }
346
347 return HI_NULL;
348 }
349
350 /* ****************************************************************************
351 功能描述 : 根据名字寻找netdevice
352 **************************************************************************** */
oal_get_netdev_by_name(const hi_char * pc_name)353 oal_net_device_stru *oal_get_netdev_by_name(const hi_char *pc_name)
354 {
355 return NetDeviceGetInstByName(pc_name);
356 }
357
358 /* ****************************************************************************
359 功能描述 : 根据名字寻找netdevice,新增len用于后续校验扩展
360 **************************************************************************** */
oal_get_netdevice_by_name(const hi_char * pc_name,hi_u32 len)361 oal_net_device_stru *oal_get_netdevice_by_name(const hi_char *pc_name, hi_u32 len)
362 {
363 (void)len;
364 return NetDeviceGetInstByName(pc_name);
365 }
366
367
368 /* ****************************************************************************
369 功能描述 : 分配网络设备
370 输入参数 : ul_sizeof_priv: 私有结构空间长度
371 : puc_name 设备名称
372 : p_set_up:启动函数指针
373 **************************************************************************** */
374 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_net_alloc_netdev(const hi_char * puc_name,hi_u8 max_name_len)375 oal_net_device_stru *oal_net_alloc_netdev(const hi_char *puc_name, hi_u8 max_name_len)
376 {
377 (void)max_name_len;
378 oal_net_device_stru *netdev = NetDeviceInit(puc_name, strlen(puc_name), WIFI_LINK, LITE_OS);
379 if (netdev != NULL) {
380 netdev->funType.wlanType = PROTOCOL_80211_IFTYPE_STATION;
381 }
382 return netdev;
383 }
384 #endif
385
OalInitSpecialProcPriv(oal_net_device_stru * netdev)386 void OalInitSpecialProcPriv(oal_net_device_stru *netdev)
387 {
388 if (netdev == NULL) {
389 return;
390 }
391 netdev->specialProcPriv = NULL;
392 oal_hisi_eapol_stru *hisi_eapol = (oal_hisi_eapol_stru *)oal_memalloc(sizeof(oal_hisi_eapol_stru));
393 if (hisi_eapol == NULL) {
394 oam_error_log0(0, OAM_SF_ANY, "WalinitSpecialProcPriv:FAIL");
395 return;
396 }
397 if (memset_s(hisi_eapol, sizeof(oal_hisi_eapol_stru), 0, sizeof(oal_hisi_eapol_stru)) != EOK) {
398 return;
399 }
400 NetBufQueueInit(&hisi_eapol->eapolQueue);
401 netdev->specialProcPriv = hisi_eapol;
402 return;
403 }
404
OalFreeSpecialProcPriv(oal_net_device_stru * netdev)405 void OalFreeSpecialProcPriv(oal_net_device_stru *netdev)
406 {
407 if (netdev == NULL || netdev->specialProcPriv == NULL) {
408 return;
409 }
410 /* 删除netdev时 释放wpa未处理的所有eapol资源 */
411 oal_hisi_eapol_stru *hisi_eapol = (oal_hisi_eapol_stru *)netdev->specialProcPriv;
412 NetBufQueueClear(&hisi_eapol->eapolQueue);
413 oal_free(hisi_eapol);
414 netdev->specialProcPriv = NULL;
415 return;
416 }
417
418 /* ****************************************************************************
419 功能描述 : 分配网络设备,包含多个队列
420 输入参数 : ul_sizeof_priv: 私有结构空间长度
421 : puc_name 设备名称
422 : p_set_up:启动函数指针
423 **************************************************************************** */
oal_net_alloc_netdev_mqs(const hi_char * puc_name)424 oal_net_device_stru *oal_net_alloc_netdev_mqs(const hi_char *puc_name)
425 {
426 hi_u32 size;
427 oal_net_device_stru *netdev;
428
429 size = strlen((const hi_char *)puc_name) + 1; /* 包括'\0' */
430 netdev = (oal_net_device_stru *)oal_memalloc(sizeof(oal_net_device_stru));
431 if (netdev == HI_NULL) {
432 return HI_NULL;
433 }
434
435 /* 安全编程规则6.6例外(3) 从堆中分配内存后,赋予初值 */
436 memset_s(netdev, sizeof(oal_net_device_stru), 0, sizeof(oal_net_device_stru));
437
438 /* 将name保存到netdeivce */
439 if (memcpy_s(netdev->name, OAL_IF_NAME_SIZE, puc_name, size) != EOK) {
440 oal_free(netdev);
441 return HI_NULL;
442 }
443
444 return netdev;
445 }
446
oal_net_clear_netdev(oal_net_device_stru * netdev)447 hi_void oal_net_clear_netdev(oal_net_device_stru *netdev)
448 {
449 if (netdev == HI_NULL) {
450 return;
451 }
452 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
453 if (GET_NET_DEV_CFG80211_WIRELESS(netdev) != HI_NULL) {
454 if (GET_NET_DEV_CFG80211_WIRELESS(netdev)->preset_chandef.chan != HI_NULL) {
455 OsalMemFree(GET_NET_DEV_CFG80211_WIRELESS(netdev)->preset_chandef.chan);
456 GET_NET_DEV_CFG80211_WIRELESS(netdev)->preset_chandef.chan = HI_NULL;
457 }
458 oal_mem_free(netdev->ieee80211Ptr);
459 netdev->ieee80211Ptr = HI_NULL;
460 }
461 DestroyEapolData(netdev);
462 #endif
463 }
464
465
466 /* ****************************************************************************
467 功能描述 : 释放网络设备
468 输入参数 : ul_sizeof_priv: 私有结构空间长度
469 : puc_name 设备名称
470 : p_set_up:启动函数指针
471 **************************************************************************** */
oal_net_free_netdev(oal_net_device_stru * netdev)472 hi_void oal_net_free_netdev(oal_net_device_stru *netdev)
473 {
474 if (netdev == HI_NULL) {
475 return;
476 }
477 oal_net_clear_netdev(netdev);
478 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
479 if (netdev->classDriverName != NULL) {
480 HDF_LOGW("%s:platform NetDevice shell not released by chip driver", __func__);
481 (void)ReleasePlatformNetDevice(netdev);
482 } else {
483 NetDeviceDeInit(netdev);
484 }
485 #endif
486 }
487
488 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
489 /* ****************************************************************************
490 功能描述 : 注册网络设备
491 输入参数 : p_net_device: net device 结构体指针
492 返 回 值 : 错误码
493 **************************************************************************** */
oal_net_register_netdev(oal_net_device_stru * netdev,nl80211_iftype_uint8 type)494 hi_u32 oal_net_register_netdev(oal_net_device_stru *netdev, nl80211_iftype_uint8 type)
495 {
496 (void)type;
497 if (netdev == HI_NULL) {
498 oam_error_log0(0, 0, "hwal_lwip_register_netdev parameter NULL.");
499 return HI_ERR_CODE_PTR_NULL;
500 }
501
502 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
503 /* HCC层用 */
504 oal_netdevice_headroom(netdev) = 64; /* 固定设置为 64 */
505 oal_netdevice_tailroom(netdev) = 32; /* 固定设置为 32 */
506 #endif
507 oal_netdevice_specical_proc_priv(netdev) = HI_NULL;
508 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
509 /* 配置vap(Hisilicon0)不需要注册 */
510 if (strncmp(netdev->name, "Hisilicon", strlen("Hisilicon")) == 0) {
511 return HI_SUCCESS;
512 }
513
514 /* 初始化skb list */
515 OalInitSpecialProcPriv(netdev);
516 #endif
517 NetDeviceAdd(netdev);
518 return HI_SUCCESS;
519 }
520
521 /* ****************************************************************************
522 函 数 名 : oal_net_unregister_netdev
523 功能描述 : 去注册网络设备
524 输入参数 : p_net_device: net device 结构体指针
525 **************************************************************************** */
oal_net_unregister_netdev(oal_net_device_stru * netdev)526 hi_void oal_net_unregister_netdev(oal_net_device_stru *netdev)
527 {
528 if (NetDeviceDelete(netdev) != 0) {
529 oal_io_print0("NetDeviceDelete FAIL !\n");
530 }
531 return;
532 }
533 #endif
534
535 /* ****************************************************************************
536 功能描述 : 生成ipv6的magic
537 **************************************************************************** */
oal_csum_ipv6_magic(hi_u32 len,hi_u8 * buffer)538 hi_u16 oal_csum_ipv6_magic(hi_u32 len, hi_u8 *buffer)
539 {
540 hi_u32 cksum = 0;
541 hi_u16* p = (hi_u16*)buffer;
542 hi_u32 size = (len >> 1) + (len & 0x1);
543
544 while (size > 0) {
545 cksum += *p;
546 p++;
547 size--;
548 }
549
550 cksum = (cksum >> 16) + (cksum & 0xffff); /* 16:右移16位 */
551 cksum = (cksum >> 16) + (cksum & 0xffff); /* 16:右移16位 */
552
553 return (hi_u16)(~cksum);
554 }
555
556 /* ****************************************************************************
557 功能描述 : 保证skb->data包含ul_len指指示的空间,如果没有,则从 skb_shinfo(skb)->frags[]中
558 拷贝一份数据。
559 **************************************************************************** */
oal_eth_header(oal_netbuf_stru * netbuf,oal_net_device_stru * netdev,oal_eth_header_info_stru * eth_header_info)560 hi_s32 oal_eth_header(oal_netbuf_stru *netbuf, oal_net_device_stru *netdev, oal_eth_header_info_stru *eth_header_info)
561 {
562 oal_ether_header_stru *eth = (oal_ether_header_stru *)oal_netbuf_push(netbuf, 14); /* 14: 空间长度 */
563 if (eth == HI_NULL) {
564 oal_io_print0("oal_eth_header into eth is null !\n");
565 return HI_FAIL;
566 }
567
568 if (eth_header_info->type != 0x0001 && eth_header_info->type != 0x0004) {
569 eth->us_ether_type = (hi_u16)oal_host2net_short(eth_header_info->type);
570 } else {
571 eth->us_ether_type = (hi_u16)oal_host2net_short(eth_header_info->len);
572 }
573
574 if ((eth_header_info->saddr) == HI_NULL) {
575 eth_header_info->saddr = netdev->macAddr;
576 }
577
578 if (memcpy_s(eth->auc_ether_shost, ETHER_ADDR_LEN, eth_header_info->saddr, ETHER_ADDR_LEN) != EOK) {
579 return HI_FAIL;
580 }
581
582 if (eth_header_info->daddr != HI_NULL) {
583 if (memcpy_s(eth->auc_ether_dhost, ETHER_ADDR_LEN, eth_header_info->daddr, ETHER_ADDR_LEN) != EOK) {
584 return HI_FAIL;
585 }
586 return 14; /* 14: 返回值 */
587 }
588
589 return HI_FAIL;
590 }
591
592 #ifdef _PRE_DEBUG_MODE
593 /* ****************************************************************************
594 功能描述 : 创建一个arp包
595 **************************************************************************** */
596 /* 规则5.1 避免函数过长,函数不超过50行(非空非注释),申请例外: 组帧函数,且函数无调度,申请屏蔽 */
oal_arp_create(const oal_arp_create_info_stru * p_arp_create_info,oal_net_device_stru * netdev)597 oal_netbuf_stru *oal_arp_create(const oal_arp_create_info_stru *p_arp_create_info, oal_net_device_stru *netdev)
598 {
599 hi_s8 ac_bcast[6] = {0x33, 0x33, 0x33, 0x33, 0x33, 0x33}; /* 6: 元素个数 */
600 oal_eth_header_info_stru eth_header_info;
601
602 /* Allocate a buffer */
603 oal_netbuf_stru *netbuf = oal_netbuf_alloc(oal_arp_hdr_len(netdev) + oal_ll_allocated_space(netdev), 0);
604 if (netbuf == HI_NULL) {
605 return HI_NULL;
606 }
607
608 skb_reserve(netbuf, oal_ll_allocated_space(netdev)); /* reserve 16 */
609
610 oal_eth_arphdr_stru *arp = (oal_eth_arphdr_stru *)oal_netbuf_put(netbuf, (hi_u32)oal_arp_hdr_len(netdev));
611
612 netbuf->dev = netdev;
613 netbuf->protocol = oal_host2net_short(ETHER_TYPE_ARP);
614
615 if (((p_arp_create_info->puc_src_hw != HI_NULL) &&
616 (memcpy_s(p_arp_create_info->puc_src_hw, ETHER_ADDR_LEN, netdev->dev_addr, ETHER_ADDR_LEN) != EOK)) ||
617 ((p_arp_create_info->puc_dest_hw != HI_NULL) &&
618 (memcpy_s(p_arp_create_info->puc_dest_hw, ETHER_ADDR_LEN, ac_bcast, ETHER_ADDR_LEN) != EOK))) {
619 goto NETBUF_FREE;
620 }
621
622 /* Fill the device header for the ARP frame */
623 eth_header_info.type = p_arp_create_info->l_ptype;
624 eth_header_info.daddr = p_arp_create_info->puc_dest_hw;
625 eth_header_info.saddr = p_arp_create_info->puc_src_hw;
626 eth_header_info.len = netbuf->len;
627 if (oal_eth_header(netbuf, netdev, ð_header_info) < 0) {
628 goto NETBUF_FREE;
629 }
630
631 arp->us_ar_hrd = (hi_u16)oal_host2net_short(netdev->type);
632 arp->us_ar_pro = (hi_u16)oal_host2net_short(ETHER_TYPE_IP);
633
634 arp->ar_hln = 6; /* 6: length of hardware address */
635 arp->ar_pln = 4; /* 4: length of protocol address */
636 arp->us_ar_op = (hi_u16)oal_host2net_short(p_arp_create_info->l_type);
637
638 hi_u8 *arp_ptr = (hi_u8 *)arp + 8; /* 8: 偏移8 */
639 if ((p_arp_create_info->puc_src_hw != HI_NULL) &&
640 (memcpy_s(arp_ptr, ETHER_ADDR_LEN, p_arp_create_info->puc_src_hw, ETHER_ADDR_LEN) != EOK)) {
641 goto NETBUF_FREE;
642 }
643
644 arp_ptr += 6; /* 6: 偏移6 */
645 if (memcpy_s(arp_ptr, ETH_IP_ADDR_LEN, &(p_arp_create_info->src_ip), ETH_IP_ADDR_LEN) != EOK) {
646 goto NETBUF_FREE;
647 }
648
649 arp_ptr += 4; /* 4: 偏移4 */
650 if (p_arp_create_info->puc_target_hw != HI_NULL) {
651 if (memcpy_s(arp_ptr, ETHER_ADDR_LEN, p_arp_create_info->puc_target_hw, ETHER_ADDR_LEN) != EOK) {
652 oal_netbuf_free(netbuf);
653 return HI_NULL;
654 }
655 } else {
656 if (memset_s(arp_ptr, ETHER_ADDR_LEN, 0, ETHER_ADDR_LEN) != EOK) {
657 oal_netbuf_free(netbuf);
658 return HI_NULL;
659 }
660 }
661
662 arp_ptr += 6; /* 6: 偏移6 */
663 if (memcpy_s(arp_ptr, ETH_IP_ADDR_LEN, &(p_arp_create_info->dest_ip), ETH_IP_ADDR_LEN) != EOK) {
664 goto NETBUF_FREE;
665 }
666
667 return netbuf;
668
669 NETBUF_FREE:
670 oal_netbuf_free(netbuf);
671 return HI_NULL;
672 }
673 #endif
674
675 /* ****************************************************************************
676 功能描述 :校验设备类型并尝试获取设备名
677 **************************************************************************** */
oal_net_check_and_get_devname(nl80211_iftype_uint8 type,char * dev_name,hi_u32 * len)678 hi_u32 oal_net_check_and_get_devname(nl80211_iftype_uint8 type, char *dev_name, hi_u32 *len)
679 {
680 hi_s32 netdev_count = 0;
681
682 /* 获取已注册netdev信息 */
683 netdev_count = NetDevGetRegisterCount();
684 /* 最多只支持3个netdev共存 */
685 if (netdev_count > 3) { /* 3: 最多只支持4个netdev共存 */
686 oal_io_print0("{oal_net_check_and_get_devname::already have 4 vaps. Could not start a new one!}\r\n");
687 return HI_FAIL;
688 }
689
690 /* strncpy源内存全部是静态字符串常量,可以不用安全函数 */
691 switch (type) {
692 case NL80211_IFTYPE_STATION:
693 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
694 strncpy_s(dev_name, *len, "wlan0", strlen("wlan0") + 1);
695 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
696 strncpy_s(dev_name, *len, "wlan%d", strlen("wlan%d") + 1);
697 #endif
698 break;
699 case NL80211_IFTYPE_AP:
700 strncpy_s(dev_name, *len, "wlan0", strlen("wlan0") + 1);
701 break;
702 case NL80211_IFTYPE_P2P_DEVICE:
703 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
704 strncpy_s(dev_name, *len, "p2p", strlen("p2p") + 1);
705 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
706 strncpy_s(dev_name, *len, "p2p%d", strlen("p2p%d") + 1);
707 #endif
708 break;
709 case NL80211_IFTYPE_P2P_CLIENT:
710 /* fall-through */
711 case NL80211_IFTYPE_P2P_GO:
712 strncpy_s(dev_name, *len, "p2p-p2p0-", strlen("p2p-p2p0-") + 1);
713 break;
714 case NL80211_IFTYPE_MESH_POINT:
715 strncpy_s(dev_name, *len, "mesh", strlen("mesh") + 1);
716 break;
717 default:
718 oal_io_print0("{oal_net_check_and_get_devname::not supported dev type!}\r\n");
719 return HI_FAIL;
720 }
721 *len = strlen(dev_name);
722 return HI_SUCCESS;
723 }
724
725 #ifdef __cplusplus
726 #if __cplusplus
727 }
728 #endif
729 #endif
730