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