18e93258fSBjoern A. Zeeb /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 28e93258fSBjoern A. Zeeb * Copyright(c) 2019-2020 Realtek Corporation 38e93258fSBjoern A. Zeeb */ 48e93258fSBjoern A. Zeeb #ifndef __RTW89_UTIL_H__ 58e93258fSBjoern A. Zeeb #define __RTW89_UTIL_H__ 68e93258fSBjoern A. Zeeb 78e93258fSBjoern A. Zeeb #include "core.h" 88e93258fSBjoern A. Zeeb 9*6d67aabdSBjoern A. Zeeb #define RTW89_LINEAR_FRAC_BITS 3 10*6d67aabdSBjoern A. Zeeb 118e93258fSBjoern A. Zeeb #define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ 128e93258fSBjoern A. Zeeb ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ 138e93258fSBjoern A. Zeeb IEEE80211_IFACE_ITER_NORMAL, iterator, data) 148e93258fSBjoern A. Zeeb 158e93258fSBjoern A. Zeeb /* call this function with rtwdev->mutex is held */ 168e93258fSBjoern A. Zeeb #define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ 178e93258fSBjoern A. Zeeb list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) 188e93258fSBjoern A. Zeeb 198e93258fSBjoern A. Zeeb /* The result of negative dividend and positive divisor is undefined, but it 208e93258fSBjoern A. Zeeb * should be one case of round-down or round-up. So, make it round-down if the 218e93258fSBjoern A. Zeeb * result is round-up. 228e93258fSBjoern A. Zeeb * Note: the maximum value of divisor is 0x7FFF_FFFF, because we cast it to 238e93258fSBjoern A. Zeeb * signed value to make compiler to use signed divide instruction. 248e93258fSBjoern A. Zeeb */ 258e93258fSBjoern A. Zeeb static inline s32 s32_div_u32_round_down(s32 dividend, u32 divisor, s32 *remainder) 268e93258fSBjoern A. Zeeb { 278e93258fSBjoern A. Zeeb s32 i_divisor = (s32)divisor; 288e93258fSBjoern A. Zeeb s32 i_remainder; 298e93258fSBjoern A. Zeeb s32 quotient; 308e93258fSBjoern A. Zeeb 318e93258fSBjoern A. Zeeb quotient = dividend / i_divisor; 328e93258fSBjoern A. Zeeb i_remainder = dividend % i_divisor; 338e93258fSBjoern A. Zeeb 348e93258fSBjoern A. Zeeb if (i_remainder < 0) { 358e93258fSBjoern A. Zeeb quotient--; 368e93258fSBjoern A. Zeeb i_remainder += i_divisor; 378e93258fSBjoern A. Zeeb } 388e93258fSBjoern A. Zeeb 398e93258fSBjoern A. Zeeb if (remainder) 408e93258fSBjoern A. Zeeb *remainder = i_remainder; 418e93258fSBjoern A. Zeeb return quotient; 428e93258fSBjoern A. Zeeb } 438e93258fSBjoern A. Zeeb 448e93258fSBjoern A. Zeeb static inline s32 s32_div_u32_round_closest(s32 dividend, u32 divisor) 458e93258fSBjoern A. Zeeb { 468e93258fSBjoern A. Zeeb return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL); 478e93258fSBjoern A. Zeeb } 488e93258fSBjoern A. Zeeb 49e2340276SBjoern A. Zeeb static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask) 50e2340276SBjoern A. Zeeb { 51e2340276SBjoern A. Zeeb int i; 52e2340276SBjoern A. Zeeb 53e2340276SBjoern A. Zeeb eth_zero_addr(dst); 54e2340276SBjoern A. Zeeb for (i = 0; i < ETH_ALEN; i++) { 55e2340276SBjoern A. Zeeb if (mask & BIT(i)) 56e2340276SBjoern A. Zeeb dst[i] = src[i]; 57e2340276SBjoern A. Zeeb } 58e2340276SBjoern A. Zeeb } 59e2340276SBjoern A. Zeeb 60*6d67aabdSBjoern A. Zeeb u32 rtw89_linear_2_db(u64 linear); 61*6d67aabdSBjoern A. Zeeb u64 rtw89_db_2_linear(u32 db); 62*6d67aabdSBjoern A. Zeeb 638e93258fSBjoern A. Zeeb #endif 64