• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 /* ****************************************************************************
20   1 头文件包含
21 **************************************************************************** */
22 #include "oal_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, &eth_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