• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: Header file of WLAN product specification macro definition.
15  * Create: 2020-10-18
16  */
17 
18 #ifndef __OAL_UTIL_HCM_H__
19 #define __OAL_UTIL_HCM_H__
20 
21 #include "securec.h"
22 #include "osal_types.h"
23 #include "osal_adapt.h"
24 #include "oal_types.h"
25 #include "wlan_util_common.h"
26 #if defined(_PRE_OS_VERSION_LINUX) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
27 #include <linux/etherdevice.h>
28 #endif
29 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
30 #include <sys/time.h>
31 #include <stdio.h>
32 #include <ctype.h>
33 #endif
34 
35 #ifdef __cplusplus
36 #if __cplusplus
37 extern "C" {
38 #endif
39 #endif
40 
41 #ifdef CONTROLLER_CUSTOMIZATION
42 #define wifi_printf_always(fmt, ...) \
43     printk(KERN_EMERG KBUILD_MODNAME "[%s:%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
44 #else
45 #define wifi_printf_always(fmt, arg...) osal_printk(fmt, ##arg)
46 #endif
47 
48 #ifdef _PRE_WIFI_PRINTK
49 #ifdef CONTROLLER_CUSTOMIZATION
50 #define wifi_printf(fmt, ...) printk(KERN_EMERG KBUILD_MODNAME "[%s:%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
51 #else
52 #define wifi_printf(fmt, arg...) osal_printk(fmt, ##arg)
53 #endif
54 #else
55 #define wifi_printf(fmt, arg...)
56 #endif
57 
58 /*****************************************************************************
59   2 宏定义
60 *****************************************************************************/
61 #define OAL_DECLARE_PACKED    __attribute__((__packed__))
62 #define WIFI_ROM_TEXT           __attribute__ ((section(".wifi.rom.text")))   /* ROM代码段 */
63 #define WIFI_ROM_RODATA         __attribute__ ((section(".wifi.rom.rodata"))) /* ROM const全局变量段 可与text段复用 */
64 #define WIFI_ROM_DATA           __attribute__ ((section(".wifi.rom.data")))   /* ROM 初值非0全局变量段 不能与bss混用 */
65 #define WIFI_ROM_BSS            __attribute__ ((section(".wifi.rom.bss")))    /* ROM 初值0或未赋值全局变量段
66                                                                                  可以data段混用 只会影响RAM段大小 */
67 #if defined(_PRE_WLAN_FEATURE_WS63)
68 #define WIFI_TCM_TEXT __attribute__((section(".wifi.tcm.text")))
69 #define WIFI_TCM_RODATA __attribute__((section(".wifi.tcm.rodata")))
70 #define WIFI_HMAC_TCM_TEXT
71 #define WIFI_HMAC_TCM_RODATA
72 #elif defined(_PRE_WLAN_FEATURE_WS53)
73 #define WIFI_TCM_TEXT
74 #define WIFI_TCM_RODATA __attribute__((section(".wifi.tcm.rodata")))
75 #define WIFI_HMAC_TCM_TEXT __attribute__((section(".wifi.tcm.text")))
76 #define WIFI_HMAC_TCM_RODATA
77 #else
78 #define WIFI_TCM_TEXT
79 #define WIFI_TCM_RODATA
80 #define WIFI_HMAC_TCM_TEXT
81 #define WIFI_HMAC_TCM_RODATA
82 #endif
83 
84 /* 拼接为16 bit或者 32bit */
85 #define OAL_MAKE_WORD16(lsb, msb) ((((osal_u16)(msb) << 8) & 0xFF00) | (lsb))
86 #define OAL_MAKE_WORD32(lsw, msw) ((((osal_u32)(msw) << 16) & 0xFFFF0000) | (lsw))
87 
88 /* 比较宏 */
89 #define OAL_MIN(_A, _B) (((_A) < (_B)) ? (_A) : (_B))
90 
91 /* 比较宏 */
92 #define OAL_MAX(_A, _B) (((_A) > (_B)) ? (_A) : (_B))
93 #define OAL_SUB(_A, _B) (((_A) > (_B)) ? ((_A) - (_B)) : (0))
94 #define OAL_ABSOLUTE_SUB(_A, _B) (((_A) > (_B)) ? ((_A) - (_B)) : ((_B) - (_A)))
95 
96 #define OAL_ARRAY_SIZE(_ast_array)                  (sizeof(_ast_array) / sizeof((_ast_array)[0]))
97 
98 /* 修改_PRE_BIG_CPU_ENDIAN保持HMAC&DMAC统一 */
99 /* BIG_ENDIAN */
100 #if defined(_PRE_BIG_CPU_ENDIAN) && defined(_PRE_CPU_ENDIAN) && (_PRE_BIG_CPU_ENDIAN == _PRE_CPU_ENDIAN)
101 #define oal_ntoh_16(_val)                  (_val)
102 #define oal_ntoh_32(_val)                  (_val)
103 #define oal_hton_16(_val)                  (_val)
104 #define oal_hton_32(_val)                  (_val)
105 #define OAL_NTOH_16(_val)                  (_val)
106 #define OAL_NTOH_32(_val)                  (_val)
107 #define OAL_HTON_16(_val)                  (_val)
108 #define OAL_HTON_32(_val)                  (_val)
109 
110 #else     /* LITTLE_ENDIAN */
111 #define oal_ntoh_16(_val)                  oal_swap_byteorder_16(_val)
112 #define oal_ntoh_32(_val)                  oal_swap_byteorder_32(_val)
113 #define oal_hton_16(_val)                  oal_swap_byteorder_16(_val)
114 #define oal_hton_32(_val)                  oal_swap_byteorder_32(_val)
115 #define OAL_NTOH_16(_val)                  oal_swap_byteorder_16(_val)
116 #define OAL_NTOH_32(_val)                  oal_swap_byteorder_32(_val)
117 #define OAL_HTON_16(_val)                  oal_swap_byteorder_16(_val)
118 #define OAL_HTON_32(_val)                  oal_swap_byteorder_32(_val)
119 #endif
120 
121 /* 获取大小 */
122 #define OAL_SIZEOF                                 sizeof
123 
124 #define HCC_DATA_LEN_ALIGN 32
125 /* 获取数组大小 */
126 #define osal_array_size(_array)                     (sizeof(_array) / sizeof((_array)[0]))
127 
128 /* 从某个设备读取某个寄存器地址的32-bit寄存器的值。 */
129 #define OAL_REG_READ32(_addr)    \
130         *((OAL_VOLATILE osal_u32 *)(_addr))
131 
132 #define OAL_REG_READ16(_addr)    \
133     *((OAL_VOLATILE osal_u16 *)(_addr))
134 
135 /* 往某个设备某个32-bit寄存器地址写入某个值 */
136 #define OAL_REG_WRITE32(_addr, _val)    \
137     (*((OAL_VOLATILE osal_u32 *)(_addr)) = (_val))
138 #define OAL_REG_WRITE16(_addr, _val)    \
139     (*((OAL_VOLATILE osal_u16 *)(_addr)) = (_val))
140 
141 #ifndef round_mask
142 #define round_mask(x, y) ((__typeof__(x))((y) - 1))
143 #endif
144 
145 #ifndef round_up
146 #define round_up(x, y) ((((x) - 1) | round_mask(x, y)) + 1)
147 #endif
148 #define OAL_ROUND_UP        round_up
149 
150 #ifndef round_down
151 #define round_down(x, y) ((x) & ~round_mask(x, y))
152 #endif
153 #define OAL_ROUND_DOWN      round_down
154 
155 #define OAL_IPV4_ADDR_LEN 6
156 #define OAL_IPV6_ADDR_LEN 16
157 
158 /* 获取CORE ID */
159 #define OAL_GET_CORE_ID()    (0)
160 
161 typedef osal_ulong    oal_bitops;
162 
163 #define OAL_OFFSET_OF           offsetof
164 
165 typedef ssize_t     oal_ssize_t;    /* hi1102-cb for sys interface  51/02 */
166 typedef size_t      oal_size_t;
167 
168 #define OAL_STRLEN                                  osal_strlen
169 #define OAL_MEMCMP                                  osal_memcmp
170 #define OAL_STRSTR                                  osal_strstr
171 
172 #define todigit(c) ((c) - '0')
173 #define tochar(n)  ((n) + '0')
174 #define oal_tolower(x) ((osal_u8)(x) | 0x20)
175 #define oal_isdigit(c) ('0' <= (c) && (c) <= '9')
176 #define oal_isxdigit(c) (('0' <= (c) && (c) <= '9') || ('a' <= (c) && (c) <= 'f') || ('A' <= (c) && (c) <= 'F'))
177 
178 #define oal_is_null_ptr4(ptr1, ptr2, ptr3, ptr4) \
179     ((NULL == (ptr1)) || (NULL == (ptr2)) || (NULL == (ptr3)) || (NULL == (ptr4)))
180 
181 static inline osal_slong oal_strtol(OAL_CONST osal_s8 *pc_nptr, osal_s8 **ppc_endptr, osal_s32 l_base);
182 /*****************************************************************************
183  函 数 名  : oal_bit_find_first_zero_one_byte
184  功能描述  : 找到1字节右数第一个是0的位数
185 *****************************************************************************/
oal_bit_find_first_zero_one_byte(osal_u8 byte)186 static inline osal_u8 oal_bit_find_first_zero_one_byte(osal_u8 byte)
187 {
188     osal_u8 zero_bit = 0;
189 
190     byte = ~byte;
191     byte = byte & (-byte);
192 
193     while (byte != 1) {
194         zero_bit++;
195         byte = (byte >> 1);
196 
197         if (zero_bit > 7) {  /* 7表示超过字节最大bit数。退出循环 */
198             return zero_bit;
199         }
200     }
201 
202     return zero_bit;
203 }
204 
205 /*****************************************************************************
206  函 数 名  : oal_set_mac_addr_zero
207  功能描述  : mac地址置零
208 *****************************************************************************/
oal_set_mac_addr_zero(osal_u8 * mac_addr)209 static inline osal_void oal_set_mac_addr_zero(osal_u8 *mac_addr)
210 {
211     const osal_u32 mac_len = 6; /* 6字节mac地址长度 */
212     (osal_void)memset_s(mac_addr, mac_len, 0, mac_len);
213 }
214 
215 /*****************************************************************************
216  函 数 名  : osal_strtohex
217  功能描述  : 将一个字符转化成16进制数
218 *****************************************************************************/
oal_strtohex(const osal_s8 * string)219 static inline osal_u8 oal_strtohex(const osal_s8 *string)
220 {
221     osal_u8 ret = 0;
222 
223     if (*string >= '0' && *string <= '9') {
224         ret = (osal_u8)(*string - '0');
225     } else if (*string >= 'A' && *string <= 'F') {
226         ret = (osal_u8)(*string - 'A' + 10); /* 10进制转换 */
227     } else if (*string >= 'a' && *string <= 'f') {
228         ret = (osal_u8)(*string - 'a' + 10); /* 10进制转换 */
229     } else {
230         ret = 0xff;
231     }
232 
233     return ret;
234 }
235 
236 /* ****************************************************************************
237  函 数 名  : oal_strtoaddr
238  功能描述  : 字符串转MAC地址
239 **************************************************************************** */
oal_strtoaddr(const osal_char * pc_param,osal_u8 * mac_addr)240 static inline osal_void oal_strtoaddr(const osal_char *pc_param, osal_u8 *mac_addr)
241 {
242     osal_u8 char_index;
243 
244     /* 获取mac地址,16进制转换 */
245     for (char_index = 0; char_index < 12; char_index++) { /* 12 mac地址字符长度 */
246         while ((*pc_param == ':') || (*pc_param == '-')) {
247             pc_param++;
248 
249             continue;
250         }
251 
252         /* 处理2字符, 16表字节内高4bit */
253         mac_addr[char_index / 2] = (osal_u8)(mac_addr[char_index / 2] * 16 * (char_index % 2) +
254             oal_strtohex((const osal_s8 *)pc_param));
255         pc_param++;
256     }
257 }
258 
259 /*****************************************************************************
260  函 数 名  : oal_strtoipv6
261  功能描述  : 字符串转ipv6地址
262  输入参数  : pc_param: ipv6地址字符串, 格式 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
263  输出参数  : mac_addr: 转换成16进制后的ipv6地址
264 *****************************************************************************/
oal_strtoipv6(const osal_s8 * pc_param,osal_u8 * ipv6_addr)265 static inline osal_void oal_strtoipv6(const osal_s8 *pc_param, osal_u8 *ipv6_addr)
266 {
267     osal_u8   char_index;
268 
269     /* 获取ipv6地址,16进制转换,每个byte对应2位十六进制数 */
270     for (char_index = 0; char_index < OAL_IPV6_ADDR_LEN * 2; char_index++) {
271         if ((*pc_param == ':')) {
272             pc_param++;
273             if (char_index != 0) {
274                 char_index--;
275             }
276             continue;
277         }
278         /* 将ipv6字符串转换为16进制数组,4 2分别用作位移数及求余 */
279         ipv6_addr[char_index >> 1] = (osal_u8)(((ipv6_addr[char_index>>1]) << 4) * (char_index % 2) +
280             oal_strtohex(pc_param));
281         pc_param++;
282     }
283 }
284 
oal_strtoipv4(const osal_s8 * ip_str,osal_u8 * ipv4_addr)285 static inline osal_void oal_strtoipv4(const osal_s8 *ip_str, osal_u8 *ipv4_addr)
286 {
287     osal_char *pc_token;
288     osal_char *pc_ctx;
289     osal_char *pc_sep = ".";
290     osal_s8 param_num = 3; /* IPV4地址有4段, 数组idx为0/1/2/3 */
291 
292     pc_token = strtok_s((osal_char *)ip_str, (OAL_CONST osal_char *)pc_sep, &pc_ctx);
293     while (pc_token) {
294          /* 10 base权值 */
295         *(ipv4_addr + param_num) = (osal_u8)oal_strtol((OAL_CONST osal_s8 *)pc_token, OAL_PTR_NULL, 10);
296         pc_token = strtok_s(OAL_PTR_NULL, (OAL_CONST osal_char *)pc_sep, &pc_ctx);
297         param_num--;
298     }
299 }
300 
301 /*****************************************************************************
302  函 数 名  : oal_gen_random
303  功能描述  : 产生随机数
304  输入参数  : val:随机种子   rst_flag:0:不更新随机种子,非0:更新随机种子
305 *****************************************************************************/
oal_gen_random(osal_u32 val,osal_u8 rst_flag)306 static inline osal_u8 oal_gen_random(osal_u32 val, osal_u8 rst_flag)
307 {
308     OAL_STATIC osal_u32 rand = 0;
309     if (rst_flag != 0) {
310         rand = val;
311     }
312     rand = rand * 1664525L + 1013904223L;
313     /* 32位 - 8位 = 24位,右移24位得到u8 */
314     return (osal_u8) (rand >> 24);
315 }
316 
317 /*****************************************************************************
318  函 数 名  : oal_strim
319  功能描述  : 去掉字符串开始与结尾的空格
320  输入参数  : 无
321  输出参数  : 无
322 *****************************************************************************/
oal_strim(osal_s8 * s)323 static inline osal_s8 *oal_strim(osal_s8 *s)
324 {
325     osal_s8 *end;
326 
327     while (*s == ' ') {
328         ++s;
329     }
330 
331     end = s;
332     while ((*end != ' ') && (*end != '\0')) {
333         ++end;
334     }
335 
336     *end = '\0';
337 
338     return s;
339 }
340 
oal_random_ether_addr(osal_u8 * addr,osal_u8 len)341 static inline void oal_random_ether_addr(osal_u8 *addr, osal_u8 len)
342 {
343 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
344     struct timeval tv1;
345     struct timeval tv2;
346     unref_param(len);
347 
348     /* 获取随机种子 */
349     gettimeofday(&tv1, NULL);
350 
351     /* 防止秒级种子为0 */
352     tv1.tv_sec += 2; /* 加2 */
353 
354     tv2.tv_sec = (osal_slong)((td_u32)((td_u64)tv1.tv_sec * tv1.tv_sec) * (td_u64)tv1.tv_usec);
355     tv2.tv_usec = (osal_slong)((td_u32)((td_u64)tv1.tv_sec * tv1.tv_usec) * (td_u64)tv1.tv_usec);
356 
357     /* 生成随机的mac地址 */
358     addr[0] = ((td_u32)tv2.tv_sec & 0xff) & 0xfe;
359     addr[1] = (osal_u8)((td_u32)tv2.tv_usec & 0xff);
360     addr[2] = (osal_u8)(((td_u32)tv2.tv_sec & 0xff0) >> 4);   /* mac_addr[2]右移4 bit */
361     addr[3] = (osal_u8)(((td_u32)tv2.tv_usec & 0xff0) >> 4);  /* mac_addr[3]右移4 bit */
362     addr[4] = (osal_u8)(((td_u32)tv2.tv_sec & 0xff00) >> 8);  /* mac_addr[4]右移8 bit */
363     addr[5] = (osal_u8)(((td_u32)tv2.tv_usec & 0xff00) >> 8); /* mac_addr[5]右移8 bit */
364 #endif
365 #if defined(_PRE_OS_VERSION_LINUX) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
366     unref_param(len);
367     random_ether_addr(addr);
368 #endif
369 }
370 
371 /*****************************************************************************
372  函 数 名  : oal_byteorder_host_to_net_uint16
373  功能描述  : 将16位本地字节序转换为网络字节序
374  输入参数  : byte: 需要字节序转换的变量
375  输出参数  : 无
376  返 回 值  : 转换好的变量
377 *****************************************************************************/
oal_byteorder_net_to_host_uint16(osal_u16 byte)378 static inline osal_u16 oal_byteorder_net_to_host_uint16(osal_u16 byte)
379 {
380     return oal_ntoh_16(byte);
381 }
382 
383 /*****************************************************************************
384  函 数 名  : oal_byteorder_host_to_net_uint16
385  功能描述  : 将32位本地字节序转换为网络字节序
386  输入参数  : byte: 需要字节序转换的变量
387  输出参数  : 无
388  返 回 值  : 转换好的变量
389 *****************************************************************************/
oal_byteorder_host_to_net_uint32(osal_u32 byte)390 static inline osal_u32 oal_byteorder_host_to_net_uint32(osal_u32 byte)
391 {
392     return oal_hton_32(byte);
393 }
394 
395 /*****************************************************************************
396  函 数 名  : oal_atoi
397  功能描述  : 字符串类型转换成整形
398  输入参数  : c_string: 字符串地址
399 *****************************************************************************/
oal_atoi(const osal_s8 * string)400 static inline osal_s32 oal_atoi(const osal_s8 *string)
401 {
402     osal_s32 ret = 0;
403     osal_s32 flag = 0;
404 
405     for (; ; string++) {
406         switch (*string) {
407             case '0'...'9':
408                 /* 乘10进位 */
409                 ret = 10 * ret + (*string - '0');
410                 break;
411             case '-':
412                 flag = 1;
413                 break;
414 
415             case ' ':
416                 continue;
417 
418             default:
419                 return ((flag == 0) ? ret : (-ret));
420         }
421     }
422 }
423 
simple_guess_base(const char * cp)424 static inline unsigned int simple_guess_base(const char *cp)
425 {
426     if (cp[0] == '0') {
427         if (oal_tolower(cp[1]) == 'x' && oal_isxdigit(cp[2])) {
428             /* 对应16进制 */
429             return 16;
430         } else {
431             /* 对应8进制 */
432             return 8;
433         }
434     } else {
435         /* 对应10进制 */
436         return 10;
437     }
438 }
439 
oal_simple_strtoull(const osal_s8 * cp,osal_s8 ** endp,unsigned int base)440 static inline unsigned long long oal_simple_strtoull(const osal_s8 *cp, osal_s8 **endp, unsigned int base)
441 {
442     unsigned long long result = 0;
443 
444     if (base == 0) {
445         base = simple_guess_base((const char *)cp);
446     }
447     /* 对应16进制 */
448     if (base == 16 && cp[0] == '0' && oal_tolower(cp[1]) == 'x') {
449         /* 指针后移2位 */
450         cp += 2;
451     }
452     while (oal_isxdigit(*cp)) {
453         unsigned int value;
454         /* 16进制下,a对应10 */
455         value = oal_isdigit(*cp) ? *cp - '0' : oal_tolower(*cp) - 'a' + 10;
456         if (value >= base) {
457             break;
458         }
459         result = result * base + value;
460         cp++;
461     }
462     if (endp) {
463         *endp = (osal_s8 *)cp;
464     }
465     return result;
466 }
467 
oal_strtol(OAL_CONST osal_s8 * pc_nptr,osal_s8 ** ppc_endptr,osal_s32 l_base)468 static inline osal_slong oal_strtol(OAL_CONST osal_s8 *pc_nptr, osal_s8 **ppc_endptr, osal_s32 l_base)
469 {
470     /* 跳过空格 */
471     while ((*pc_nptr) == ' ') {
472         pc_nptr++;
473     }
474 
475     if (*pc_nptr == '-') {
476         return (osal_slong)(-oal_simple_strtoull(pc_nptr + 1, ppc_endptr, (osal_u32)l_base));
477     }
478     return (osal_slong)oal_simple_strtoull(pc_nptr, ppc_endptr, (osal_u32)l_base);
479 }
480 
481 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
482 #ifdef _PRE_WIFI_PRINTK
oal_print_hex_dump(const osal_u8 * addr,osal_s32 len,osal_s32 groupsize,const osal_char * pre_str)483 static inline osal_void oal_print_hex_dump(const osal_u8* addr, osal_s32 len, osal_s32 groupsize,
484     const osal_char* pre_str)
485 {
486     unref_param(groupsize);
487     wifi_printf("%s: len = %d", pre_str, len);
488     for (td_s32 i = 0; i < len; i++) {
489         if (((td_u32)i & 0x000f) == 0) {
490             wifi_printf("\r\n%04d: ", i);
491         }
492         wifi_printf(" %02x", addr[i]);
493     }
494     wifi_printf("\r\n");
495 }
496 #endif
oal_dump_stack(osal_void)497 static inline osal_void oal_dump_stack(osal_void)
498 {
499 #if defined(_PRE_OS_VERSION_LINUX) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
500     ArchBackTrace();
501 #endif
502     return;
503 }
504 #endif
505 
506 #ifdef __cplusplus
507 #if __cplusplus
508 }
509 #endif
510 #endif
511 
512 #endif
513 
514