GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / staging / rtlwifi / phydm / rtl8822b / phydm_iqk_8822b.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2016  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25
26 #include "../mp_precomp.h"
27 #include "../phydm_precomp.h"
28
29 /*---------------------------Define Local Constant---------------------------*/
30
31 static bool _iqk_rx_iqk_by_path_8822b(void *, u8);
32
33 static inline void phydm_set_iqk_info(struct phy_dm_struct *dm,
34                                       struct dm_iqk_info *iqk_info, u8 status)
35 {
36         bool KFAIL = true;
37
38         while (1) {
39                 KFAIL = _iqk_rx_iqk_by_path_8822b(dm, ODM_RF_PATH_A);
40                 if (status == 0)
41                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
42                                      "[IQK]S0RXK KFail = 0x%x\n", KFAIL);
43                 else if (status == 1)
44                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
45                                      "[IQK]S1RXK KFail = 0x%x\n", KFAIL);
46                 if (iqk_info->rxiqk_step == 5) {
47                         dm->rf_calibrate_info.iqk_step++;
48                         iqk_info->rxiqk_step = 1;
49                         if (KFAIL && status == 0)
50                                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
51                                              "[IQK]S0RXK fail code: %d!!!\n",
52                                              iqk_info->rxiqk_fail_code
53                                                      [0][ODM_RF_PATH_A]);
54                         else if (KFAIL && status == 1)
55                                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
56                                              "[IQK]S1RXK fail code: %d!!!\n",
57                                              iqk_info->rxiqk_fail_code
58                                                      [0][ODM_RF_PATH_A]);
59                         break;
60                 }
61         }
62
63         iqk_info->kcount++;
64 }
65
66 static inline void phydm_init_iqk_information(struct dm_iqk_info *iqk_info)
67 {
68         u8 i, j, k, m;
69
70         for (i = 0; i < 2; i++) {
71                 iqk_info->iqk_channel[i] = 0x0;
72
73                 for (j = 0; j < SS_8822B; j++) {
74                         iqk_info->lok_idac[i][j] = 0x0;
75                         iqk_info->rxiqk_agc[i][j] = 0x0;
76                         iqk_info->bypass_iqk[i][j] = 0x0;
77
78                         for (k = 0; k < 2; k++) {
79                                 iqk_info->iqk_fail_report[i][j][k] = true;
80                                 for (m = 0; m < 8; m++) {
81                                         iqk_info->iqk_cfir_real[i][j][k][m] =
82                                                 0x0;
83                                         iqk_info->iqk_cfir_imag[i][j][k][m] =
84                                                 0x0;
85                                 }
86                         }
87
88                         for (k = 0; k < 3; k++)
89                                 iqk_info->retry_count[i][j][k] = 0x0;
90                 }
91         }
92 }
93
94 static inline void phydm_backup_iqk_information(struct dm_iqk_info *iqk_info)
95 {
96         u8 i, j, k;
97
98         iqk_info->iqk_channel[1] = iqk_info->iqk_channel[0];
99         for (i = 0; i < 2; i++) {
100                 iqk_info->lok_idac[1][i] = iqk_info->lok_idac[0][i];
101                 iqk_info->rxiqk_agc[1][i] = iqk_info->rxiqk_agc[0][i];
102                 iqk_info->bypass_iqk[1][i] = iqk_info->bypass_iqk[0][i];
103                 iqk_info->rxiqk_fail_code[1][i] =
104                         iqk_info->rxiqk_fail_code[0][i];
105                 for (j = 0; j < 2; j++) {
106                         iqk_info->iqk_fail_report[1][i][j] =
107                                 iqk_info->iqk_fail_report[0][i][j];
108                         for (k = 0; k < 8; k++) {
109                                 iqk_info->iqk_cfir_real[1][i][j][k] =
110                                         iqk_info->iqk_cfir_real[0][i][j][k];
111                                 iqk_info->iqk_cfir_imag[1][i][j][k] =
112                                         iqk_info->iqk_cfir_imag[0][i][j][k];
113                         }
114                 }
115         }
116
117         for (i = 0; i < 4; i++) {
118                 iqk_info->rxiqk_fail_code[0][i] = 0x0;
119                 iqk_info->rxiqk_agc[0][i] = 0x0;
120                 for (j = 0; j < 2; j++) {
121                         iqk_info->iqk_fail_report[0][i][j] = true;
122                         iqk_info->gs_retry_count[0][i][j] = 0x0;
123                 }
124                 for (j = 0; j < 3; j++)
125                         iqk_info->retry_count[0][i][j] = 0x0;
126         }
127 }
128
129 static inline void phydm_set_iqk_cfir(struct phy_dm_struct *dm,
130                                       struct dm_iqk_info *iqk_info, u8 path)
131 {
132         u8 idx, i;
133         u32 tmp;
134
135         for (idx = 0; idx < 2; idx++) {
136                 odm_set_bb_reg(dm, 0x1b00, MASKDWORD, 0xf8000008 | path << 1);
137
138                 if (idx == 0)
139                         odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x3);
140                 else
141                         odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x1);
142
143                 odm_set_bb_reg(dm, 0x1bd4,
144                                BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16),
145                                0x10);
146
147                 for (i = 0; i < 8; i++) {
148                         odm_set_bb_reg(dm, 0x1bd8, MASKDWORD,
149                                        0xe0000001 + (i * 4));
150                         tmp = odm_get_bb_reg(dm, 0x1bfc, MASKDWORD);
151                         iqk_info->iqk_cfir_real[0][path][idx][i] =
152                                 (tmp & 0x0fff0000) >> 16;
153                         iqk_info->iqk_cfir_imag[0][path][idx][i] = tmp & 0xfff;
154                 }
155         }
156 }
157
158 static inline void phydm_get_read_counter(struct phy_dm_struct *dm)
159 {
160         u32 counter = 0x0;
161
162         while (1) {
163                 if (((odm_read_4byte(dm, 0x1bf0) >> 24) == 0x7f) ||
164                     (counter > 300))
165                         break;
166
167                 counter++;
168                 ODM_delay_ms(1);
169         }
170
171         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]counter = %d\n", counter);
172 }
173
174 /*---------------------------Define Local Constant---------------------------*/
175
176 void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value,
177                   u8 threshold)
178 {
179         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
180
181         odm_reset_iqk_result(dm);
182
183         dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
184
185         phy_iq_calibrate_8822b(dm, true);
186 }
187
188 static void _iqk_fill_iqk_report_8822b(void *dm_void, u8 channel)
189 {
190         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
191         struct dm_iqk_info *iqk_info = &dm->IQK_info;
192         u32 tmp1 = 0x0, tmp2 = 0x0, tmp3 = 0x0;
193         u8 i;
194
195         for (i = 0; i < SS_8822B; i++) {
196                 tmp1 = tmp1 +
197                        ((iqk_info->iqk_fail_report[channel][i][TX_IQK] & 0x1)
198                         << i);
199                 tmp2 = tmp2 +
200                        ((iqk_info->iqk_fail_report[channel][i][RX_IQK] & 0x1)
201                         << (i + 4));
202                 tmp3 = tmp3 + ((iqk_info->rxiqk_fail_code[channel][i] & 0x3)
203                                << (i * 2 + 8));
204         }
205         odm_write_4byte(dm, 0x1b00, 0xf8000008);
206         odm_set_bb_reg(dm, 0x1bf0, 0x0000ffff, tmp1 | tmp2 | tmp3);
207
208         for (i = 0; i < 2; i++)
209                 odm_write_4byte(
210                         dm, 0x1be8 + (i * 4),
211                         (iqk_info->rxiqk_agc[channel][(i * 2) + 1] << 16) |
212                                 iqk_info->rxiqk_agc[channel][i * 2]);
213 }
214
215 static void _iqk_backup_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup,
216                                      u32 *BB_backup, u32 *backup_mac_reg,
217                                      u32 *backup_bb_reg)
218 {
219         u32 i;
220
221         for (i = 0; i < MAC_REG_NUM_8822B; i++)
222                 MAC_backup[i] = odm_read_4byte(dm, backup_mac_reg[i]);
223
224         for (i = 0; i < BB_REG_NUM_8822B; i++)
225                 BB_backup[i] = odm_read_4byte(dm, backup_bb_reg[i]);
226 }
227
228 static void _iqk_backup_rf_8822b(struct phy_dm_struct *dm, u32 RF_backup[][2],
229                                  u32 *backup_rf_reg)
230 {
231         u32 i;
232
233         for (i = 0; i < RF_REG_NUM_8822B; i++) {
234                 RF_backup[i][ODM_RF_PATH_A] = odm_get_rf_reg(
235                         dm, ODM_RF_PATH_A, backup_rf_reg[i], RFREGOFFSETMASK);
236                 RF_backup[i][ODM_RF_PATH_B] = odm_get_rf_reg(
237                         dm, ODM_RF_PATH_B, backup_rf_reg[i], RFREGOFFSETMASK);
238         }
239 }
240
241 static void _iqk_agc_bnd_int_8822b(struct phy_dm_struct *dm)
242 {
243         /*initialize RX AGC bnd, it must do after bbreset*/
244         odm_write_4byte(dm, 0x1b00, 0xf8000008);
245         odm_write_4byte(dm, 0x1b00, 0xf80a7008);
246         odm_write_4byte(dm, 0x1b00, 0xf8015008);
247         odm_write_4byte(dm, 0x1b00, 0xf8000008);
248 }
249
250 static void _iqk_bb_reset_8822b(struct phy_dm_struct *dm)
251 {
252         bool cca_ing = false;
253         u32 count = 0;
254
255         odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x0, RFREGOFFSETMASK, 0x10000);
256         odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x0, RFREGOFFSETMASK, 0x10000);
257
258         while (1) {
259                 odm_write_4byte(dm, 0x8fc, 0x0);
260                 odm_set_bb_reg(dm, 0x198c, 0x7, 0x7);
261                 cca_ing = (bool)odm_get_bb_reg(dm, 0xfa0, BIT(3));
262
263                 if (count > 30)
264                         cca_ing = false;
265
266                 if (cca_ing) {
267                         ODM_delay_ms(1);
268                         count++;
269                 } else {
270                         odm_write_1byte(dm, 0x808, 0x0); /*RX ant off*/
271                         odm_set_bb_reg(dm, 0xa04,
272                                        BIT(27) | BIT(26) | BIT(25) | BIT(24),
273                                        0x0); /*CCK RX path off*/
274
275                         /*BBreset*/
276                         odm_set_bb_reg(dm, 0x0, BIT(16), 0x0);
277                         odm_set_bb_reg(dm, 0x0, BIT(16), 0x1);
278
279                         if (odm_get_bb_reg(dm, 0x660, BIT(16)))
280                                 odm_write_4byte(dm, 0x6b4, 0x89000006);
281                         break;
282                 }
283         }
284 }
285
286 static void _iqk_afe_setting_8822b(struct phy_dm_struct *dm, bool do_iqk)
287 {
288         if (do_iqk) {
289                 odm_write_4byte(dm, 0xc60, 0x50000000);
290                 odm_write_4byte(dm, 0xc60, 0x70070040);
291                 odm_write_4byte(dm, 0xe60, 0x50000000);
292                 odm_write_4byte(dm, 0xe60, 0x70070040);
293
294                 odm_write_4byte(dm, 0xc58, 0xd8000402);
295                 odm_write_4byte(dm, 0xc5c, 0xd1000120);
296                 odm_write_4byte(dm, 0xc6c, 0x00000a15);
297                 odm_write_4byte(dm, 0xe58, 0xd8000402);
298                 odm_write_4byte(dm, 0xe5c, 0xd1000120);
299                 odm_write_4byte(dm, 0xe6c, 0x00000a15);
300                 _iqk_bb_reset_8822b(dm);
301         } else {
302                 odm_write_4byte(dm, 0xc60, 0x50000000);
303                 odm_write_4byte(dm, 0xc60, 0x70038040);
304                 odm_write_4byte(dm, 0xe60, 0x50000000);
305                 odm_write_4byte(dm, 0xe60, 0x70038040);
306
307                 odm_write_4byte(dm, 0xc58, 0xd8020402);
308                 odm_write_4byte(dm, 0xc5c, 0xde000120);
309                 odm_write_4byte(dm, 0xc6c, 0x0000122a);
310                 odm_write_4byte(dm, 0xe58, 0xd8020402);
311                 odm_write_4byte(dm, 0xe5c, 0xde000120);
312                 odm_write_4byte(dm, 0xe6c, 0x0000122a);
313         }
314 }
315
316 static void _iqk_restore_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup,
317                                       u32 *BB_backup, u32 *backup_mac_reg,
318                                       u32 *backup_bb_reg)
319 {
320         u32 i;
321
322         for (i = 0; i < MAC_REG_NUM_8822B; i++)
323                 odm_write_4byte(dm, backup_mac_reg[i], MAC_backup[i]);
324         for (i = 0; i < BB_REG_NUM_8822B; i++)
325                 odm_write_4byte(dm, backup_bb_reg[i], BB_backup[i]);
326 }
327
328 static void _iqk_restore_rf_8822b(struct phy_dm_struct *dm, u32 *backup_rf_reg,
329                                   u32 RF_backup[][2])
330 {
331         u32 i;
332
333         odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, RFREGOFFSETMASK, 0x0);
334         odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, RFREGOFFSETMASK, 0x0);
335         /*0xdf[4]=0*/
336         odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xdf, RFREGOFFSETMASK,
337                        RF_backup[0][ODM_RF_PATH_A] & (~BIT(4)));
338         odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xdf, RFREGOFFSETMASK,
339                        RF_backup[0][ODM_RF_PATH_B] & (~BIT(4)));
340
341         for (i = 1; i < RF_REG_NUM_8822B; i++) {
342                 odm_set_rf_reg(dm, ODM_RF_PATH_A, backup_rf_reg[i],
343                                RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_A]);
344                 odm_set_rf_reg(dm, ODM_RF_PATH_B, backup_rf_reg[i],
345                                RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_B]);
346         }
347 }
348
349 static void _iqk_backup_iqk_8822b(struct phy_dm_struct *dm, u8 step)
350 {
351         struct dm_iqk_info *iqk_info = &dm->IQK_info;
352         u8 path;
353         u16 iqk_apply[2] = {0xc94, 0xe94};
354
355         if (step == 0x0) {
356                 phydm_backup_iqk_information(iqk_info);
357         } else {
358                 iqk_info->iqk_channel[0] = iqk_info->rf_reg18;
359                 for (path = 0; path < 2; path++) {
360                         iqk_info->lok_idac[0][path] =
361                                 odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
362                                                0x58, RFREGOFFSETMASK);
363                         iqk_info->bypass_iqk[0][path] =
364                                 odm_get_bb_reg(dm, iqk_apply[path], MASKDWORD);
365
366                         phydm_set_iqk_cfir(dm, iqk_info, path);
367                         odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0);
368                         odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0);
369                 }
370         }
371 }
372
373 static void _iqk_reload_iqk_setting_8822b(
374         struct phy_dm_struct *dm, u8 channel,
375         u8 reload_idx /*1: reload TX, 2: reload LO, TX, RX*/
376         )
377 {
378         struct dm_iqk_info *iqk_info = &dm->IQK_info;
379         u8 i, path, idx;
380         u16 iqk_apply[2] = {0xc94, 0xe94};
381
382         for (path = 0; path < 2; path++) {
383                 if (reload_idx == 2) {
384                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
385                                        BIT(4), 0x1);
386                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x58,
387                                        RFREGOFFSETMASK,
388                                        iqk_info->lok_idac[channel][path]);
389                 }
390
391                 for (idx = 0; idx < reload_idx; idx++) {
392                         odm_set_bb_reg(dm, 0x1b00, MASKDWORD,
393                                        0xf8000008 | path << 1);
394                         odm_set_bb_reg(dm, 0x1b2c, MASKDWORD, 0x7);
395                         odm_set_bb_reg(dm, 0x1b38, MASKDWORD, 0x20000000);
396                         odm_set_bb_reg(dm, 0x1b3c, MASKDWORD, 0x20000000);
397                         odm_set_bb_reg(dm, 0x1bcc, MASKDWORD, 0x00000000);
398
399                         if (idx == 0)
400                                 odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12),
401                                                0x3);
402                         else
403                                 odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12),
404                                                0x1);
405
406                         odm_set_bb_reg(dm, 0x1bd4, BIT(20) | BIT(19) | BIT(18) |
407                                                            BIT(17) | BIT(16),
408                                        0x10);
409
410                         for (i = 0; i < 8; i++) {
411                                 odm_write_4byte(
412                                         dm, 0x1bd8,
413                                         ((0xc0000000 >> idx) + 0x3) + (i * 4) +
414                                                 (iqk_info->iqk_cfir_real
415                                                          [channel][path][idx][i]
416                                                  << 9));
417                                 odm_write_4byte(
418                                         dm, 0x1bd8,
419                                         ((0xc0000000 >> idx) + 0x1) + (i * 4) +
420                                                 (iqk_info->iqk_cfir_imag
421                                                          [channel][path][idx][i]
422                                                  << 9));
423                         }
424                 }
425                 odm_set_bb_reg(dm, iqk_apply[path], MASKDWORD,
426                                iqk_info->bypass_iqk[channel][path]);
427
428                 odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0);
429                 odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0);
430         }
431 }
432
433 static bool _iqk_reload_iqk_8822b(struct phy_dm_struct *dm, bool reset)
434 {
435         struct dm_iqk_info *iqk_info = &dm->IQK_info;
436         u8 i;
437         bool reload = false;
438
439         if (reset) {
440                 for (i = 0; i < 2; i++)
441                         iqk_info->iqk_channel[i] = 0x0;
442         } else {
443                 iqk_info->rf_reg18 = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18,
444                                                     RFREGOFFSETMASK);
445
446                 for (i = 0; i < 2; i++) {
447                         if (iqk_info->rf_reg18 == iqk_info->iqk_channel[i]) {
448                                 _iqk_reload_iqk_setting_8822b(dm, i, 2);
449                                 _iqk_fill_iqk_report_8822b(dm, i);
450                                 ODM_RT_TRACE(
451                                         dm, ODM_COMP_CALIBRATION,
452                                         "[IQK]reload IQK result before!!!!\n");
453                                 reload = true;
454                         }
455                 }
456         }
457         return reload;
458 }
459
460 static void _iqk_rfe_setting_8822b(struct phy_dm_struct *dm, bool ext_pa_on)
461 {
462         if (ext_pa_on) {
463                 /*RFE setting*/
464                 odm_write_4byte(dm, 0xcb0, 0x77777777);
465                 odm_write_4byte(dm, 0xcb4, 0x00007777);
466                 odm_write_4byte(dm, 0xcbc, 0x0000083B);
467                 odm_write_4byte(dm, 0xeb0, 0x77777777);
468                 odm_write_4byte(dm, 0xeb4, 0x00007777);
469                 odm_write_4byte(dm, 0xebc, 0x0000083B);
470                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
471                              "[IQK]external PA on!!!!\n");
472         } else {
473                 /*RFE setting*/
474                 odm_write_4byte(dm, 0xcb0, 0x77777777);
475                 odm_write_4byte(dm, 0xcb4, 0x00007777);
476                 odm_write_4byte(dm, 0xcbc, 0x00000100);
477                 odm_write_4byte(dm, 0xeb0, 0x77777777);
478                 odm_write_4byte(dm, 0xeb4, 0x00007777);
479                 odm_write_4byte(dm, 0xebc, 0x00000100);
480         }
481 }
482
483 static void _iqk_rf_setting_8822b(struct phy_dm_struct *dm)
484 {
485         u8 path;
486         u32 tmp;
487
488         odm_write_4byte(dm, 0x1b00, 0xf8000008);
489         odm_write_4byte(dm, 0x1bb8, 0x00000000);
490
491         for (path = 0; path < 2; path++) {
492                 /*0xdf:B11 = 1,B4 = 0, B1 = 1*/
493                 tmp = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
494                                      RFREGOFFSETMASK);
495                 tmp = (tmp & (~BIT(4))) | BIT(1) | BIT(11);
496                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
497                                RFREGOFFSETMASK, tmp);
498
499                 /*release 0x56 TXBB*/
500                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x65,
501                                RFREGOFFSETMASK, 0x09000);
502
503                 if (*dm->band_type == ODM_BAND_5G) {
504                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
505                                        BIT(19), 0x1);
506                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
507                                        RFREGOFFSETMASK, 0x00026);
508                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e,
509                                        RFREGOFFSETMASK, 0x00037);
510                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f,
511                                        RFREGOFFSETMASK, 0xdefce);
512                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
513                                        BIT(19), 0x0);
514                 } else {
515                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
516                                        BIT(19), 0x1);
517                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
518                                        RFREGOFFSETMASK, 0x00026);
519                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e,
520                                        RFREGOFFSETMASK, 0x00037);
521                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f,
522                                        RFREGOFFSETMASK, 0x5efce);
523                         odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
524                                        BIT(19), 0x0);
525                 }
526         }
527 }
528
529 static void _iqk_configure_macbb_8822b(struct phy_dm_struct *dm)
530 {
531         /*MACBB register setting*/
532         odm_write_1byte(dm, 0x522, 0x7f);
533         odm_set_bb_reg(dm, 0x550, BIT(11) | BIT(3), 0x0);
534         odm_set_bb_reg(dm, 0x90c, BIT(15),
535                        0x1); /*0x90c[15]=1: dac_buf reset selection*/
536         odm_set_bb_reg(dm, 0x9a4, BIT(31),
537                        0x0); /*0x9a4[31]=0: Select da clock*/
538         /*0xc94[0]=1, 0xe94[0]=1: let tx through iqk*/
539         odm_set_bb_reg(dm, 0xc94, BIT(0), 0x1);
540         odm_set_bb_reg(dm, 0xe94, BIT(0), 0x1);
541         /* 3-wire off*/
542         odm_write_4byte(dm, 0xc00, 0x00000004);
543         odm_write_4byte(dm, 0xe00, 0x00000004);
544 }
545
546 static void _iqk_lok_setting_8822b(struct phy_dm_struct *dm, u8 path)
547 {
548         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
549         odm_write_4byte(dm, 0x1bcc, 0x9);
550         odm_write_1byte(dm, 0x1b23, 0x00);
551
552         switch (*dm->band_type) {
553         case ODM_BAND_2_4G:
554                 odm_write_1byte(dm, 0x1b2b, 0x00);
555                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
556                                RFREGOFFSETMASK, 0x50df2);
557                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
558                                RFREGOFFSETMASK, 0xadc00);
559                 /* WE_LUT_TX_LOK*/
560                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4),
561                                0x1);
562                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
563                                BIT(1) | BIT(0), 0x0);
564                 break;
565         case ODM_BAND_5G:
566                 odm_write_1byte(dm, 0x1b2b, 0x80);
567                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
568                                RFREGOFFSETMASK, 0x5086c);
569                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
570                                RFREGOFFSETMASK, 0xa9c00);
571                 /* WE_LUT_TX_LOK*/
572                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4),
573                                0x1);
574                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
575                                BIT(1) | BIT(0), 0x1);
576                 break;
577         }
578 }
579
580 static void _iqk_txk_setting_8822b(struct phy_dm_struct *dm, u8 path)
581 {
582         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
583         odm_write_4byte(dm, 0x1bcc, 0x9);
584         odm_write_4byte(dm, 0x1b20, 0x01440008);
585
586         if (path == 0x0)
587                 odm_write_4byte(dm, 0x1b00, 0xf800000a);
588         else
589                 odm_write_4byte(dm, 0x1b00, 0xf8000008);
590         odm_write_4byte(dm, 0x1bcc, 0x3f);
591
592         switch (*dm->band_type) {
593         case ODM_BAND_2_4G:
594                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
595                                RFREGOFFSETMASK, 0x50df2);
596                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
597                                RFREGOFFSETMASK, 0xadc00);
598                 odm_write_1byte(dm, 0x1b2b, 0x00);
599                 break;
600         case ODM_BAND_5G:
601                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
602                                RFREGOFFSETMASK, 0x500ef);
603                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
604                                RFREGOFFSETMASK, 0xa9c00);
605                 odm_write_1byte(dm, 0x1b2b, 0x80);
606                 break;
607         }
608 }
609
610 static void _iqk_rxk1_setting_8822b(struct phy_dm_struct *dm, u8 path)
611 {
612         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
613
614         switch (*dm->band_type) {
615         case ODM_BAND_2_4G:
616                 odm_write_1byte(dm, 0x1bcc, 0x9);
617                 odm_write_1byte(dm, 0x1b2b, 0x00);
618                 odm_write_4byte(dm, 0x1b20, 0x01450008);
619                 odm_write_4byte(dm, 0x1b24, 0x01460c88);
620                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
621                                RFREGOFFSETMASK, 0x510e0);
622                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
623                                RFREGOFFSETMASK, 0xacc00);
624                 break;
625         case ODM_BAND_5G:
626                 odm_write_1byte(dm, 0x1bcc, 0x09);
627                 odm_write_1byte(dm, 0x1b2b, 0x80);
628                 odm_write_4byte(dm, 0x1b20, 0x00850008);
629                 odm_write_4byte(dm, 0x1b24, 0x00460048);
630                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
631                                RFREGOFFSETMASK, 0x510e0);
632                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
633                                RFREGOFFSETMASK, 0xadc00);
634                 break;
635         }
636 }
637
638 static void _iqk_rxk2_setting_8822b(struct phy_dm_struct *dm, u8 path,
639                                     bool is_gs)
640 {
641         struct dm_iqk_info *iqk_info = &dm->IQK_info;
642
643         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
644
645         switch (*dm->band_type) {
646         case ODM_BAND_2_4G:
647                 if (is_gs)
648                         iqk_info->tmp1bcc = 0x12;
649                 odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc);
650                 odm_write_1byte(dm, 0x1b2b, 0x00);
651                 odm_write_4byte(dm, 0x1b20, 0x01450008);
652                 odm_write_4byte(dm, 0x1b24, 0x01460848);
653                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
654                                RFREGOFFSETMASK, 0x510e0);
655                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
656                                RFREGOFFSETMASK, 0xa9c00);
657                 break;
658         case ODM_BAND_5G:
659                 if (is_gs) {
660                         if (path == ODM_RF_PATH_A)
661                                 iqk_info->tmp1bcc = 0x12;
662                         else
663                                 iqk_info->tmp1bcc = 0x09;
664                 }
665                 odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc);
666                 odm_write_1byte(dm, 0x1b2b, 0x80);
667                 odm_write_4byte(dm, 0x1b20, 0x00850008);
668                 odm_write_4byte(dm, 0x1b24, 0x00460848);
669                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
670                                RFREGOFFSETMASK, 0x51060);
671                 odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
672                                RFREGOFFSETMASK, 0xa9c00);
673                 break;
674         }
675 }
676
677 static bool _iqk_check_cal_8822b(struct phy_dm_struct *dm, u32 IQK_CMD)
678 {
679         bool notready = true, fail = true;
680         u32 delay_count = 0x0;
681
682         while (notready) {
683                 if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) {
684                         fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26));
685                         notready = false;
686                 } else {
687                         ODM_delay_ms(1);
688                         delay_count++;
689                 }
690
691                 if (delay_count >= 50) {
692                         fail = true;
693                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
694                                      "[IQK]IQK timeout!!!\n");
695                         break;
696                 }
697         }
698         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay count = 0x%x!!!\n",
699                      delay_count);
700         return fail;
701 }
702
703 static bool _iqk_rx_iqk_gain_search_fail_8822b(struct phy_dm_struct *dm,
704                                                u8 path, u8 step)
705 {
706         struct dm_iqk_info *iqk_info = &dm->IQK_info;
707         bool fail = true;
708         u32 IQK_CMD = 0x0, rf_reg0, tmp, bb_idx;
709         u8 IQMUX[4] = {0x9, 0x12, 0x1b, 0x24};
710         u8 idx;
711
712         for (idx = 0; idx < 4; idx++)
713                 if (iqk_info->tmp1bcc == IQMUX[idx])
714                         break;
715
716         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
717         odm_write_4byte(dm, 0x1bcc, iqk_info->tmp1bcc);
718
719         if (step == RXIQK1)
720                 ODM_RT_TRACE(
721                         dm, ODM_COMP_CALIBRATION,
722                         "[IQK]============ S%d RXIQK GainSearch ============\n",
723                         path);
724
725         if (step == RXIQK1)
726                 IQK_CMD = 0xf8000208 | (1 << (path + 4));
727         else
728                 IQK_CMD = 0xf8000308 | (1 << (path + 4));
729
730         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]S%d GS%d_Trigger = 0x%x\n",
731                      path, step, IQK_CMD);
732
733         odm_write_4byte(dm, 0x1b00, IQK_CMD);
734         odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1);
735         ODM_delay_ms(GS_delay_8822B);
736         fail = _iqk_check_cal_8822b(dm, IQK_CMD);
737
738         if (step == RXIQK2) {
739                 rf_reg0 = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0x0,
740                                          RFREGOFFSETMASK);
741                 odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
742                 ODM_RT_TRACE(
743                         dm, ODM_COMP_CALIBRATION,
744                         "[IQK]S%d ==> RF0x0 = 0x%x, tmp1bcc = 0x%x, idx = %d, 0x1b3c = 0x%x\n",
745                         path, rf_reg0, iqk_info->tmp1bcc, idx,
746                         odm_read_4byte(dm, 0x1b3c));
747                 tmp = (rf_reg0 & 0x1fe0) >> 5;
748                 iqk_info->lna_idx = tmp >> 5;
749                 bb_idx = tmp & 0x1f;
750                 if (bb_idx == 0x1) {
751                         if (iqk_info->lna_idx != 0x0)
752                                 iqk_info->lna_idx--;
753                         else if (idx != 3)
754                                 idx++;
755                         else
756                                 iqk_info->isbnd = true;
757                         fail = true;
758                 } else if (bb_idx == 0xa) {
759                         if (idx != 0)
760                                 idx--;
761                         else if (iqk_info->lna_idx != 0x7)
762                                 iqk_info->lna_idx++;
763                         else
764                                 iqk_info->isbnd = true;
765                         fail = true;
766                 } else {
767                         fail = false;
768                 }
769
770                 if (iqk_info->isbnd)
771                         fail = false;
772
773                 iqk_info->tmp1bcc = IQMUX[idx];
774
775                 if (fail) {
776                         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
777                         odm_write_4byte(
778                                 dm, 0x1b24,
779                                 (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) |
780                                         (iqk_info->lna_idx << 10));
781                 }
782         }
783
784         return fail;
785 }
786
787 static bool _lok_one_shot_8822b(void *dm_void, u8 path)
788 {
789         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
790         struct dm_iqk_info *iqk_info = &dm->IQK_info;
791         u8 delay_count = 0;
792         bool LOK_notready = false;
793         u32 LOK_temp = 0;
794         u32 IQK_CMD = 0x0;
795
796         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
797                      "[IQK]==========S%d LOK ==========\n", path);
798
799         IQK_CMD = 0xf8000008 | (1 << (4 + path));
800
801         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]LOK_Trigger = 0x%x\n",
802                      IQK_CMD);
803
804         odm_write_4byte(dm, 0x1b00, IQK_CMD);
805         odm_write_4byte(dm, 0x1b00, IQK_CMD + 1);
806         /*LOK: CMD ID = 0       {0xf8000018, 0xf8000028}*/
807         /*LOK: CMD ID = 0       {0xf8000019, 0xf8000029}*/
808         ODM_delay_ms(LOK_delay_8822B);
809
810         delay_count = 0;
811         LOK_notready = true;
812
813         while (LOK_notready) {
814                 if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f))
815                         LOK_notready = false;
816                 else
817                         LOK_notready = true;
818
819                 if (LOK_notready) {
820                         ODM_delay_ms(1);
821                         delay_count++;
822                 }
823
824                 if (delay_count >= 50) {
825                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
826                                      "[IQK]S%d LOK timeout!!!\n", path);
827                         break;
828                 }
829         }
830
831         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
832                      "[IQK]S%d ==> delay_count = 0x%x\n", path, delay_count);
833         if (ODM_COMP_CALIBRATION) {
834                 if (!LOK_notready) {
835                         LOK_temp =
836                                 odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
837                                                0x58, RFREGOFFSETMASK);
838                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
839                                      "[IQK]0x58 = 0x%x\n", LOK_temp);
840                 } else {
841                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
842                                      "[IQK]==>S%d LOK Fail!!!\n", path);
843                 }
844         }
845         iqk_info->lok_fail[path] = LOK_notready;
846         return LOK_notready;
847 }
848
849 static bool _iqk_one_shot_8822b(void *dm_void, u8 path, u8 idx)
850 {
851         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
852         struct dm_iqk_info *iqk_info = &dm->IQK_info;
853         u8 delay_count = 0;
854         bool notready = true, fail = true;
855         u32 IQK_CMD = 0x0;
856         u16 iqk_apply[2] = {0xc94, 0xe94};
857
858         if (idx == TXIQK)
859                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
860                              "[IQK]============ S%d WBTXIQK ============\n",
861                              path);
862         else if (idx == RXIQK1)
863                 ODM_RT_TRACE(
864                         dm, ODM_COMP_CALIBRATION,
865                         "[IQK]============ S%d WBRXIQK STEP1============\n",
866                         path);
867         else
868                 ODM_RT_TRACE(
869                         dm, ODM_COMP_CALIBRATION,
870                         "[IQK]============ S%d WBRXIQK STEP2============\n",
871                         path);
872
873         if (idx == TXIQK) {
874                 IQK_CMD = 0xf8000008 | ((*dm->band_width + 4) << 8) |
875                           (1 << (path + 4));
876                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
877                              "[IQK]TXK_Trigger = 0x%x\n", IQK_CMD);
878                 /*{0xf8000418, 0xf800042a} ==> 20 WBTXK (CMD = 4)*/
879                 /*{0xf8000518, 0xf800052a} ==> 40 WBTXK (CMD = 5)*/
880                 /*{0xf8000618, 0xf800062a} ==> 80 WBTXK (CMD = 6)*/
881         } else if (idx == RXIQK1) {
882                 if (*dm->band_width == 2)
883                         IQK_CMD = 0xf8000808 | (1 << (path + 4));
884                 else
885                         IQK_CMD = 0xf8000708 | (1 << (path + 4));
886                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
887                              "[IQK]RXK1_Trigger = 0x%x\n", IQK_CMD);
888                 /*{0xf8000718, 0xf800072a} ==> 20 WBTXK (CMD = 7)*/
889                 /*{0xf8000718, 0xf800072a} ==> 40 WBTXK (CMD = 7)*/
890                 /*{0xf8000818, 0xf800082a} ==> 80 WBTXK (CMD = 8)*/
891         } else if (idx == RXIQK2) {
892                 IQK_CMD = 0xf8000008 | ((*dm->band_width + 9) << 8) |
893                           (1 << (path + 4));
894                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
895                              "[IQK]RXK2_Trigger = 0x%x\n", IQK_CMD);
896                 /*{0xf8000918, 0xf800092a} ==> 20 WBRXK (CMD = 9)*/
897                 /*{0xf8000a18, 0xf8000a2a} ==> 40 WBRXK (CMD = 10)*/
898                 /*{0xf8000b18, 0xf8000b2a} ==> 80 WBRXK (CMD = 11)*/
899                 odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
900                 odm_write_4byte(dm, 0x1b24,
901                                 (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) |
902                                         ((iqk_info->lna_idx & 0x7) << 10));
903         }
904         odm_write_4byte(dm, 0x1b00, IQK_CMD);
905         odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1);
906         ODM_delay_ms(WBIQK_delay_8822B);
907
908         while (notready) {
909                 if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f))
910                         notready = false;
911                 else
912                         notready = true;
913
914                 if (notready) {
915                         ODM_delay_ms(1);
916                         delay_count++;
917                 } else {
918                         fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26));
919                         break;
920                 }
921
922                 if (delay_count >= 50) {
923                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
924                                      "[IQK]S%d IQK timeout!!!\n", path);
925                         break;
926                 }
927         }
928
929         if (dm->debug_components & ODM_COMP_CALIBRATION) {
930                 odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
931                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
932                              "[IQK]S%d ==> 0x1b00 = 0x%x, 0x1b08 = 0x%x\n",
933                              path, odm_read_4byte(dm, 0x1b00),
934                              odm_read_4byte(dm, 0x1b08));
935                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
936                              "[IQK]S%d ==> delay_count = 0x%x\n", path,
937                              delay_count);
938                 if (idx != TXIQK)
939                         ODM_RT_TRACE(
940                                 dm, ODM_COMP_CALIBRATION,
941                                 "[IQK]S%d ==> RF0x0 = 0x%x, RF0x56 = 0x%x\n",
942                                 path,
943                                 odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
944                                                0x0, RFREGOFFSETMASK),
945                                 odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
946                                                0x56, RFREGOFFSETMASK));
947         }
948
949         odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
950
951         if (idx == TXIQK)
952                 if (fail)
953                         odm_set_bb_reg(dm, iqk_apply[path], BIT(0), 0x0);
954
955         if (idx == RXIQK2) {
956                 iqk_info->rxiqk_agc[0][path] =
957                         (u16)(((odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
958                                                0x0, RFREGOFFSETMASK) >>
959                                 5) &
960                                0xff) |
961                               (iqk_info->tmp1bcc << 8));
962
963                 odm_write_4byte(dm, 0x1b38, 0x20000000);
964
965                 if (!fail)
966                         odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)),
967                                        0x1);
968                 else
969                         odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)),
970                                        0x0);
971         }
972
973         if (idx == TXIQK)
974                 iqk_info->iqk_fail_report[0][path][TXIQK] = fail;
975         else
976                 iqk_info->iqk_fail_report[0][path][RXIQK] = fail;
977
978         return fail;
979 }
980
981 static bool _iqk_rx_iqk_by_path_8822b(void *dm_void, u8 path)
982 {
983         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
984         struct dm_iqk_info *iqk_info = &dm->IQK_info;
985         bool KFAIL = true, gonext;
986
987         switch (iqk_info->rxiqk_step) {
988         case 1: /*gain search_RXK1*/
989                 _iqk_rxk1_setting_8822b(dm, path);
990                 gonext = false;
991                 while (1) {
992                         KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path,
993                                                                    RXIQK1);
994                         if (KFAIL &&
995                             (iqk_info->gs_retry_count[0][path][GSRXK1] < 2))
996                                 iqk_info->gs_retry_count[0][path][GSRXK1]++;
997                         else if (KFAIL) {
998                                 iqk_info->rxiqk_fail_code[0][path] = 0;
999                                 iqk_info->rxiqk_step = 5;
1000                                 gonext = true;
1001                         } else {
1002                                 iqk_info->rxiqk_step++;
1003                                 gonext = true;
1004                         }
1005                         if (gonext)
1006                                 break;
1007                 }
1008                 break;
1009         case 2: /*gain search_RXK2*/
1010                 _iqk_rxk2_setting_8822b(dm, path, true);
1011                 iqk_info->isbnd = false;
1012                 while (1) {
1013                         KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path,
1014                                                                    RXIQK2);
1015                         if (KFAIL &&
1016                             (iqk_info->gs_retry_count[0][path][GSRXK2] <
1017                              rxiqk_gs_limit)) {
1018                                 iqk_info->gs_retry_count[0][path][GSRXK2]++;
1019                         } else {
1020                                 iqk_info->rxiqk_step++;
1021                                 break;
1022                         }
1023                 }
1024                 break;
1025         case 3: /*RXK1*/
1026                 _iqk_rxk1_setting_8822b(dm, path);
1027                 gonext = false;
1028                 while (1) {
1029                         KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK1);
1030                         if (KFAIL &&
1031                             (iqk_info->retry_count[0][path][RXIQK1] < 2))
1032                                 iqk_info->retry_count[0][path][RXIQK1]++;
1033                         else if (KFAIL) {
1034                                 iqk_info->rxiqk_fail_code[0][path] = 1;
1035                                 iqk_info->rxiqk_step = 5;
1036                                 gonext = true;
1037                         } else {
1038                                 iqk_info->rxiqk_step++;
1039                                 gonext = true;
1040                         }
1041                         if (gonext)
1042                                 break;
1043                 }
1044                 break;
1045         case 4: /*RXK2*/
1046                 _iqk_rxk2_setting_8822b(dm, path, false);
1047                 gonext = false;
1048                 while (1) {
1049                         KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK2);
1050                         if (KFAIL &&
1051                             (iqk_info->retry_count[0][path][RXIQK2] < 2))
1052                                 iqk_info->retry_count[0][path][RXIQK2]++;
1053                         else if (KFAIL) {
1054                                 iqk_info->rxiqk_fail_code[0][path] = 2;
1055                                 iqk_info->rxiqk_step = 5;
1056                                 gonext = true;
1057                         } else {
1058                                 iqk_info->rxiqk_step++;
1059                                 gonext = true;
1060                         }
1061                         if (gonext)
1062                                 break;
1063                 }
1064                 break;
1065         }
1066         return KFAIL;
1067 }
1068
1069 static void _iqk_iqk_by_path_8822b(void *dm_void, bool segment_iqk)
1070 {
1071         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1072         struct dm_iqk_info *iqk_info = &dm->IQK_info;
1073         bool KFAIL = true;
1074         u8 i, kcount_limit;
1075
1076         if (*dm->band_width == 2)
1077                 kcount_limit = kcount_limit_80m;
1078         else
1079                 kcount_limit = kcount_limit_others;
1080
1081         while (1) {
1082                 switch (dm->rf_calibrate_info.iqk_step) {
1083                 case 1: /*S0 LOK*/
1084                         _iqk_lok_setting_8822b(dm, ODM_RF_PATH_A);
1085                         _lok_one_shot_8822b(dm, ODM_RF_PATH_A);
1086                         dm->rf_calibrate_info.iqk_step++;
1087                         break;
1088                 case 2: /*S1 LOK*/
1089                         _iqk_lok_setting_8822b(dm, ODM_RF_PATH_B);
1090                         _lok_one_shot_8822b(dm, ODM_RF_PATH_B);
1091                         dm->rf_calibrate_info.iqk_step++;
1092                         break;
1093                 case 3: /*S0 TXIQK*/
1094                         _iqk_txk_setting_8822b(dm, ODM_RF_PATH_A);
1095                         KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_A, TXIQK);
1096                         iqk_info->kcount++;
1097                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1098                                      "[IQK]S0TXK KFail = 0x%x\n", KFAIL);
1099
1100                         if (KFAIL &&
1101                             (iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK] <
1102                              3))
1103                                 iqk_info->retry_count[0][ODM_RF_PATH_A]
1104                                                      [TXIQK]++;
1105                         else
1106                                 dm->rf_calibrate_info.iqk_step++;
1107                         break;
1108                 case 4: /*S1 TXIQK*/
1109                         _iqk_txk_setting_8822b(dm, ODM_RF_PATH_B);
1110                         KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_B, TXIQK);
1111                         iqk_info->kcount++;
1112                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1113                                      "[IQK]S1TXK KFail = 0x%x\n", KFAIL);
1114                         if (KFAIL &&
1115                             iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK] < 3)
1116                                 iqk_info->retry_count[0][ODM_RF_PATH_B]
1117                                                      [TXIQK]++;
1118                         else
1119                                 dm->rf_calibrate_info.iqk_step++;
1120                         break;
1121                 case 5: /*S0 RXIQK*/
1122                         phydm_set_iqk_info(dm, iqk_info, 0);
1123                         break;
1124                 case 6: /*S1 RXIQK*/
1125                         phydm_set_iqk_info(dm, iqk_info, 1);
1126                         break;
1127                 }
1128
1129                 if (dm->rf_calibrate_info.iqk_step == 7) {
1130                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1131                                      "[IQK]==========LOK summary ==========\n");
1132                         ODM_RT_TRACE(
1133                                 dm, ODM_COMP_CALIBRATION,
1134                                 "[IQK]PathA_LOK_notready = %d, PathB_LOK1_notready = %d\n",
1135                                 iqk_info->lok_fail[ODM_RF_PATH_A],
1136                                 iqk_info->lok_fail[ODM_RF_PATH_B]);
1137                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1138                                      "[IQK]==========IQK summary ==========\n");
1139                         ODM_RT_TRACE(
1140                                 dm, ODM_COMP_CALIBRATION,
1141                                 "[IQK]PathA_TXIQK_fail = %d, PathB_TXIQK_fail = %d\n",
1142                                 iqk_info->iqk_fail_report[0][ODM_RF_PATH_A]
1143                                                          [TXIQK],
1144                                 iqk_info->iqk_fail_report[0][ODM_RF_PATH_B]
1145                                                          [TXIQK]);
1146                         ODM_RT_TRACE(
1147                                 dm, ODM_COMP_CALIBRATION,
1148                                 "[IQK]PathA_RXIQK_fail = %d, PathB_RXIQK_fail = %d\n",
1149                                 iqk_info->iqk_fail_report[0][ODM_RF_PATH_A]
1150                                                          [RXIQK],
1151                                 iqk_info->iqk_fail_report[0][ODM_RF_PATH_B]
1152                                                          [RXIQK]);
1153                         ODM_RT_TRACE(
1154                                 dm, ODM_COMP_CALIBRATION,
1155                                 "[IQK]PathA_TXIQK_retry = %d, PathB_TXIQK_retry = %d\n",
1156                                 iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK],
1157                                 iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK]);
1158                         ODM_RT_TRACE(
1159                                 dm, ODM_COMP_CALIBRATION,
1160                                 "[IQK]PathA_RXK1_retry = %d, PathA_RXK2_retry = %d, PathB_RXK1_retry = %d, PathB_RXK2_retry = %d\n",
1161                                 iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK1],
1162                                 iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK2],
1163                                 iqk_info->retry_count[0][ODM_RF_PATH_B][RXIQK1],
1164                                 iqk_info->retry_count[0][ODM_RF_PATH_B]
1165                                                      [RXIQK2]);
1166                         ODM_RT_TRACE(
1167                                 dm, ODM_COMP_CALIBRATION,
1168                                 "[IQK]PathA_GS1_retry = %d, PathA_GS2_retry = %d, PathB_GS1_retry = %d, PathB_GS2_retry = %d\n",
1169                                 iqk_info->gs_retry_count[0][ODM_RF_PATH_A]
1170                                                         [GSRXK1],
1171                                 iqk_info->gs_retry_count[0][ODM_RF_PATH_A]
1172                                                         [GSRXK2],
1173                                 iqk_info->gs_retry_count[0][ODM_RF_PATH_B]
1174                                                         [GSRXK1],
1175                                 iqk_info->gs_retry_count[0][ODM_RF_PATH_B]
1176                                                         [GSRXK2]);
1177                         for (i = 0; i < 2; i++) {
1178                                 odm_write_4byte(dm, 0x1b00,
1179                                                 0xf8000008 | i << 1);
1180                                 odm_write_4byte(dm, 0x1b2c, 0x7);
1181                                 odm_write_4byte(dm, 0x1bcc, 0x0);
1182                         }
1183                         break;
1184                 }
1185
1186                 if (segment_iqk && (iqk_info->kcount == kcount_limit))
1187                         break;
1188         }
1189 }
1190
1191 static void _iqk_start_iqk_8822b(struct phy_dm_struct *dm, bool segment_iqk)
1192 {
1193         u32 tmp;
1194
1195         /*GNT_WL = 1*/
1196         tmp = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK);
1197         tmp = tmp | BIT(5) | BIT(0);
1198         odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK, tmp);
1199
1200         tmp = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK);
1201         tmp = tmp | BIT(5) | BIT(0);
1202         odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK, tmp);
1203
1204         _iqk_iqk_by_path_8822b(dm, segment_iqk);
1205 }
1206
1207 static void _iq_calibrate_8822b_init(void *dm_void)
1208 {
1209         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1210         struct dm_iqk_info *iqk_info = &dm->IQK_info;
1211         u8 i, j;
1212
1213         if (iqk_info->iqk_times == 0) {
1214                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1215                              "[IQK]=====>PHY_IQCalibrate_8822B_Init\n");
1216
1217                 for (i = 0; i < SS_8822B; i++) {
1218                         for (j = 0; j < 2; j++) {
1219                                 iqk_info->lok_fail[i] = true;
1220                                 iqk_info->iqk_fail[j][i] = true;
1221                                 iqk_info->iqc_matrix[j][i] = 0x20000000;
1222                         }
1223                 }
1224
1225                 phydm_init_iqk_information(iqk_info);
1226         }
1227 }
1228
1229 static void _phy_iq_calibrate_8822b(struct phy_dm_struct *dm, bool reset)
1230 {
1231         u32 MAC_backup[MAC_REG_NUM_8822B], BB_backup[BB_REG_NUM_8822B],
1232                 RF_backup[RF_REG_NUM_8822B][SS_8822B];
1233         u32 backup_mac_reg[MAC_REG_NUM_8822B] = {0x520, 0x550};
1234         u32 backup_bb_reg[BB_REG_NUM_8822B] = {
1235                 0x808, 0x90c, 0xc00, 0xcb0,  0xcb4, 0xcbc, 0xe00,
1236                 0xeb0, 0xeb4, 0xebc, 0x1990, 0x9a4, 0xa04};
1237         u32 backup_rf_reg[RF_REG_NUM_8822B] = {0xdf, 0x8f, 0x65, 0x0, 0x1};
1238         bool segment_iqk = false, is_mp = false;
1239
1240         struct dm_iqk_info *iqk_info = &dm->IQK_info;
1241
1242         if (dm->mp_mode)
1243                 is_mp = true;
1244         else if (dm->is_linked)
1245                 segment_iqk = true;
1246
1247         if (!is_mp)
1248                 if (_iqk_reload_iqk_8822b(dm, reset))
1249                         return;
1250
1251         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1252                      "[IQK]==========IQK strat!!!!!==========\n");
1253
1254         ODM_RT_TRACE(
1255                 dm, ODM_COMP_CALIBRATION,
1256                 "[IQK]band_type = %s, band_width = %d, ExtPA2G = %d, ext_pa_5g = %d\n",
1257                 (*dm->band_type == ODM_BAND_5G) ? "5G" : "2G", *dm->band_width,
1258                 dm->ext_pa, dm->ext_pa_5g);
1259         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1260                      "[IQK]Interface = %d, cut_version = %x\n",
1261                      dm->support_interface, dm->cut_version);
1262
1263         iqk_info->iqk_times++;
1264
1265         iqk_info->kcount = 0;
1266         dm->rf_calibrate_info.iqk_total_progressing_time = 0;
1267         dm->rf_calibrate_info.iqk_step = 1;
1268         iqk_info->rxiqk_step = 1;
1269
1270         _iqk_backup_iqk_8822b(dm, 0);
1271         _iqk_backup_mac_bb_8822b(dm, MAC_backup, BB_backup, backup_mac_reg,
1272                                  backup_bb_reg);
1273         _iqk_backup_rf_8822b(dm, RF_backup, backup_rf_reg);
1274
1275         while (1) {
1276                 if (!is_mp)
1277                         dm->rf_calibrate_info.iqk_start_time =
1278                                 odm_get_current_time(dm);
1279
1280                 _iqk_configure_macbb_8822b(dm);
1281                 _iqk_afe_setting_8822b(dm, true);
1282                 _iqk_rfe_setting_8822b(dm, false);
1283                 _iqk_agc_bnd_int_8822b(dm);
1284                 _iqk_rf_setting_8822b(dm);
1285
1286                 _iqk_start_iqk_8822b(dm, segment_iqk);
1287
1288                 _iqk_afe_setting_8822b(dm, false);
1289                 _iqk_restore_mac_bb_8822b(dm, MAC_backup, BB_backup,
1290                                           backup_mac_reg, backup_bb_reg);
1291                 _iqk_restore_rf_8822b(dm, backup_rf_reg, RF_backup);
1292
1293                 if (!is_mp) {
1294                         dm->rf_calibrate_info.iqk_progressing_time =
1295                                 odm_get_progressing_time(
1296                                         dm,
1297                                         dm->rf_calibrate_info.iqk_start_time);
1298                         dm->rf_calibrate_info.iqk_total_progressing_time +=
1299                                 odm_get_progressing_time(
1300                                         dm,
1301                                         dm->rf_calibrate_info.iqk_start_time);
1302                         ODM_RT_TRACE(
1303                                 dm, ODM_COMP_CALIBRATION,
1304                                 "[IQK]IQK progressing_time = %lld ms\n",
1305                                 dm->rf_calibrate_info.iqk_progressing_time);
1306                 }
1307
1308                 if (dm->rf_calibrate_info.iqk_step == 7)
1309                         break;
1310
1311                 iqk_info->kcount = 0;
1312                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay 50ms!!!\n");
1313                 ODM_delay_ms(50);
1314         };
1315
1316         _iqk_backup_iqk_8822b(dm, 1);
1317         _iqk_fill_iqk_report_8822b(dm, 0);
1318
1319         if (!is_mp)
1320                 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1321                              "[IQK]Total IQK progressing_time = %lld ms\n",
1322                              dm->rf_calibrate_info.iqk_total_progressing_time);
1323
1324         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1325                      "[IQK]==========IQK end!!!!!==========\n");
1326 }
1327
1328 static void _phy_iq_calibrate_by_fw_8822b(void *dm_void, u8 clear) {}
1329
1330 /*IQK version:v3.3, NCTL v0.6*/
1331 /*1.The new gainsearch method for RXIQK*/
1332 /*2.The new format of IQK report register: 0x1be8/0x1bec*/
1333 /*3. add the option of segment IQK*/
1334 void phy_iq_calibrate_8822b(void *dm_void, bool clear)
1335 {
1336         struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1337
1338         dm->iqk_fw_offload = 0;
1339
1340         /*FW IQK*/
1341         if (dm->iqk_fw_offload) {
1342                 if (!dm->rf_calibrate_info.is_iqk_in_progress) {
1343                         odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
1344                         dm->rf_calibrate_info.is_iqk_in_progress = true;
1345                         odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
1346
1347                         dm->rf_calibrate_info.iqk_start_time =
1348                                 odm_get_current_time(dm);
1349
1350                         odm_write_4byte(dm, 0x1b00, 0xf8000008);
1351                         odm_set_bb_reg(dm, 0x1bf0, 0xff000000, 0xff);
1352                         ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
1353                                      "[IQK]0x1bf0 = 0x%x\n",
1354                                      odm_read_4byte(dm, 0x1bf0));
1355
1356                         _phy_iq_calibrate_by_fw_8822b(dm, clear);
1357                         phydm_get_read_counter(dm);
1358
1359                         dm->rf_calibrate_info.iqk_progressing_time =
1360                                 odm_get_progressing_time(
1361                                         dm,
1362                                         dm->rf_calibrate_info.iqk_start_time);
1363
1364                         ODM_RT_TRACE(
1365                                 dm, ODM_COMP_CALIBRATION,
1366                                 "[IQK]IQK progressing_time = %lld ms\n",
1367                                 dm->rf_calibrate_info.iqk_progressing_time);
1368
1369                         odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
1370                         dm->rf_calibrate_info.is_iqk_in_progress = false;
1371                         odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
1372                 } else {
1373                         ODM_RT_TRACE(
1374                                 dm, ODM_COMP_CALIBRATION,
1375                                 "== Return the IQK CMD, because the IQK in Progress ==\n");
1376                 }
1377
1378         } else {
1379                 _iq_calibrate_8822b_init(dm_void);
1380
1381                 if (!dm->rf_calibrate_info.is_iqk_in_progress) {
1382                         odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
1383                         dm->rf_calibrate_info.is_iqk_in_progress = true;
1384                         odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
1385                         if (dm->mp_mode)
1386                                 dm->rf_calibrate_info.iqk_start_time =
1387                                         odm_get_current_time(dm);
1388
1389                         _phy_iq_calibrate_8822b(dm, clear);
1390                         if (dm->mp_mode) {
1391                                 dm->rf_calibrate_info.iqk_progressing_time =
1392                                         odm_get_progressing_time(
1393                                                 dm, dm->rf_calibrate_info
1394                                                             .iqk_start_time);
1395                                 ODM_RT_TRACE(
1396                                         dm, ODM_COMP_CALIBRATION,
1397                                         "[IQK]IQK progressing_time = %lld ms\n",
1398                                         dm->rf_calibrate_info
1399                                                 .iqk_progressing_time);
1400                         }
1401                         odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
1402                         dm->rf_calibrate_info.is_iqk_in_progress = false;
1403                         odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
1404                 } else {
1405                         ODM_RT_TRACE(
1406                                 dm, ODM_COMP_CALIBRATION,
1407                                 "[IQK]== Return the IQK CMD, because the IQK in Progress ==\n");
1408                 }
1409         }
1410 }