xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/realtek/rtw88/util.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*4882a593Smuzhiyun /* Copyright(c) 2018-2019  Realtek Corporation
3*4882a593Smuzhiyun  */
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include "main.h"
6*4882a593Smuzhiyun #include "util.h"
7*4882a593Smuzhiyun #include "reg.h"
8*4882a593Smuzhiyun 
check_hw_ready(struct rtw_dev * rtwdev,u32 addr,u32 mask,u32 target)9*4882a593Smuzhiyun bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target)
10*4882a593Smuzhiyun {
11*4882a593Smuzhiyun 	u32 cnt;
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun 	for (cnt = 0; cnt < 1000; cnt++) {
14*4882a593Smuzhiyun 		if (rtw_read32_mask(rtwdev, addr, mask) == target)
15*4882a593Smuzhiyun 			return true;
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun 		udelay(10);
18*4882a593Smuzhiyun 	}
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun 	return false;
21*4882a593Smuzhiyun }
22*4882a593Smuzhiyun EXPORT_SYMBOL(check_hw_ready);
23*4882a593Smuzhiyun 
ltecoex_read_reg(struct rtw_dev * rtwdev,u16 offset,u32 * val)24*4882a593Smuzhiyun bool ltecoex_read_reg(struct rtw_dev *rtwdev, u16 offset, u32 *val)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	struct rtw_chip_info *chip = rtwdev->chip;
27*4882a593Smuzhiyun 	const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr;
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun 	if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1))
30*4882a593Smuzhiyun 		return false;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	rtw_write32(rtwdev, ltecoex->ctrl, 0x800F0000 | offset);
33*4882a593Smuzhiyun 	*val = rtw_read32(rtwdev, ltecoex->rdata);
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	return true;
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun 
ltecoex_reg_write(struct rtw_dev * rtwdev,u16 offset,u32 value)38*4882a593Smuzhiyun bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun 	struct rtw_chip_info *chip = rtwdev->chip;
41*4882a593Smuzhiyun 	const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1))
44*4882a593Smuzhiyun 		return false;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	rtw_write32(rtwdev, ltecoex->wdata, value);
47*4882a593Smuzhiyun 	rtw_write32(rtwdev, ltecoex->ctrl, 0xC00F0000 | offset);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	return true;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
rtw_restore_reg(struct rtw_dev * rtwdev,struct rtw_backup_info * bckp,u32 num)52*4882a593Smuzhiyun void rtw_restore_reg(struct rtw_dev *rtwdev,
53*4882a593Smuzhiyun 		     struct rtw_backup_info *bckp, u32 num)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	u8 len;
56*4882a593Smuzhiyun 	u32 reg;
57*4882a593Smuzhiyun 	u32 val;
58*4882a593Smuzhiyun 	int i;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	for (i = 0; i < num; i++, bckp++) {
61*4882a593Smuzhiyun 		len = bckp->len;
62*4882a593Smuzhiyun 		reg = bckp->reg;
63*4882a593Smuzhiyun 		val = bckp->val;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 		switch (len) {
66*4882a593Smuzhiyun 		case 1:
67*4882a593Smuzhiyun 			rtw_write8(rtwdev, reg, (u8)val);
68*4882a593Smuzhiyun 			break;
69*4882a593Smuzhiyun 		case 2:
70*4882a593Smuzhiyun 			rtw_write16(rtwdev, reg, (u16)val);
71*4882a593Smuzhiyun 			break;
72*4882a593Smuzhiyun 		case 4:
73*4882a593Smuzhiyun 			rtw_write32(rtwdev, reg, (u32)val);
74*4882a593Smuzhiyun 			break;
75*4882a593Smuzhiyun 		default:
76*4882a593Smuzhiyun 			break;
77*4882a593Smuzhiyun 		}
78*4882a593Smuzhiyun 	}
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun EXPORT_SYMBOL(rtw_restore_reg);
81*4882a593Smuzhiyun 
rtw_desc_to_mcsrate(u16 rate,u8 * mcs,u8 * nss)82*4882a593Smuzhiyun void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 	if (rate <= DESC_RATE54M)
85*4882a593Smuzhiyun 		return;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	if (rate >= DESC_RATEVHT1SS_MCS0 &&
88*4882a593Smuzhiyun 	    rate <= DESC_RATEVHT1SS_MCS9) {
89*4882a593Smuzhiyun 		*nss = 1;
90*4882a593Smuzhiyun 		*mcs = rate - DESC_RATEVHT1SS_MCS0;
91*4882a593Smuzhiyun 	} else if (rate >= DESC_RATEVHT2SS_MCS0 &&
92*4882a593Smuzhiyun 		   rate <= DESC_RATEVHT2SS_MCS9) {
93*4882a593Smuzhiyun 		*nss = 2;
94*4882a593Smuzhiyun 		*mcs = rate - DESC_RATEVHT2SS_MCS0;
95*4882a593Smuzhiyun 	} else if (rate >= DESC_RATEVHT3SS_MCS0 &&
96*4882a593Smuzhiyun 		   rate <= DESC_RATEVHT3SS_MCS9) {
97*4882a593Smuzhiyun 		*nss = 3;
98*4882a593Smuzhiyun 		*mcs = rate - DESC_RATEVHT3SS_MCS0;
99*4882a593Smuzhiyun 	} else if (rate >= DESC_RATEVHT4SS_MCS0 &&
100*4882a593Smuzhiyun 		   rate <= DESC_RATEVHT4SS_MCS9) {
101*4882a593Smuzhiyun 		*nss = 4;
102*4882a593Smuzhiyun 		*mcs = rate - DESC_RATEVHT4SS_MCS0;
103*4882a593Smuzhiyun 	} else if (rate >= DESC_RATEMCS0 &&
104*4882a593Smuzhiyun 		   rate <= DESC_RATEMCS15) {
105*4882a593Smuzhiyun 		*mcs = rate - DESC_RATEMCS0;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun }
108