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 #ifndef __OAL_UTIL_H__
20 #define __OAL_UTIL_H__
21
22 /* ****************************************************************************
23 1 其他头文件包含
24 **************************************************************************** */
25 #include <linux/kernel.h>
26 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
27 #include <sys/time.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <linux/delay.h>
31 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
32 #include <linux/time.h>
33 #include <linux/string.h>
34 #include <linux/ctype.h>
35 #include <linux/delay.h>
36 #include <asm/delay.h>
37 #endif
38
39 #include "hi_atomic.h"
40 #include "hi_stdlib.h"
41 #include "oal_err_wifi.h"
42 #include "oam_log.h"
43 #include "wlan_spec_1131h.h"
44
45 #ifdef __cplusplus
46 #if __cplusplus
47 extern "C" {
48 #endif
49 #endif
50
51 /* ****************************************************************************
52 2 宏定义
53 **************************************************************************** */
54 #ifndef CURRENT
55 #define CURRENT 0
56 #endif
57 #ifndef EOK
58 #define EOK 0
59 #endif
60
61 #define __OAL_DECLARE_PACKED __attribute__((__packed__))
62 #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE)
63 #define WIFI_ROM_TEXT
64 #define WIFI_ROM_RODATA
65 #define WIFI_ROM_DATA
66 #define WIFI_ROM_BSS
67 #else
68 #define WIFI_ROM_TEXT __attribute__ ((section(".wifi.rom.text"))) /* ROM代码段 */
69 #define WIFI_ROM_RODATA __attribute__ ((section(".wifi.rom.rodata"))) /* ROM const全局变量段 可与text段复用 */
70 #define WIFI_ROM_DATA __attribute__ ((section(".wifi.rom.data"))) /* ROM 初值非0全局变量段 不能与bss混用 */
71 #define WIFI_ROM_BSS __attribute__ ((section(".wifi.rom.bss"))) /* ROM 初值0或未赋值全局变量段
72 可以data段混用 只会影响RAM段大小 */
73 #endif
74
75 extern hi_u32 g_level_log;
76
77 #define _HI113X_PRINTK_STDOUT
78
hi_strrchr(const hi_char * file,hi_char c)79 static inline hi_char *hi_strrchr(const hi_char *file, hi_char c)
80 {
81 hi_char *p = HI_NULL;
82 return (((p = strrchr(file, c)) != HI_NULL) ? (p + 1) : (HI_NULL));
83 }
84
85
86 #if defined(HAVE_PCLINT_CHECK)
87 #define oal_likely(_expr) (_expr)
88 #define oal_unlikely(_expr) (_expr)
89 #else
90 #define oal_likely(_expr) likely(_expr)
91 #define oal_unlikely(_expr) unlikely(_expr)
92 #endif
93
94 #define OAL_BUG_ON(_con) BUG_ON(_con)
95 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
96 #define OAL_WARN_ON(condition) ({int __ret = !!(condition); __ret;})
97 #else
98 #define OAL_WARN_ON(condition) WARN_ON(condition)
99 #endif
100
101 /* 数学计算 */
102 #define oal_max(a, b) (((a) > (b)) ? (a) : (b))
103 #define oal_min(a, b) (((a) < (b)) ? (a) : (b))
104 #define oal_sub(a, b) (((a) > (b)) ? ((a) - (b)) : 0)
105 #define oal_abs(a) (((a) > 0) ? (a) : (-(a)))
106 #define oal_abs_ab(a, b) ((a) >= 0 ? (b) : (-(b)))
107 #define oal_abs_sub(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
108
109 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
110 /* Works only for digits and letters, but small and fast */
111 #define TOLOWER(x) ((x) | 0x20)
112
113 #define isdigit(c) ('0' <= (c) && (c) <= '9')
114
115 #define _isxdigit(c) (('0' <= (c) && (c) <= '9') || ('a' <= (c) && (c) <= 'f') || ('A' <= (c) && (c) <= 'F'))
116 #endif
117
118 /* 入参判空 */
119 #define oal_any_null_ptr1(_a) (oal_unlikely(HI_NULL == (_a)))
120 #define oal_any_null_ptr2(_a, _b) (oal_unlikely((HI_NULL == (_a)) || (HI_NULL == (_b))))
121 #define oal_any_null_ptr3(_a, _b, _c) (oal_unlikely((HI_NULL == (_a)) || (HI_NULL == (_b)) || (HI_NULL == (_c))))
122
123 /* 字节操作 */
124 #define rotl_w(val, bits, width) (((val) << (bits)) | ((val) >> ((width) - (bits))))
125 #define rotr_w(val, bits, width) (((val) >> (bits)) | ((val) << ((width) - (bits))))
126 #define rotl32(val, bits) rotl_w(val, bits, 32) /* 32 bits word */
127 #define rotr32(val, bits) rotr_w(val, bits, 32) /* 32 bits word */
128
129 #define OAL_RET_ADDR __builtin_return_address(0)
130
131 /* RSSI统计滤波,RSSI范围是-128~127, 一般不会等于127这么大,所以将127设置为MARKER,即初始值 */
132 #define WLAN_RSSI_DUMMY_MARKER 0x7F
133 /* 将几个字符串按照指定格式合成一个字符串 */
134 #define OAL_PAGE_SIZE PAGE_SIZE
135
136 #define kernel_version(a, b, c) (((a)<<16) | ((b)<<8) | (c))
137 #ifndef _PRE_HDF_LINUX
138 #define LINUX_VERSION_CODE kernel_version(4, 9, 0)
139 #endif
140 #ifndef HW_LITEOS_OPEN_VERSION_NUM
141 #define HW_LITEOS_OPEN_VERSION_NUM kernel_version(1, 3, 2)
142 #endif
143
144 #define oal_warn_on(condition) (condition)
145 #define PLATFORM_NAME_SIZE 20
146
147 /* 虚拟地址转物理地址 */
148 #define oal_virt_to_phy_addr(_virt_addr) ((uintptr_t)(_virt_addr))
149 /* 物理地址转虚拟地址 */
150 #define oal_phy_to_virt_addr(_phy_addr) ((hi_u32 *)(_phy_addr))
151
152 #if (_PRE_BIG_CPU_ENDIAN == _PRE_CPU_ENDIAN) /* BIG_ENDIAN */
153 #define oal_byteorder_to_le64(_val) hi_swap_byteorder_64(_val)
154 #define oal_byteorder_to_le32(_val) hi_swap_byteorder_32(_val)
155 #define oal_byteorder_to_le16(_val) hi_swap_byteorder_16(_val)
156
157 #define oal_byteorder_to_be64(_val) (_val)
158 #define oal_byteorder_to_be32(_val) (_val)
159 #define oal_byteorder_to_be16(_val) (_val)
160
161 #define oal_mask_inverse(_len, _offset) ((hi_u32)(hi_swap_byteorder_32(~((hi_u32)((1UL << (_len)) - 1) << (_offset)))))
162 #define oal_mask(_len, _offset) ((hi_u32)(hi_swap_byteorder_32((hi_u32)((1UL << (_len)) - 1) << (_offset))))
163 #define oal_ntoh_16(_val) (_val)
164 #define oal_ntoh_32(_val) (_val)
165 #define oal_hton_16(_val) (_val)
166 #define oal_hton_32(_val) (_val)
167
168 #elif (_PRE_LITTLE_CPU_ENDIAN == _PRE_CPU_ENDIAN) /* LITTLE_ENDIAN */
169 #define oal_byteorder_to_le64(_val) (_val)
170 #define oal_byteorder_to_le32(_val) (_val)
171 #define oal_byteorder_to_le16(_val) (_val)
172
173 #ifdef HAVE_PCLINT_CHECK
174 #define oal_byteorder_to_be64(_val) (_val)
175 #define oal_byteorder_to_be32(_val) (_val)
176 #define oal_byteorder_to_be16(_val) (_val)
177
178 #define oal_ntoh_16(_val) (_val)
179 #define oal_ntoh_32(_val) (_val)
180 #define oal_hton_16(_val) (_val)
181 #define oal_hton_32(_val) (_val)
182 #else
183 #define oal_byteorder_to_be64(_val) hi_swap_byteorder_64(_val)
184 #define oal_byteorder_to_be32(_val) hi_swap_byteorder_32(_val)
185 #define oal_byteorder_to_be16(_val) hi_swap_byteorder_16(_val)
186
187 #define oal_ntoh_16(_val) hi_swap_byteorder_16(_val)
188 #define oal_ntoh_32(_val) hi_swap_byteorder_32(_val)
189 #define oal_hton_16(_val) hi_swap_byteorder_16(_val)
190 #define oal_hton_32(_val) hi_swap_byteorder_32(_val)
191 #endif /* HAVE_PCLINT_CHECK */
192
193 #define oal_mask_inverse(_len, _offset) ((hi_u32)(~((hi_u32)((1UL << (_len)) - 1) << (_offset))))
194 #define oal_mask(_len, _offset) ((hi_u32)((hi_u32)((1UL << (_len)) - 1) << (_offset)))
195 #endif /* _PRE_CPU_ENDIAN */
196
197
198 /* 日志级别 */
199 typedef enum {
200 OAM_LOG_LEVEL_ERROR = 0, /* ERROR级别打印 */
201 OAM_LOG_LEVEL_WARNING, /* WARNING级别打印 */
202 OAM_LOG_LEVEL_INFO, /* INFO级别打印 */
203 OAM_LOG_LEVEL_DEBUG, /* INFO级别打印 */
204 OAM_LOG_LEVEL_VERBOSE, /* INFO级别打印 */
205
206 OAM_LOG_LEVEL_BUTT
207 } oam_log_level_enum;
208
209 #define oam_logn(vid, eid, level, fmt, args...) \
210 oal_print_nlogs(__FILE__, __FUNCTION__, (hi_u16)__LINE__, OAL_RET_ADDR, vid, eid, level, 0, fmt, ##args)
211
212 #define oam_log(vid, eid, level, fmt, cnt, p1, p2, p3, p4) \
213 oal_print_nlogs(__FILE__, __FUNCTION__, (hi_u16)__LINE__, OAL_RET_ADDR, vid, eid, level, cnt, fmt, p1, p2, p3, p4)
214
215 #define hi_diag_log_msg_e0(id, sz) oam_log(0, id, OAM_LOG_LEVEL_ERROR, sz, 0, 0, 0, 0, 0)
216 #define hi_diag_log_msg_e1(id, sz, p1) oam_log(0, id, OAM_LOG_LEVEL_ERROR, sz, 1, p1,0, 0, 0)
217 #define hi_diag_log_msg_e2(id, sz, p1, p2) oam_log(0, id, OAM_LOG_LEVEL_ERROR, sz, 2, p1, p2, 0, 0)
218 #define hi_diag_log_msg_e3(id, sz, p1, p2, p3) oam_log(0, id, OAM_LOG_LEVEL_ERROR, sz, 3, p1, p2, p3, 0)
219 #define hi_diag_log_msg_e4(id, sz, p1, p2, p3, p4) oam_log(0, id, OAM_LOG_LEVEL_ERROR, sz, 4, p1, p2, p3, p4)
220 #define hi_diag_log_buf_e(id, sz, buffer, size)
221
222 #define hi_diag_log_msg_w0(id, sz) oam_log(0, id, OAM_LOG_LEVEL_WARNING, sz, 0, 0, 0, 0, 0)
223 #define hi_diag_log_msg_w1(id, sz, p1) oam_log(0, id, OAM_LOG_LEVEL_WARNING, sz, 1, p1,0, 0, 0)
224 #define hi_diag_log_msg_w2(id, sz, p1, p2) oam_log(0, id, OAM_LOG_LEVEL_WARNING, sz, 2, p1, p2, 0, 0)
225 #define hi_diag_log_msg_w3(id, sz, p1, p2, p3) oam_log(0, id, OAM_LOG_LEVEL_WARNING, sz, 3, p1, p2, p3, 0)
226 #define hi_diag_log_msg_w4(id, sz, p1, p2, p3, p4) oam_log(0, id, OAM_LOG_LEVEL_WARNING, sz, 4, p1, p2, p3, p4)
227 #define hi_diag_log_buf_w(id, sz, buffer, size)
228
229 #define hi_diag_log_msg_i0(id, sz) oam_log(0, id, OAM_LOG_LEVEL_INFO, sz, 0, 0, 0, 0, 0)
230 #define hi_diag_log_msg_i1(id, sz, p1) oam_log(0, id, OAM_LOG_LEVEL_INFO, sz, 1, p1,0, 0, 0)
231 #define hi_diag_log_msg_i2(id, sz, p1, p2) oam_log(0, id, OAM_LOG_LEVEL_INFO, sz, 2, p1, p2, 0, 0)
232 #define hi_diag_log_msg_i3(id, sz, p1, p2, p3) oam_log(0, id, OAM_LOG_LEVEL_INFO, sz, 3, p1, p2, p3, 0)
233 #define hi_diag_log_msg_i4(id, sz, p1, p2, p3, p4) oam_log(0, id, OAM_LOG_LEVEL_INFO, sz, 4, p1, p2, p3, p4)
234 #define hi_diag_log_bug(id, sz, buffer, size)
235
236 #define oal_io_print_err(sz) oam_log(0, 0, OAM_LOG_LEVEL_ERROR, sz, 0, 0, 0, 0, 0)
237 #define oal_io_print(sz) oam_print(sz)
238 #define oal_io_print0(sz) oam_log(0, 0, OAM_LOG_LEVEL_INFO, sz, 0, 0,0, 0, 0)
239 #define oal_io_print1(sz, p1) oam_log(0, 0, OAM_LOG_LEVEL_INFO, sz, 1, p1,0, 0, 0)
240 #define oal_io_print2(sz, p1, p2) oam_log(0, 0, OAM_LOG_LEVEL_INFO, sz, 2, p1, p2, 0, 0)
241 #define oal_io_print3(sz, p1, p2, p3) oam_log(0, 0, OAM_LOG_LEVEL_INFO, sz, 3, p1, p2, p3, 0)
242 #define oal_io_print4(sz, p1, p2, p3, p4) oam_log(0, 0, OAM_LOG_LEVEL_INFO, sz, 4, p1, p2, p3, p4)
243
244 #define hi_at_printf dprintf
245
246 #ifndef IS_ALIGNED
247 #define oal_is_aligned(val, align) (((hi_u32)(val) & ((align)-1)) == 0)
248 #else
249 #define oal_is_aligned IS_ALIGNED
250 #endif
251
252 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
253 #define oal_round_up round_up
254 #define oal_round_down round_down
255 #define oal_offset_of offsetof
256 #else
257 #define oal_round_up(_old_len, _align) ((((_old_len) + ((_align) - 1)) / (_align)) * (_align))
258 #define oal_round_down(value, boundary) ((value) & (~((boundary) - 1)))
259 #define oal_offset_of(type, member) ((long) &((type *) 0)->member)
260 #endif
261
262 /* ****************************************************************************
263 函数声明
264 **************************************************************************** */
265 hi_void oal_strtoaddr(const hi_char *param, hi_u8 *mac_addr, hi_u8 mac_addr_len);
266 hi_u8 oal_bit_find_first_bit_four_byte(hi_u32 word);
267 hi_u8 oal_get_lut_index(hi_u8 *lut_index_table, hi_u8 bitmap_len, hi_u16 max_lut_size);
268 hi_void oal_random_ether_addr(hi_u8 *mac_addr, hi_u8 mac_addr_len);
269 hi_void oal_print_hex_dump(const hi_u8 *addr, hi_s32 len, hi_s32 group_size, hi_char *pre_str);
270 hi_s8 wlan_rssi_lpf(hi_s8 old, hi_s8 new);
271
272 /* ****************************************************************************
273 函数定义
274 **************************************************************************** */
275 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
276 #define oal_atoi atoi
277 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
278 hi_s32 oal_atoi(const hi_char *c_string);
279 #endif
280
281
282 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
283 #define oal_strtok strtok
284 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_strtok(hi_char * pc_token,const hi_char * pc_delemit)285 static inline hi_char *oal_strtok(hi_char *pc_token, const hi_char *pc_delemit)
286 {
287 hi_char *pc_str = HI_NULL;
288 const hi_char *pc_ctrl = pc_delemit;
289
290 hi_char uc_map[32]; /* 32个元素数组 */
291 hi_s32 l_count;
292
293 static hi_char *pc_nextoken;
294
295 /* Clear control map */
296 for (l_count = 0; l_count < 32; l_count++) { /* 32个元素数组 */
297 uc_map[l_count] = 0;
298 }
299
300 /* Set bits in delimiter table */
301 do {
302 uc_map[*pc_ctrl >> 3] |= (1 << (*pc_ctrl & 7)); /* 7:取低3位,左移1位 */
303 } while (*pc_ctrl++);
304
305 /* Initialize str. If string is NULL, set str to the saved
306 * pointer (i.e., continue breaking tokens out of the string
307 * from the last strtok call) */
308 if (pc_token != HI_NULL) {
309 pc_str = pc_token;
310 } else {
311 pc_str = pc_nextoken;
312 }
313
314 /* Find beginning of token (skip over leading delimiters). Note that
315 * there is no token iff this loop sets str to point to the terminal
316 * null (*str == '\0') */
317 while ((uc_map[*pc_str >> 3] & (1 << (*pc_str & 7))) && *pc_str) { /* 7:取低3位,左移1位 */
318 pc_str++;
319 }
320
321 pc_token = pc_str;
322
323 /* Find the end of the token. If it is not the end of the string,
324 * put a null there. */
325 for (; *pc_str; pc_str++) {
326 if (uc_map[*pc_str >> 3] & (1 << (*pc_str & 7))) { /* 7:取低3位,左移1位 */
327 *pc_str++ = '\0';
328 break;
329 }
330 }
331
332 /* Update nextoken (or the corresponding field in the per-thread data
333 * structure */
334 pc_nextoken = pc_str;
335
336 /* Determine if a token has been found. */
337 if (pc_token == pc_str) {
338 return NULL;
339 } else {
340 return pc_token;
341 }
342 }
343 #endif
344
345 /* ****************************************************************************
346 功能描述 : 判断是否是大写字母
347 输入参数 : c_letter: 字符串字母
348 **************************************************************************** */
oal_is_alpha_upper(hi_char letter)349 static inline hi_u8 oal_is_alpha_upper(hi_char letter)
350 {
351 if (letter >= 'A' && letter <= 'Z') {
352 return HI_TRUE;
353 }
354
355 return HI_FALSE;
356 }
357
358 /* ****************************************************************************
359 功能描述 : 将一个字符转化成16进制数
360 **************************************************************************** */
oal_strtohex(const hi_char * str)361 static inline hi_u8 oal_strtohex(const hi_char *str)
362 {
363 if (*str >= '0' && *str <= '9') {
364 return (hi_u8)(*str - '0');
365 } else if (*str >= 'A' && *str <= 'F') {
366 return (hi_u8)(*str - 'A' + 10); /* 10: 加10 */
367 } else if (*str >= 'a' && *str <= 'f') {
368 return (hi_u8)(*str - 'a' + 10); /* 10: 加10 */
369 }
370
371 return 0;
372 }
373
374 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
375 #define oal_strtol strtol
376 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_simple_guess_base(const char * cp)377 static inline hi_u32 oal_simple_guess_base(const char *cp)
378 {
379 if (cp[0] == '0') {
380 if (TOLOWER(cp[1]) == 'x' && _isxdigit(cp[2])) {
381 return 16; /* 16 hex */
382 } else {
383 return 8; /* 8 oct */
384 }
385 } else {
386 return 10; /* 10 dec */
387 }
388 }
389
oal_simple_strtoull(const hi_char * cp,hi_char ** endp,hi_u32 base)390 static inline unsigned long long oal_simple_strtoull(const hi_char *cp, hi_char **endp, hi_u32 base)
391 {
392 unsigned long long result = 0;
393
394 if (!base) {
395 base = oal_simple_guess_base(cp);
396 }
397
398 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') { /* base equal 16 */
399 cp += 2; /* add 2 */
400 }
401
402 while (_isxdigit(*cp)) {
403 unsigned int value;
404
405 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; /* add 10 */
406 if (value >= base) {
407 break;
408 }
409 result = result * base + value;
410 cp++;
411 }
412 if (endp != HI_NULL) {
413 *endp = (hi_char *)cp;
414 }
415
416 return result;
417 }
418
oal_strtol(const hi_char * pc_nptr,hi_char ** ppc_endptr,hi_s32 l_base)419 static inline hi_s32 oal_strtol(const hi_char *pc_nptr, hi_char **ppc_endptr, hi_s32 l_base)
420 {
421 /* 跳过空格 */
422 while ((*pc_nptr) == ' ') {
423 pc_nptr++;
424 }
425
426 if (*pc_nptr == '-') {
427 return -oal_simple_strtoull(pc_nptr + 1, ppc_endptr, l_base);
428 }
429
430 return oal_simple_strtoull(pc_nptr, ppc_endptr, l_base);
431 }
432 #endif /* #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) */
433
434 /* ****************************************************************************
435 功能描述 : 产生随机数
436 **************************************************************************** */
oal_get_random(hi_void)437 static inline hi_u8 oal_get_random(hi_void)
438 {
439 return 1;
440 }
441
442 /* ****************************************************************************
443 功能描述 : 产生随机数
444 输入参数 : value:随机种子 rst_flag:0:不更新随机种子,非0:更新随机种子
445 **************************************************************************** */
oal_gen_random(hi_u32 value,hi_u8 rst_flag)446 static inline hi_u8 oal_gen_random(hi_u32 value, hi_u8 rst_flag)
447 {
448 static hi_u32 rand_val = 0; /* 本inline函数被ROM化代码调用,lin_t e1534告警屏蔽 */
449
450 if (rst_flag != 0) {
451 rand_val = value;
452 }
453
454 rand_val = rand_val * 1664525L + 1013904223L;
455 return (hi_u8)(rand_val >> 24); /* 24: 右移24位 */
456 }
457
458 /* ****************************************************************************
459 功能描述 : 获取单字节中的bit1的个数
460 输入参数 : byte:需要操作的字节
461 **************************************************************************** */
oal_bit_get_num_one_byte(hi_u8 byte)462 static inline hi_u8 oal_bit_get_num_one_byte(hi_u8 byte)
463 {
464 byte = (byte & 0x55) + ((byte >> 1) & 0x55);
465 byte = (byte & 0x33) + ((byte >> 2) & 0x33); /* 2: 右移2位 */
466 byte = (byte & 0x0F) + ((byte >> 4) & 0x0F); /* 4: 右移4位 */
467
468 return byte;
469 }
470
471 /* ****************************************************************************
472 功能描述 : 获取4字节中bit1的个数
473 输入参数 : word:需要操作的字节
474 **************************************************************************** */
oal_bit_get_num_four_byte(hi_u32 word)475 static inline hi_u32 oal_bit_get_num_four_byte(hi_u32 word)
476 {
477 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
478 word = (word & 0x33333333) + ((word >> 2) & 0x33333333); /* 2: 右移2位 */
479 word = (word & 0x0F0F0F0F) + ((word >> 4) & 0x0F0F0F0F); /* 4: 右移4位 */
480 word = (word & 0x00FF00FF) + ((word >> 8) & 0x00FF00FF); /* 8: 右移8位 */
481 word = (word & 0x0000FFFF) + ((word >> 16) & 0x0000FFFF); /* 16: 右移16位 */
482
483 return word;
484 }
485
486 /* ****************************************************************************
487 功能描述 : 对1字节的指定位置一
488 输入参数 : byte: 要进行位操作的变量地址
489 nr: 置位的位数
490 **************************************************************************** */
oal_bit_set_bit_one_byte(hi_u8 * byte,hi_u32 nr)491 static inline hi_void oal_bit_set_bit_one_byte(hi_u8 *byte, hi_u32 nr)
492 {
493 *byte |= ((hi_u8)(1 << nr));
494 }
495
496 /* ****************************************************************************
497 功能描述 : 对1字节的指定位置零
498 输入参数 : byte: 要进行位操作的变量地址
499 nr: 置零的位数
500 **************************************************************************** */
oal_bit_clear_bit_one_byte(hi_u8 * byte,hi_u32 nr)501 static inline hi_void oal_bit_clear_bit_one_byte(hi_u8 *byte, hi_u32 nr)
502 {
503 *byte &= (~((hi_u8)(1 << nr)));
504 }
505
506 /* ****************************************************************************
507 功能描述 : 对8字节的指定位置一
508 输入参数 : [1]double_word
509 [2]nr
510 输出参数 : 无
511 返 回 值 : static inline hi_void
512 **************************************************************************** */
oal_bit_set_bit_eight_byte(hi_u64 * double_word,hi_u32 nr)513 static inline hi_void oal_bit_set_bit_eight_byte(hi_u64 *double_word, hi_u32 nr)
514 {
515 *double_word |= ((hi_u64)1 << nr);
516 }
517
518 /* ****************************************************************************
519 功能描述 : 对8字节的指定位置0
520 输入参数 : [1]double_word
521 [2]nr
522 **************************************************************************** */
oal_bit_clear_bit_eight_byte(hi_u64 * double_word,hi_u32 nr)523 static inline hi_void oal_bit_clear_bit_eight_byte(hi_u64 *double_word, hi_u32 nr)
524 {
525 *double_word &= ~((hi_u64)1 << nr);
526 }
527
528 /* ****************************************************************************
529 功能描述 : 找到字节数第一个是0的位数
530 输入参数 : value: 要查找的字节, max_cnt: 查找字节中可用位数
531 返 回 值 : 右数第一个是0的位数
532 **************************************************************************** */
oal_bit_find_first_zero(hi_u32 value,hi_u8 max_cnt)533 static inline hi_u8 oal_bit_find_first_zero(hi_u32 value, hi_u8 max_cnt)
534 {
535 hi_u8 index;
536
537 for (index = 0; index < max_cnt; index++) {
538 if ((value & (hi_u32)(1 << index)) == 0) {
539 break;
540 }
541 }
542 return index;
543 }
544
545 /* ****************************************************************************
546 功能描述 : mac地址置零
547 输入参数 : mac_addr: 需清零的mac地址的指针
548 **************************************************************************** */
oal_set_mac_addr_zero(hi_u8 * mac_addr)549 static inline hi_void oal_set_mac_addr_zero(hi_u8 *mac_addr)
550 {
551 mac_addr[0] = 0;
552 mac_addr[1] = 0;
553 mac_addr[2] = 0; /* 2: mac_addr 下标 */
554 mac_addr[3] = 0; /* 3: mac_addr 下标 */
555 mac_addr[4] = 0; /* 4: mac_addr 下标 */
556 mac_addr[5] = 0; /* 5: mac_addr 下标 */
557 }
558
559 /* ****************************************************************************
560 功能描述 : 比较两个mac地址是否相等
561 输入参数 : mac_addr1: 第一个mac地址
562 mac_addr2: 第二个mac地址
563 输出参数 : 无
564 返 回 值 : 不等返回1 ; 相等返回0
565 **************************************************************************** */
oal_compare_mac_addr(const hi_u8 * mac_addr1,const hi_u8 * mac_addr2,hi_u8 mac_addr_len)566 static inline hi_u32 oal_compare_mac_addr(const hi_u8 *mac_addr1, const hi_u8 *mac_addr2, hi_u8 mac_addr_len)
567 {
568 if (mac_addr_len != WLAN_MAC_ADDR_LEN) {
569 return 1;
570 }
571
572 return (mac_addr1[0] ^ mac_addr2[0]) | (mac_addr1[1] ^ mac_addr2[1])
573 | (mac_addr1[2] ^ mac_addr2[2]) | (mac_addr1[3] ^ mac_addr2[3]) /* 2,3: mac_addr 下标 */
574 | (mac_addr1[4] ^ mac_addr2[4]) | (mac_addr1[5] ^ mac_addr2[5]); /* 4,5: mac_addr 下标 */
575 }
576
577 /* ****************************************************************************
578 功能描述 : 将第二个ip地址 赋值给第一个ip地址
579 输入参数 : ip_addr1: 第一个mac地址
580 ip_addr2: 第二个mac地址
581 **************************************************************************** */
oal_set_ip_addr(hi_u8 * ip_addr1,const hi_u8 * ip_addr2)582 static inline hi_void oal_set_ip_addr(hi_u8 *ip_addr1, const hi_u8 *ip_addr2)
583 {
584 ip_addr1[0] = ip_addr2[0];
585 ip_addr1[1] = ip_addr2[1];
586 ip_addr1[2] = ip_addr2[2]; /* 2: ip_addr1 下标 */
587 ip_addr1[3] = ip_addr2[3]; /* 3: ip_addr1 下标 */
588 }
589
590 /* ****************************************************************************
591 功能描述 : 比较两个接收描述符的中断顺序号的大小,seq_num1大于seq_num2返回真
592 输入参数 : (1)数值1
593 (2)数值2
594 (3)两个数值间的最大差值
595 输出参数 : 无
596 返 回 值 : HI_TRUE或者HI_FALSE
597 **************************************************************************** */
oal_cmp_seq_num(hi_u32 seq_num1,hi_u32 seq_num2,hi_u32 diff_value)598 static inline hi_u8 oal_cmp_seq_num(hi_u32 seq_num1, hi_u32 seq_num2, hi_u32 diff_value)
599 {
600 if (((seq_num1 < seq_num2) && ((seq_num2 - seq_num1) < diff_value)) ||
601 ((seq_num1 > seq_num2) && ((seq_num1 - seq_num2) > diff_value))) {
602 return HI_TRUE;
603 }
604
605 return HI_FALSE;
606 }
607
608 /* ****************************************************************************
609 功能描述 : 初始化传入的LUT BITMAP表
610 **************************************************************************** */
oal_init_lut(hi_u8 * lut_index_table,hi_u8 bitmap_len)611 static inline hi_u32 oal_init_lut(hi_u8 *lut_index_table, hi_u8 bitmap_len)
612 {
613 hi_u8 index;
614
615 for (index = 0; index < bitmap_len; index++) {
616 lut_index_table[index] = 0;
617 }
618
619 return HI_SUCCESS;
620 }
621
622 /* ****************************************************************************
623 功能描述 : 在LUT index bitmap表中,删除一个LUT index (注:%可以作为优化项)
624 **************************************************************************** */
oal_del_lut_index(hi_u8 * lut_index_table,hi_u8 idx)625 static inline hi_void oal_del_lut_index(hi_u8 *lut_index_table, hi_u8 idx)
626 {
627 hi_u8 byte = idx / 8; /* 8: 除以8 */
628 hi_u8 bit_offset = idx % 8; /* 8: 对8取余 */
629
630 lut_index_table[byte] &= ~(hi_u8)(1 << bit_offset);
631 }
632
633 /* ****************************************************************************
634 功能描述 : 物理地址转化为虚拟地址
635 **************************************************************************** */
oal_get_virt_addr(hi_u32 * phy_addr)636 static inline hi_u32 *oal_get_virt_addr(hi_u32 *phy_addr)
637 {
638 /* 空指针无需转化 */
639 if (phy_addr == HI_NULL) {
640 return phy_addr;
641 }
642
643 return (hi_u32 *)oal_phy_to_virt_addr(phy_addr);
644 }
645
646 /* ****************************************************************************
647 功能描述 : 获取当前时间
648 **************************************************************************** */
oal_get_curr_time_ms(hi_void)649 static inline hi_u32 oal_get_curr_time_ms(hi_void)
650 {
651 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
652 struct timeval tv = {
653 .tv_sec = 0,
654 .tv_usec = 0,
655 };
656
657 gettimeofday(&tv, HI_NULL);
658 return (hi_u32)(tv.tv_sec * 1000 + tv.tv_usec / 1000); /* 1000 时间单位转换 */
659 #elif defined(_PRE_HDF_LINUX)
660 return 0;
661 #endif
662 }
663
oal_simple_strtoul(const hi_char * string,char ** result,hi_u32 base)664 static inline unsigned long oal_simple_strtoul(const hi_char *string, char **result, hi_u32 base)
665 {
666 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
667 return strtoul(string, result, base);
668 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
669 return simple_strtoul(string, result, base);
670 #endif
671 }
672
oal_msleep(hi_u32 ul_usecs)673 static inline hi_void oal_msleep(hi_u32 ul_usecs)
674 {
675 msleep(ul_usecs);
676 }
677
678 #ifdef __cplusplus
679 #if __cplusplus
680 }
681 #endif
682 #endif
683
684 #endif /* end of oal_util.h */
685