1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #include "../include/rtw_iol.h"
5
CheckCondition(const u32 Condition,const u32 Hex)6 static bool CheckCondition(const u32 Condition, const u32 Hex)
7 {
8 u32 _interface = (Hex & 0x0000FF00) >> 8;
9 u32 _platform = (Hex & 0x00FF0000) >> 16;
10 u32 cond = Condition;
11
12 if (Condition == 0xCDCDCDCD)
13 return true;
14
15 cond = Condition & 0x0000FF00;
16 cond = cond >> 8;
17 if ((_interface & cond) == 0 && cond != 0x07)
18 return false;
19
20 cond = Condition & 0x00FF0000;
21 cond = cond >> 16;
22 if ((_platform & cond) == 0 && cond != 0x0F)
23 return false;
24 return true;
25 }
26
27 /******************************************************************************
28 * RadioA_1T.TXT
29 ******************************************************************************/
30
31 static u32 Array_RadioA_1T_8188E[] = {
32 0x000, 0x00030000,
33 0x008, 0x00084000,
34 0x018, 0x00000407,
35 0x019, 0x00000012,
36 0x01E, 0x00080009,
37 0x01F, 0x00000880,
38 0x02F, 0x0001A060,
39 0x03F, 0x00000000,
40 0x042, 0x000060C0,
41 0x057, 0x000D0000,
42 0x058, 0x000BE180,
43 0x067, 0x00001552,
44 0x083, 0x00000000,
45 0x0B0, 0x000FF8FC,
46 0x0B1, 0x00054400,
47 0x0B2, 0x000CCC19,
48 0x0B4, 0x00043003,
49 0x0B6, 0x0004953E,
50 0x0B7, 0x0001C718,
51 0x0B8, 0x000060FF,
52 0x0B9, 0x00080001,
53 0x0BA, 0x00040000,
54 0x0BB, 0x00000400,
55 0x0BF, 0x000C0000,
56 0x0C2, 0x00002400,
57 0x0C3, 0x00000009,
58 0x0C4, 0x00040C91,
59 0x0C5, 0x00099999,
60 0x0C6, 0x000000A3,
61 0x0C7, 0x00088820,
62 0x0C8, 0x00076C06,
63 0x0C9, 0x00000000,
64 0x0CA, 0x00080000,
65 0x0DF, 0x00000180,
66 0x0EF, 0x000001A0,
67 0x051, 0x0006B27D,
68 0xFF0F041F, 0xABCD,
69 0x052, 0x0007E4DD,
70 0xCDCDCDCD, 0xCDCD,
71 0x052, 0x0007E49D,
72 0xFF0F041F, 0xDEAD,
73 0x053, 0x00000073,
74 0x056, 0x00051FF3,
75 0x035, 0x00000086,
76 0x035, 0x00000186,
77 0x035, 0x00000286,
78 0x036, 0x00001C25,
79 0x036, 0x00009C25,
80 0x036, 0x00011C25,
81 0x036, 0x00019C25,
82 0x0B6, 0x00048538,
83 0x018, 0x00000C07,
84 0x05A, 0x0004BD00,
85 0x019, 0x000739D0,
86 0x034, 0x0000ADF3,
87 0x034, 0x00009DF0,
88 0x034, 0x00008DED,
89 0x034, 0x00007DEA,
90 0x034, 0x00006DE7,
91 0x034, 0x000054EE,
92 0x034, 0x000044EB,
93 0x034, 0x000034E8,
94 0x034, 0x0000246B,
95 0x034, 0x00001468,
96 0x034, 0x0000006D,
97 0x000, 0x00030159,
98 0x084, 0x00068200,
99 0x086, 0x000000CE,
100 0x087, 0x00048A00,
101 0x08E, 0x00065540,
102 0x08F, 0x00088000,
103 0x0EF, 0x000020A0,
104 0x03B, 0x000F02B0,
105 0x03B, 0x000EF7B0,
106 0x03B, 0x000D4FB0,
107 0x03B, 0x000CF060,
108 0x03B, 0x000B0090,
109 0x03B, 0x000A0080,
110 0x03B, 0x00090080,
111 0x03B, 0x0008F780,
112 0x03B, 0x000722B0,
113 0x03B, 0x0006F7B0,
114 0x03B, 0x00054FB0,
115 0x03B, 0x0004F060,
116 0x03B, 0x00030090,
117 0x03B, 0x00020080,
118 0x03B, 0x00010080,
119 0x03B, 0x0000F780,
120 0x0EF, 0x000000A0,
121 0x000, 0x00010159,
122 0x018, 0x0000F407,
123 0xFFE, 0x00000000,
124 0xFFE, 0x00000000,
125 0x01F, 0x00080003,
126 0xFFE, 0x00000000,
127 0xFFE, 0x00000000,
128 0x01E, 0x00000001,
129 0x01F, 0x00080000,
130 0x000, 0x00033E60,
131 };
132
odm_ConfigRFReg_8188E(struct odm_dm_struct * pDM_Odm,u32 Addr,u32 Data,u32 RegAddr)133 static void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr,
134 u32 Data, u32 RegAddr)
135 {
136 if (Addr == 0xffe) {
137 msleep(50);
138 } else if (Addr == 0xfd) {
139 mdelay(5);
140 } else if (Addr == 0xfc) {
141 mdelay(1);
142 } else if (Addr == 0xfb) {
143 udelay(50);
144 } else if (Addr == 0xfa) {
145 udelay(5);
146 } else if (Addr == 0xf9) {
147 udelay(1);
148 } else {
149 rtl8188e_PHY_SetRFReg(pDM_Odm->Adapter, RegAddr, bRFRegOffsetMask, Data);
150 /* Add 1us delay between BB/RF register setting. */
151 udelay(1);
152 }
153 }
154
odm_ConfigRF_RadioA_8188E(struct odm_dm_struct * pDM_Odm,u32 Addr,u32 Data)155 static void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data)
156 {
157 u32 content = 0x1000; /* RF_Content: radioa_txt */
158 u32 maskforPhySet = (u32)(content & 0xE000);
159
160 odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, Addr | maskforPhySet);
161 }
162
ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct * pDM_Odm)163 int ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *pDM_Odm)
164 {
165 #define READ_NEXT_PAIR(v1, v2, i) do \
166 { i += 2; v1 = Array[i]; \
167 v2 = Array[i + 1]; } while (0)
168
169 u32 hex = 0;
170 u32 i = 0;
171 u32 ArrayLen = ARRAY_SIZE(Array_RadioA_1T_8188E);
172 u32 *Array = Array_RadioA_1T_8188E;
173 bool biol = false;
174 struct adapter *Adapter = pDM_Odm->Adapter;
175 struct xmit_frame *pxmit_frame = NULL;
176 u8 bndy_cnt = 1;
177
178 hex += ODM_ITRF_USB << 8;
179 hex += ODM_CE << 16;
180 hex += 0xFF000000;
181 biol = rtw_IOL_applied(Adapter);
182
183 if (biol) {
184 pxmit_frame = rtw_IOL_accquire_xmit_frame(Adapter);
185 if (!pxmit_frame) {
186 pr_info("rtw_IOL_accquire_xmit_frame failed\n");
187 return -ENOMEM;
188 }
189 }
190
191 for (i = 0; i < ArrayLen; i += 2) {
192 u32 v1 = Array[i];
193 u32 v2 = Array[i + 1];
194
195 /* This (offset, data) pair meets the condition. */
196 if (v1 < 0xCDCDCDCD) {
197 if (biol) {
198 if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
199 bndy_cnt++;
200
201 if (v1 == 0xffe)
202 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
203 else if (v1 == 0xfd)
204 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
205 else if (v1 == 0xfc)
206 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
207 else if (v1 == 0xfb)
208 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
209 else if (v1 == 0xfa)
210 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
211 else if (v1 == 0xf9)
212 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
213 else
214 rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask);
215 } else {
216 odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2);
217 }
218 continue;
219 } else { /* This line is the start line of branch. */
220 if (!CheckCondition(Array[i], hex)) {
221 /* Discard the following (offset, data) pairs. */
222 READ_NEXT_PAIR(v1, v2, i);
223 while (v2 != 0xDEAD &&
224 v2 != 0xCDEF &&
225 v2 != 0xCDCD && i < ArrayLen - 2)
226 READ_NEXT_PAIR(v1, v2, i);
227 i -= 2; /* prevent from for-loop += 2 */
228 } else { /* Configure matched pairs and skip to end of if-else. */
229 READ_NEXT_PAIR(v1, v2, i);
230 while (v2 != 0xDEAD &&
231 v2 != 0xCDEF &&
232 v2 != 0xCDCD && i < ArrayLen - 2) {
233 if (biol) {
234 if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
235 bndy_cnt++;
236
237 if (v1 == 0xffe)
238 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
239 else if (v1 == 0xfd)
240 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
241 else if (v1 == 0xfc)
242 rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
243 else if (v1 == 0xfb)
244 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
245 else if (v1 == 0xfa)
246 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
247 else if (v1 == 0xf9)
248 rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
249 else
250 rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask);
251 } else {
252 odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2);
253 }
254 READ_NEXT_PAIR(v1, v2, i);
255 }
256
257 while (v2 != 0xDEAD && i < ArrayLen - 2)
258 READ_NEXT_PAIR(v1, v2, i);
259 }
260 }
261 }
262 if (biol) {
263 if (!rtl8188e_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
264 pr_info("~~~ IOL Config %s Failed !!!\n", __func__);
265 return -1;
266 }
267 }
268 return 0;
269 }
270