• 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 #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