OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / hal / phydm / rtl8821c / phydm_hal_api8821c.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2017 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  *****************************************************************************/
15
16 #include "mp_precomp.h"
17 #include "../phydm_precomp.h"
18
19 #if (RTL8821C_SUPPORT == 1)
20 #if (PHYDM_FW_API_ENABLE_8821C == 1)
21 /* ======================================================================== */
22 /* These following functions can be used for PHY DM only*/
23
24 u32 rega24_8821c;
25 u32 rega28_8821c;
26 u32 regaac_8821c;
27
28 enum channel_width bw_8821c;
29 u8 central_ch_8821c;
30
31 __iram_odm_func__
32 s8 phydm_cck_rssi_8821c(struct dm_struct *dm, u8 lna_idx, u8 vga_idx)
33 {
34         s8 rx_pwr_all = 0;
35         s8 lna_gain = 0;
36         /*only use lna2/3/5/7*/
37         s8 lna_gain_table_0[8] = {22, 8, -6, -22, -31, -40, -46, -52};
38         /*only use lna4/8/C/F*/
39         s8 lna_gain_table_1[16] = {10, 6, 2, -2, -6, -10, -14, -17,
40                                    -20, -24, -28, -31, -34, -37, -40, -44};
41
42         if (dm->cck_agc_report_type == 0)
43                 lna_gain = lna_gain_table_0[lna_idx];
44         else
45                 lna_gain = lna_gain_table_1[lna_idx];
46
47         rx_pwr_all = lna_gain - (2 * vga_idx);
48
49         return rx_pwr_all;
50 }
51
52 __iram_odm_func__
53 boolean
54 phydm_rfe_8821c(struct dm_struct *dm, u8 channel)
55 {
56 #if 0
57         /* Efuse is not wrote now */
58         /* Need to check RFE type finally */
59         /*if (dm->rfe_type == 1) {*/
60         if (channel <= 14) {
61                 /* signal source */
62                 odm_set_bb_reg(dm, R_0xcb0, (MASKBYTE2 | MASKLWORD), 0x704570);
63                 odm_set_bb_reg(dm, R_0xeb0, (MASKBYTE2 | MASKLWORD), 0x704570);
64                 odm_set_bb_reg(dm, R_0xcb4, MASKBYTE1, 0x45);
65                 odm_set_bb_reg(dm, R_0xeb4, MASKBYTE1, 0x45);
66         } else if (channel > 35) {
67                 odm_set_bb_reg(dm, R_0xcb0, (MASKBYTE2 | MASKLWORD), 0x174517);
68                 odm_set_bb_reg(dm, R_0xeb0, (MASKBYTE2 | MASKLWORD), 0x174517);
69                 odm_set_bb_reg(dm, R_0xcb4, MASKBYTE1, 0x45);
70                 odm_set_bb_reg(dm, R_0xeb4, MASKBYTE1, 0x45);
71         } else
72                 return false;
73
74         /* chip top mux */
75         odm_set_bb_reg(dm, R_0x64, BIT(29) | BIT(28), 0x3);
76         odm_set_bb_reg(dm, R_0x4c, BIT(26) | BIT(25), 0x0);
77         odm_set_bb_reg(dm, R_0x40, BIT(2), 0x1);
78
79         /* from s0 or s1 */
80         odm_set_bb_reg(dm, R_0x1990, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), 0x30);
81         odm_set_bb_reg(dm, R_0x1990, (BIT(11) | BIT(10)), 0x3);
82
83         /* input or output */
84         odm_set_bb_reg(dm, R_0x974, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), 0x3f);
85         odm_set_bb_reg(dm, R_0x974, (BIT(11) | BIT(10)), 0x3);
86
87         /* delay 400ns for PAPE */
88         odm_set_bb_reg(dm, R_0x810, MASKBYTE3 | BIT(20) | BIT(21) | BIT(22) | BIT(23), 0x211);
89
90         /* antenna switch table */
91         odm_set_bb_reg(dm, R_0xca0, MASKLWORD, 0xa555);
92         odm_set_bb_reg(dm, R_0xea0, MASKLWORD, 0xa555);
93
94         /* inverse or not */
95         odm_set_bb_reg(dm, R_0xcbc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), 0x0);
96         odm_set_bb_reg(dm, R_0xcbc, (BIT(11) | BIT(10)), 0x0);
97         odm_set_bb_reg(dm, R_0xebc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), 0x0);
98         odm_set_bb_reg(dm, R_0xebc, (BIT(11) | BIT(10)), 0x0);
99         /*}*/
100 #endif
101         return true;
102 }
103
104 __iram_odm_func__
105 void phydm_ccapar_8821c(struct dm_struct *dm)
106 {
107 #if 0
108         u32     cca_ifem[9][4] = {
109                 /*20M*/
110                 {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
111                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
112                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg838*/
113                 /*40M*/
114                 {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
115                 {0x00000000, 0x79a0ea28, 0x00000000, 0x79a0ea28}, /*Reg830*/
116                 {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/
117                 /*80M*/
118                 {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
119                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
120                 {0x00000000, 0x87746641, 0x00000000, 0x87746641}
121         }; /*Reg838*/
122
123         u32     cca_efem[9][4] = {
124                 /*20M*/
125                 {0x75A76010, 0x75A76010, 0x75A76010, 0x75A75010}, /*Reg82C*/
126                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
127                 {0x87766651, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/
128                 /*40M*/
129                 {0x75A75010, 0x75A75010, 0x75A75010, 0x75A75010}, /*Reg82C*/
130                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
131                 {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/
132                 /*80M*/
133                 {0x75BA7010, 0x75BA7010, 0x75BA7010, 0x75BA7010}, /*Reg82C*/
134                 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
135                 {0x87766431, 0x87766431, 0x87766431, 0x87766431}
136         }; /*Reg838*/
137
138         u8      row, col;
139         u32     reg82c, reg830, reg838;
140
141         if (dm->cut_version != ODM_CUT_B)
142                 return;
143
144         if (bw_8821c == CHANNEL_WIDTH_20)
145                 row = 0;
146         else if (bw_8821c == CHANNEL_WIDTH_40)
147                 row = 3;
148         else
149                 row = 6;
150
151         if (central_ch_8821c <= 14) {
152                 if (dm->rx_ant_status == BB_PATH_A || dm->rx_ant_status == BB_PATH_B)
153                         col = 0;
154                 else
155                         col = 1;
156         } else {
157                 if (dm->rx_ant_status == BB_PATH_A || dm->rx_ant_status == BB_PATH_B)
158                         col = 2;
159                 else
160                         col = 3;
161         }
162
163         if (dm->rfe_type == 0) {/*iFEM*/
164                 reg82c = (cca_ifem[row][col] != 0) ? cca_ifem[row][col] : reg82c_8821c;
165                 reg830 = (cca_ifem[row + 1][col] != 0) ? cca_ifem[row + 1][col] : reg830_8821c;
166                 reg838 = (cca_ifem[row + 2][col] != 0) ? cca_ifem[row + 2][col] : reg838_8821c;
167         } else {/*eFEM*/
168                 reg82c = (cca_efem[row][col] != 0) ? cca_efem[row][col] : reg82c_8821c;
169                 reg830 = (cca_efem[row + 1][col] != 0) ? cca_efem[row + 1][col] : reg830_8821c;
170                 reg838 = (cca_efem[row + 2][col] != 0) ? cca_efem[row + 2][col] : reg838_8821c;
171         }
172
173         odm_set_bb_reg(dm, R_0x82c, MASKDWORD, reg82c);
174         odm_set_bb_reg(dm, R_0x830, MASKDWORD, reg830);
175         odm_set_bb_reg(dm, R_0x838, MASKDWORD, reg838);
176
177         PHYDM_DBG(dm, ODM_PHY_CONFIG,
178                   "[%s]: Update CCA parameters for Bcut (Pkt%d, Intf%d, RFE%d), row = %d, col = %d\n",
179                   __func__, dm->package_type, dm->support_interface,
180                   dm->rfe_type, row, col);
181 #endif
182 }
183
184 __iram_odm_func__
185 void phydm_ccapar_by_bw_8821c(struct dm_struct *dm,
186                               enum channel_width bandwidth)
187 {
188 #if 0
189         u32             reg82c;
190
191
192         if (dm->cut_version != ODM_CUT_A)
193                 return;
194
195         /* A-cut */
196         reg82c = odm_get_bb_reg(dm, R_0x82c, MASKDWORD);
197
198         if (bandwidth == CHANNEL_WIDTH_20) {
199                 /* 82c[15:12] = 4 */
200                 /* 82c[27:24] = 6 */
201
202                 reg82c &= (~(0x0f00f000));
203                 reg82c |= ((0x4) << 12);
204                 reg82c |= ((0x6) << 24);
205         } else if (bandwidth == CHANNEL_WIDTH_40) {
206                 /* 82c[19:16] = 9 */
207                 /* 82c[27:24] = 6 */
208
209                 reg82c &= (~(0x0f0f0000));
210                 reg82c |= ((0x9) << 16);
211                 reg82c |= ((0x6) << 24);
212         } else if (bandwidth == CHANNEL_WIDTH_80) {
213                 /* 82c[15:12] 7 */
214                 /* 82c[19:16] b */
215                 /* 82c[23:20] d */
216                 /* 82c[27:24] 3 */
217
218                 reg82c &= (~(0x0ffff000));
219                 reg82c |= ((0xdb7) << 12);
220                 reg82c |= ((0x3) << 24);
221         }
222
223         odm_set_bb_reg(dm, R_0x82c, MASKDWORD, reg82c);
224         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: Update CCA parameters for Acut\n",
225                   __func__);
226 #endif
227 }
228
229 __iram_odm_func__
230 void phydm_ccapar_by_rxpath_8821c(struct dm_struct *dm)
231 {
232 #if 0
233         if (dm->cut_version != ODM_CUT_A)
234                 return;
235
236         if (dm->rx_ant_status == BB_PATH_A || dm->rx_ant_status == BB_PATH_B) {
237                 /* 838[7:4] = 8 */
238                 /* 838[11:8] = 7 */
239                 /* 838[15:12] = 6 */
240                 /* 838[19:16] = 7 */
241                 /* 838[23:20] = 7 */
242                 /* 838[27:24] = 7 */
243                 odm_set_bb_reg(dm, R_0x838, 0x0ffffff0, 0x777678);
244         } else {
245                 /* 838[7:4] = 3 */
246                 /* 838[11:8] = 3 */
247                 /* 838[15:12] = 6 */
248                 /* 838[19:16] = 6 */
249                 /* 838[23:20] = 7 */
250                 /* 838[27:24] = 7 */
251                 odm_set_bb_reg(dm, R_0x838, 0x0ffffff0, 0x776633);
252         }
253         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: Update CCA parameters for Acut\n",
254                   __func__);
255 #endif
256 }
257
258 __iram_odm_func__
259 void phydm_rxdfirpar_by_bw_8821c(struct dm_struct *dm,
260                                  enum channel_width bandwidth)
261 {
262         if (bandwidth == CHANNEL_WIDTH_40) {
263                 /* RX DFIR for BW40 */
264                 odm_set_bb_reg(dm, R_0x948, BIT(29) | BIT(28), 0x2);
265                 odm_set_bb_reg(dm, R_0x94c, BIT(29) | BIT(28), 0x2);
266                 odm_set_bb_reg(dm, R_0xc20, BIT(31), 0x0);
267                 odm_set_bb_reg(dm, R_0x8f0, BIT(31), 0x0);
268         } else if (bandwidth == CHANNEL_WIDTH_80) {
269                 /* RX DFIR for BW80 */
270                 odm_set_bb_reg(dm, R_0x948, BIT(29) | BIT(28), 0x2);
271                 odm_set_bb_reg(dm, R_0x94c, BIT(29) | BIT(28), 0x1);
272                 odm_set_bb_reg(dm, R_0xc20, BIT(31), 0x0);
273                 odm_set_bb_reg(dm, R_0x8f0, BIT(31), 0x1);
274         } else {
275                 /* RX DFIR for BW20, BW10 and BW5*/
276                 odm_set_bb_reg(dm, R_0x948, BIT(29) | BIT(28), 0x2);
277                 odm_set_bb_reg(dm, R_0x94c, BIT(29) | BIT(28), 0x2);
278                 odm_set_bb_reg(dm, R_0xc20, BIT(31), 0x1);
279                 odm_set_bb_reg(dm, R_0x8f0, BIT(31), 0x0);
280         }
281         /* PHYDM_DBG(dm, ODM_PHY_CONFIG, "phydm_rxdfirpar_by_bw_8821c\n");*/
282 }
283
284 __iram_odm_func__
285 boolean
286 phydm_write_txagc_1byte_8821c(struct dm_struct *dm, u32 power_index,
287                               enum rf_path path, u8 hw_rate)
288 {
289 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
290         u32 offset_txagc[2] = {0x1d00, 0x1d80};
291         u8 rate_idx = (hw_rate & 0xfc), i;
292         u8 rate_offset = (hw_rate & 0x3);
293         u32 txagc_content = 0x0;
294
295         /* For debug command only!!!! */
296
297         /* Error handling */
298         if (path > RF_PATH_A || hw_rate > 0x53) {
299                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: unsupported path (%d)\n",
300                           __func__, path);
301                 return false;
302         }
303
304 #if 1
305         /* For HW limitation, We can't write TXAGC once a byte. */
306         for (i = 0; i < 4; i++) {
307                 if (i != rate_offset)
308                         txagc_content = txagc_content | (config_phydm_read_txagc_8821c(dm, path, rate_idx + i) << (i << 3));
309                 else
310                         txagc_content = txagc_content | ((power_index & 0x3f) << (i << 3));
311         }
312         odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, txagc_content);
313 #else
314         odm_write_1byte(dm, (offset_txagc[path] + hw_rate), (power_index & 0x3f));
315 #endif
316
317         PHYDM_DBG(dm, ODM_PHY_CONFIG,
318                   "[%s]: path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__,
319                   path, hw_rate, (offset_txagc[path] + hw_rate), power_index);
320         return true;
321 #else
322         return false;
323 #endif
324 }
325
326 __iram_odm_func__
327 void phydm_init_hw_info_by_rfe_type_8821c(struct dm_struct *dm)
328 {
329 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
330         dm->is_init_hw_info_by_rfe = false;
331         /*
332          * Let original variable rfe_type to be rfe_type_8821c.
333          * Varible rfe_type as symbol is used to identify PHY parameter.
334          */
335         dm->rfe_type = dm->rfe_type_expand >> 3;
336
337         /*2.4G default rf set with wlg or btg*/
338         if (dm->rfe_type_expand == 2 || dm->rfe_type_expand == 4 || dm->rfe_type_expand == 7) {
339                 dm->default_rf_set_8821c = SWITCH_TO_BTG;
340         } else if (dm->rfe_type_expand == 0 || dm->rfe_type_expand == 1 ||
341                  dm->rfe_type_expand == 3 || dm->rfe_type_expand == 5 ||
342                  dm->rfe_type_expand == 6) {
343                 dm->default_rf_set_8821c = SWITCH_TO_WLG;
344         } else if (dm->rfe_type_expand == 0x22 || dm->rfe_type_expand == 0x24 ||
345                  dm->rfe_type_expand == 0x27 || dm->rfe_type_expand == 0x2a ||
346                  dm->rfe_type_expand == 0x2c || dm->rfe_type_expand == 0x2f) {
347                 dm->default_rf_set_8821c = SWITCH_TO_BTG;
348                 odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1);
349         } else if (dm->rfe_type_expand == 0x20 || dm->rfe_type_expand == 0x21 ||
350                    dm->rfe_type_expand == 0x23 || dm->rfe_type_expand == 0x25 ||
351                    dm->rfe_type_expand == 0x26 || dm->rfe_type_expand == 0x28 ||
352                    dm->rfe_type_expand == 0x29 || dm->rfe_type_expand == 0x2b ||
353                    dm->rfe_type_expand == 0x2d || dm->rfe_type_expand == 0x2e) {
354                 dm->default_rf_set_8821c = SWITCH_TO_WLG;
355                 odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1);
356         }
357
358         if (dm->rfe_type_expand == 3 || dm->rfe_type_expand == 4 ||
359             dm->rfe_type_expand == 0x23 || dm->rfe_type_expand == 0x24 ||
360             dm->rfe_type_expand == 0x2b || dm->rfe_type_expand == 0x2c)
361                 dm->default_ant_num_8821c = SWITCH_TO_ANT2;
362         else
363                 dm->default_ant_num_8821c = SWITCH_TO_ANT1;
364
365         dm->is_init_hw_info_by_rfe = true;
366         PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s: RFE type (%d), rf set (%s)\n",
367                   __FUNCTION__, dm->rfe_type_expand,
368                   dm->default_rf_set_8821c == 0 ? "BTG" : "WLG");
369 #endif
370 }
371
372 __iram_odm_func__
373 void phydm_set_gnt_state_8821c(struct dm_struct *dm, boolean gnt_wl_state,
374                                boolean gnt_bt_state)
375 {
376 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
377         u32 gnt_val = 0;
378
379         odm_set_bb_reg(dm, R_0x70, BIT(26), 0x1);
380
381         if (gnt_wl_state)
382                 gnt_val = 0x3300;
383         else
384                 gnt_val = 0x1100;
385
386         if (gnt_bt_state)
387                 gnt_val = gnt_val | 0xcc00;
388         else
389                 gnt_val = gnt_val | 0x4400;
390
391         odm_set_bb_reg(dm, R_0x1704, MASKLWORD, gnt_val);
392         ODM_delay_us(50); /*waiting before access 0x1700 */
393         odm_set_bb_reg(dm, R_0x1700, MASKDWORD, 0xc00f0038);
394 #endif
395 }
396 /* ======================================================================== */
397
398 /* ======================================================================== */
399 /* These following functions can be used by driver*/
400
401 __iram_odm_func__
402 u32 config_phydm_read_rf_reg_8821c(struct dm_struct *dm, enum rf_path path,
403                                    u32 reg_addr, u32 bit_mask)
404 {
405         u32 readback_value, direct_addr;
406         u32 offset_read_rf[2] = {0x2800, 0x2c00};
407
408         /* Error handling.*/
409         if (path > RF_PATH_A) {
410                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: unsupported path (%d)\n",
411                           __func__, path);
412                 return INVALID_RF_DATA;
413         }
414
415         /* Calculate offset */
416         reg_addr &= 0xff;
417         direct_addr = offset_read_rf[path] + (reg_addr << 2);
418
419         /* RF register only has 20bits */
420         bit_mask &= RFREGOFFSETMASK;
421
422         /* Read RF register directly */
423         readback_value = odm_get_bb_reg(dm, direct_addr, bit_mask);
424         PHYDM_DBG(dm, ODM_PHY_CONFIG,
425                   "[%s]: RF-%d 0x%x = 0x%x, bit mask = 0x%x\n", __func__, path,
426                   reg_addr, readback_value, bit_mask);
427         return readback_value;
428 }
429
430 __iram_odm_func__
431 boolean
432 config_phydm_write_rf_reg_8821c(struct dm_struct *dm, enum rf_path path,
433                                 u32 reg_addr, u32 bit_mask, u32 data)
434 {
435         u32 data_and_addr = 0, data_original = 0;
436         u32 offset_write_rf[2] = {0xc90, 0xe90};
437         u8 bit_shift;
438
439         /* Error handling.*/
440         if (path > RF_PATH_A) {
441                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: unsupported path (%d)\n",
442                           __func__, path);
443                 return false;
444         }
445
446         /* Read RF register content first */
447         reg_addr &= 0xff;
448         bit_mask = bit_mask & RFREGOFFSETMASK;
449
450         if (bit_mask != RFREGOFFSETMASK) {
451                 data_original = config_phydm_read_rf_reg_8821c(dm, path, reg_addr, RFREGOFFSETMASK);
452
453                 /* Error handling. RF is disabled */
454                 if (config_phydm_read_rf_check_8821c(data_original) == false) {
455                         PHYDM_DBG(dm, ODM_PHY_CONFIG,
456                                   "[%s]: Write fail, RF is disable\n",
457                                   __func__);
458                         return false;
459                 }
460
461                 /* check bit mask */
462                 if (bit_mask != 0xfffff) {
463                         for (bit_shift = 0; bit_shift <= 19; bit_shift++) {
464                                 if (((bit_mask >> bit_shift) & 0x1) == 1)
465                                         break;
466                         }
467                         data = ((data_original) & (~bit_mask)) | (data << bit_shift);
468                 }
469         }
470
471         /* Put write addr in [27:20]  and write data in [19:00] */
472         data_and_addr = ((reg_addr << 20) | (data & 0x000fffff)) & 0x0fffffff;
473
474         /* Write operation */
475         odm_set_bb_reg(dm, offset_write_rf[path], MASKDWORD, data_and_addr);
476         PHYDM_DBG(dm, ODM_PHY_CONFIG,
477                   "[%s]: RF-%d 0x%x = 0x%x (original: 0x%x), bit mask = 0x%x\n",
478                   __func__, path, reg_addr, data, data_original, bit_mask);
479
480 #if (defined(CONFIG_RUN_IN_DRV))
481         if (dm->support_interface == ODM_ITRF_PCIE)
482                 ODM_delay_us(13);
483 #elif (defined(CONFIG_RUN_IN_FW))
484         ODM_delay_us(13);
485 #endif
486
487         return true;
488 }
489
490 __iram_odm_func__
491 boolean
492 config_phydm_write_txagc_8821c(struct dm_struct *dm, u32 power_index,
493                                enum rf_path path, u8 hw_rate)
494 {
495 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
496         u32 offset_txagc[2] = {0x1d00, 0x1d80};
497         u8 rate_idx = (hw_rate & 0xfc);
498
499         /* Input need to be HW rate index, not driver rate index!!!! */
500
501         if (dm->is_disable_phy_api) {
502                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
503                           "[%s]: disable PHY API for debug!!\n", __func__);
504                 return true;
505         }
506
507         /* Error handling */
508         if (path > RF_PATH_A || hw_rate > 0x53) {
509                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: unsupported path (%d)\n",
510                           __func__, path);
511                 return false;
512         }
513
514         /* driver need to construct a 4-byte power index */
515         odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, power_index);
516
517         PHYDM_DBG(dm, ODM_PHY_CONFIG,
518                   "[%s]: path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__,
519                   path, hw_rate, (offset_txagc[path] + hw_rate), power_index);
520         return true;
521 #else
522         return false;
523 #endif
524 }
525
526 __iram_odm_func__
527 u8 config_phydm_read_txagc_8821c(struct dm_struct *dm, enum rf_path path,
528                                  u8 hw_rate)
529 {
530 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
531         u8 read_back_data;
532
533         /* Input need to be HW rate index, not driver rate index!!!! */
534
535         /* Error handling */
536         if (path > RF_PATH_A || hw_rate > 0x53) {
537                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: unsupported path (%d)\n",
538                           __func__, path);
539                 return INVALID_TXAGC_DATA;
540         }
541
542         /* Disable TX AGC report */
543         odm_set_bb_reg(dm, R_0x1998, BIT(16), 0x0); /* need to check */
544
545         /* Set data rate index (bit0~6) and path index (bit7) */
546         odm_set_bb_reg(dm, R_0x1998, MASKBYTE0, (hw_rate | (path << 7)));
547
548         /* Enable TXAGC report */
549         odm_set_bb_reg(dm, R_0x1998, BIT(16), 0x1);
550
551         /* Read TX AGC report */
552         read_back_data = (u8)odm_get_bb_reg(dm, R_0xd30, 0x7f0000);
553
554         /* Driver have to disable TXAGC report after reading TXAGC (ref. user guide v11) */
555         odm_set_bb_reg(dm, R_0x1998, BIT(16), 0x0);
556
557         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: path-%d rate index 0x%x = 0x%x\n",
558                   __func__, path, hw_rate, read_back_data);
559         return read_back_data;
560 #else
561         return 0;
562 #endif
563 }
564
565 __iram_odm_func__
566 boolean
567 config_phydm_switch_band_8821c(struct dm_struct *dm, u8 central_ch)
568 {
569         u32 rf_reg18;
570         boolean rf_reg_status = true;
571
572         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]======================>\n",
573                   __func__);
574
575         if (dm->is_disable_phy_api) {
576                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
577                           "[%s]: disable PHY API for debug!!\n", __func__);
578                 return true;
579         }
580
581         rf_reg18 = config_phydm_read_rf_reg_8821c(dm, RF_PATH_A, 0x18, RFREGOFFSETMASK);
582         rf_reg_status = rf_reg_status & config_phydm_read_rf_check_8821c(rf_reg18);
583
584         if (central_ch <= 14) {
585                 /* 2.4G */
586
587                 /* Enable CCK block */
588                 odm_set_bb_reg(dm, R_0x808, BIT(28), 0x1);
589
590                 /* Disable MAC CCK check */
591                 odm_set_bb_reg(dm, R_0x454, BIT(7), 0x0);
592
593                 /* Disable BB CCK check */
594                 odm_set_bb_reg(dm, R_0xa80, BIT(18), 0x0);
595
596                 /*CCA Mask*/
597                 odm_set_bb_reg(dm, R_0x814, 0x0000FC00, 15); /*default value*/
598
599                 /* RF band */
600                 rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8))));
601 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
602                 /* Switch WLG/BTG*/
603                 if (dm->default_rf_set_8821c == SWITCH_TO_BTG)
604                         config_phydm_switch_rf_set_8821c(dm, SWITCH_TO_BTG);
605                 else if (dm->default_rf_set_8821c == SWITCH_TO_WLG)
606                         config_phydm_switch_rf_set_8821c(dm, SWITCH_TO_WLG);
607 #endif
608                 /*RF TXA_TANK LUT mode*/
609                 odm_set_rf_reg(dm, RF_PATH_A, RF_0xdf, BIT(6), 0x1);
610
611                 /*RF TXA_PA_TANK*/
612                 odm_set_rf_reg(dm, RF_PATH_A, RF_0x64, 0x0000f, 0xf);
613
614         } else if (central_ch > 35) {
615                 /* 5G */
616
617                 /* Enable BB CCK check */
618                 odm_set_bb_reg(dm, R_0xa80, BIT(18), 0x1);
619
620                 /* Enable CCK check */
621                 odm_set_bb_reg(dm, R_0x454, BIT(7), 0x1);
622
623                 /* Disable CCK block */
624                 odm_set_bb_reg(dm, R_0x808, BIT(28), 0x0);
625
626                 /*CCA Mask*/
627                 odm_set_bb_reg(dm, R_0x814, 0x0000FC00, 15); /*default value*/
628                 /*odm_set_bb_reg(dm, R_0x814, 0x0000FC00, 34); CCA mask = 13.6us*/
629
630                 /* RF band */
631                 rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8))));
632                 rf_reg18 = (rf_reg18 | BIT(8) | BIT(16));
633 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
634                 /* Switch WLA */
635                 config_phydm_switch_rf_set_8821c(dm, SWITCH_TO_WLA);
636 #endif
637                 /*RF TXA_TANK LUT mode*/
638                 odm_set_rf_reg(dm, RF_PATH_A, RF_0xdf, BIT(6), 0x0);
639
640         } else {
641                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
642                           "[%s]: Fail to switch band (ch: %d)\n", __func__,
643                           central_ch);
644                 return false;
645         }
646
647         odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREGOFFSETMASK, rf_reg18);
648
649         if (phydm_rfe_8821c(dm, central_ch) == false)
650                 return false;
651
652         if (!rf_reg_status) {
653                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
654                           "[%s]: Fail to switch band (ch: %d), because writing RF register is fail\n",
655                           __func__, central_ch);
656                 return false;
657         }
658
659         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: Success to switch band (ch: %d)\n",
660                   __func__, central_ch);
661         return true;
662 }
663
664 __iram_odm_func__
665 boolean
666 config_phydm_switch_channel_8821c(struct dm_struct *dm, u8 central_ch)
667 {
668         struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
669         u32 rf_reg18, rf_reg_b8 = 0;
670         boolean rf_reg_status = true;
671
672         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]====================>\n", __func__);
673
674         if (dm->is_disable_phy_api) {
675                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
676                           "[%s]: disable PHY API for debug!!\n", __func__);
677                 return true;
678         }
679
680         central_ch_8821c = central_ch;
681         rf_reg18 = config_phydm_read_rf_reg_8821c(dm, RF_PATH_A, 0x18, RFREGOFFSETMASK);
682         rf_reg_status = rf_reg_status & config_phydm_read_rf_check_8821c(rf_reg18);
683
684         if (dm->cut_version == ODM_CUT_A) {
685                 rf_reg_b8 = config_phydm_read_rf_reg_8821c(dm, RF_PATH_A, 0xb8, RFREGOFFSETMASK);
686                 rf_reg_status = rf_reg_status & config_phydm_read_rf_check_8821c(rf_reg_b8);
687         }
688
689         /* Switch band and channel */
690         if (central_ch <= 14) {
691                 /* 2.4G */
692
693                 /* 1. RF band and channel*/
694                 rf_reg18 = (rf_reg18 & (~(BIT(18) | BIT(17) | MASKBYTE0)));
695                 rf_reg18 = (rf_reg18 | central_ch);
696
697                 /* 2. AGC table selection */
698                 odm_set_bb_reg(dm, R_0xc1c, 0x00000F00, 0x0);
699                 dig_t->agc_table_idx = 0x0;
700
701                 /* 3. Set central frequency for clock offset tracking */
702                 odm_set_bb_reg(dm, R_0x860, 0x1ffe0000, 0x96a);
703
704                 /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */
705                 if (dm->cut_version == ODM_CUT_A)
706                         rf_reg_b8 = rf_reg_b8 | BIT(19);
707
708                 /* CCK TX filter parameters */
709                 if (central_ch == 14) {
710                         odm_set_bb_reg(dm, R_0xa24, MASKDWORD, 0x0000b81c);
711                         odm_set_bb_reg(dm, R_0xa28, MASKLWORD, 0x0000);
712                         odm_set_bb_reg(dm, R_0xaac, MASKDWORD, 0x00003667);
713                 } else {
714                         odm_set_bb_reg(dm, R_0xa24, MASKDWORD, rega24_8821c);
715                         odm_set_bb_reg(dm, R_0xa28, MASKLWORD, (rega28_8821c & MASKLWORD));
716                         odm_set_bb_reg(dm, R_0xaac, MASKDWORD, regaac_8821c);
717                 }
718
719         } else if (central_ch > 35) {
720                 /* 5G */
721
722                 /* 1. RF band and channel*/
723                 rf_reg18 = (rf_reg18 & (~(BIT(18) | BIT(17) | MASKBYTE0)));
724                 rf_reg18 = (rf_reg18 | central_ch);
725
726                 if (central_ch >= 36 && central_ch <= 64) {
727                         ;
728                 } else if ((central_ch >= 100) && (central_ch <= 140)) {
729                         rf_reg18 = (rf_reg18 | BIT(17));
730                 } else if (central_ch > 140) {
731                         rf_reg18 = (rf_reg18 | BIT(18));
732                 } else {
733                         PHYDM_DBG(dm, ODM_PHY_CONFIG,
734                                   "[%s]: Fail to switch channel (RF18) (ch: %d)\n",
735                                   __func__, central_ch);
736                         return false;
737                 }
738
739                 /* 2. AGC table selection */
740                 if (central_ch >= 36 && central_ch <= 64) {
741                         odm_set_bb_reg(dm, R_0xc1c, 0x00000F00, 0x1);
742                         dig_t->agc_table_idx = 0x1;
743                 } else if ((central_ch >= 100) && (central_ch <= 144)) {
744                         odm_set_bb_reg(dm, R_0xc1c, 0x00000F00, 0x2);
745                         dig_t->agc_table_idx = 0x2;
746                 } else if (central_ch >= 149) {
747                         odm_set_bb_reg(dm, R_0xc1c, 0x00000F00, 0x3);
748                         dig_t->agc_table_idx = 0x3;
749                 } else {
750                         PHYDM_DBG(dm, ODM_PHY_CONFIG,
751                                   "[%s]: Fail to switch channel (AGC) (ch: %d)\n",
752                                   __func__, central_ch);
753                         return false;
754                 }
755
756                 /* 3. Set central frequency for clock offset tracking */
757                 if (central_ch >= 36 && central_ch <= 48) {
758                         odm_set_bb_reg(dm, R_0x860, 0x1ffe0000, 0x494);
759                 } else if ((central_ch >= 52) && (central_ch <= 64)) {
760                         odm_set_bb_reg(dm, R_0x860, 0x1ffe0000, 0x453);
761                 } else if ((central_ch >= 100) && (central_ch <= 116)) {
762                         odm_set_bb_reg(dm, R_0x860, 0x1ffe0000, 0x452);
763                 } else if ((central_ch >= 118) && (central_ch <= 177)) {
764                         odm_set_bb_reg(dm, R_0x860, 0x1ffe0000, 0x412);
765                 } else {
766                         PHYDM_DBG(dm, ODM_PHY_CONFIG,
767                                   "[%s]: Fail to switch channel (fc_area) (ch: %d)\n",
768                                   __func__, central_ch);
769                         return false;
770                 }
771
772                 /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */
773                 if (dm->cut_version == ODM_CUT_A) {
774                         if (central_ch >= 57 && central_ch <= 75)
775                                 rf_reg_b8 = rf_reg_b8 & (~BIT(19));
776                         else
777                                 rf_reg_b8 = rf_reg_b8 | BIT(19);
778                 }
779
780 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
781                 /*notch 5760 spur by CSI_MASK*/
782                 if (central_ch == 153)
783                         phydm_csi_mask_setting(dm, FUNC_ENABLE, (u32)central_ch, 20, 5760, PHYDM_DONT_CARE);
784                 else if (central_ch == 151)
785                         phydm_csi_mask_setting(dm, FUNC_ENABLE, (u32)central_ch, 40, 5760, PHYDM_DONT_CARE);
786                 else if (central_ch == 155)
787                         phydm_csi_mask_setting(dm, FUNC_ENABLE, (u32)central_ch, 80, 5760, PHYDM_DONT_CARE);
788                 else
789                         phydm_csi_mask_setting(dm, FUNC_DISABLE, (u32)central_ch, 80, 5760, PHYDM_DONT_CARE);
790 #endif
791
792         } else {
793                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
794                           "[%s]: Fail to switch band (ch: %d)\n", __func__,
795                           central_ch);
796                 return false;
797         }
798
799         odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREGOFFSETMASK, rf_reg18);
800
801         if (dm->cut_version == ODM_CUT_A)
802                 odm_set_rf_reg(dm, RF_PATH_A, RF_0xb8, RFREGOFFSETMASK, rf_reg_b8);
803
804         if (!rf_reg_status) {
805                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
806                           "[%s]: Fail to switch channel (ch: %d), because writing RF register is fail\n",
807                           __func__, central_ch);
808                 return false;
809         }
810
811         phydm_ccapar_8821c(dm);
812         PHYDM_DBG(dm, ODM_PHY_CONFIG,
813                   "[%s]: Success to switch channel (ch: %d)\n", __func__,
814                   central_ch);
815         return true;
816 }
817
818 __iram_odm_func__
819 boolean
820 config_phydm_switch_bandwidth_8821c(struct dm_struct *dm, u8 primary_ch_idx,
821                                     enum channel_width bandwidth)
822 {
823         u32 rf_reg18;
824         boolean rf_reg_status = true;
825         u32 bb_reg8ac;
826
827         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]===================>\n", __func__);
828
829         if (dm->is_disable_phy_api) {
830                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
831                           "[%s]: disable PHY API for debug!!\n", __func__);
832                 return true;
833         }
834
835         /* Error handling */
836         if (bandwidth >= CHANNEL_WIDTH_MAX || (bandwidth == CHANNEL_WIDTH_40 && primary_ch_idx > 2) || (bandwidth == CHANNEL_WIDTH_80 && primary_ch_idx > 4)) {
837                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
838                           "[%s]: Fail to switch bandwidth (bw: %d, primary ch: %d)\n",
839                           __func__, bandwidth, primary_ch_idx);
840                 return false;
841         }
842         /*Make protection*/
843         if (central_ch_8821c == 165 && !(*dm->mp_mode))
844                 bandwidth = CHANNEL_WIDTH_20;
845
846         bw_8821c = bandwidth;
847         rf_reg18 = config_phydm_read_rf_reg_8821c(dm, RF_PATH_A, 0x18, RFREGOFFSETMASK);
848         rf_reg_status = rf_reg_status & config_phydm_read_rf_check_8821c(rf_reg18);
849
850         /* Switch bandwidth */
851         switch (bandwidth) {
852         case CHANNEL_WIDTH_20: {
853 /* Small BW([7:6]) = 0, primary channel ([5:2]) = 0, rf mode([1:0]) = 20M */
854 #if 0
855                 odm_set_bb_reg(dm, R_0x8ac, MASKBYTE0, CHANNEL_WIDTH_20);
856
857                 /* ADC clock = 160M clock for BW20 */
858                 odm_set_bb_reg(dm, R_0x8ac, (BIT(9) | BIT(8)), 0x0);
859                 odm_set_bb_reg(dm, R_0x8ac, BIT(16), 0x1);
860
861                 /* DAC clock = 160M clock for BW20 */
862                 odm_set_bb_reg(dm, R_0x8ac, (BIT(21) | BIT(20)), 0x0);
863                 odm_set_bb_reg(dm, R_0x8ac, BIT(28), 0x1);
864 #endif
865                 bb_reg8ac = odm_get_bb_reg(dm, R_0x8ac, MASKDWORD);
866                 bb_reg8ac &= 0xffcffc00;
867                 bb_reg8ac |= 0x10010000;
868                 odm_set_bb_reg(dm, R_0x8ac, MASKDWORD, bb_reg8ac);
869
870                 /* ADC buffer clock */
871                 odm_set_bb_reg(dm, R_0x8c4, BIT(30), 0x1);
872
873                 /* RF bandwidth */
874                 rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
875
876                 break;
877         }
878         case CHANNEL_WIDTH_40: {
879                 /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, rf mode([1:0]) = 40M */
880                 /*odm_set_bb_reg(dm, R_0x8ac, MASKBYTE0, (((primary_ch_idx & 0xf) << 2) | CHANNEL_WIDTH_40));*/
881
882                 /* CCK primary channel */
883                 if (primary_ch_idx == 1)
884                         odm_set_bb_reg(dm, R_0xa00, BIT(4), primary_ch_idx);
885                 else
886                         odm_set_bb_reg(dm, R_0xa00, BIT(4), 0);
887 #if 0
888                 /* ADC clock = 160M clock for BW40 */
889                 odm_set_bb_reg(dm, R_0x8ac, (BIT(11) | BIT(10)), 0x0);
890                 odm_set_bb_reg(dm, R_0x8ac, BIT(17), 0x1);
891
892                 /* DAC clock = 160M clock for BW20 */
893                 odm_set_bb_reg(dm, R_0x8ac, (BIT(23) | BIT(22)), 0x0);
894                 odm_set_bb_reg(dm, R_0x8ac, BIT(29), 0x1);
895 #endif
896                 bb_reg8ac = odm_get_bb_reg(dm, R_0x8ac, MASKDWORD);
897                 bb_reg8ac &= 0xff3ff300;
898                 bb_reg8ac |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) | CHANNEL_WIDTH_40;
899                 odm_set_bb_reg(dm, R_0x8ac, MASKDWORD, bb_reg8ac);
900
901                 /* ADC buffer clock */
902                 odm_set_bb_reg(dm, R_0x8c4, BIT(30), 0x1);
903
904                 /* RF bandwidth */
905                 rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10))));
906                 rf_reg18 = (rf_reg18 | BIT(11));
907
908                 break;
909         }
910         case CHANNEL_WIDTH_80: {
911 /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, rf mode([1:0]) = 80M */
912 #if 0
913                 odm_set_bb_reg(dm, R_0x8ac, MASKBYTE0, (((primary_ch_idx & 0xf) << 2) | CHANNEL_WIDTH_80));
914
915                 /* ADC clock = 160M clock for BW80 */
916                 odm_set_bb_reg(dm, R_0x8ac, (BIT(13) | BIT(12)), 0x0);
917                 odm_set_bb_reg(dm, R_0x8ac, BIT(18), 0x1);
918
919                 /* DAC clock = 160M clock for BW20 */
920                 odm_set_bb_reg(dm, R_0x8ac, (BIT(25) | BIT(24)), 0x0);
921                 odm_set_bb_reg(dm, R_0x8ac, BIT(30), 0x1);
922 #endif
923                 bb_reg8ac = odm_get_bb_reg(dm, R_0x8ac, MASKDWORD);
924                 bb_reg8ac &= 0xfcffcf00;
925                 bb_reg8ac |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) | CHANNEL_WIDTH_80;
926                 odm_set_bb_reg(dm, R_0x8ac, MASKDWORD, bb_reg8ac);
927
928                 /* ADC buffer clock */
929                 odm_set_bb_reg(dm, R_0x8c4, BIT(30), 0x1);
930
931                 /* RF bandwidth */
932                 rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10))));
933                 rf_reg18 = (rf_reg18 | BIT(10));
934
935                 break;
936         }
937         case CHANNEL_WIDTH_5: {
938 /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, rf mode([1:0]) = 20M */
939 #if 0
940                 odm_set_bb_reg(dm, R_0x8ac, MASKBYTE0, (BIT(6) | CHANNEL_WIDTH_20));
941
942                 /* ADC clock = 40M clock */
943                 odm_set_bb_reg(dm, R_0x8ac, (BIT(9) | BIT(8)), 0x2);
944                 odm_set_bb_reg(dm, R_0x8ac, BIT(16), 0x0);
945
946                 /* DAC clock = 160M clock for BW20 */
947                 odm_set_bb_reg(dm, R_0x8ac, (BIT(21) | BIT(20)), 0x2);
948                 odm_set_bb_reg(dm, R_0x8ac, BIT(28), 0x0);
949 #endif
950                 bb_reg8ac = odm_get_bb_reg(dm, R_0x8ac, MASKDWORD);
951                 bb_reg8ac &= 0xefcefc00;
952                 bb_reg8ac |= (0x2 << 20) | (0x2 << 8) | BIT(6);
953                 odm_set_bb_reg(dm, R_0x8ac, MASKDWORD, bb_reg8ac);
954
955                 /* ADC buffer clock */
956                 odm_set_bb_reg(dm, R_0x8c4, BIT(30), 0x0);
957                 odm_set_bb_reg(dm, R_0x8c8, BIT(31), 0x1);
958
959                 /* RF bandwidth */
960                 rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
961
962                 break;
963         }
964         case CHANNEL_WIDTH_10: {
965 /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, rf mode([1:0]) = 20M */
966 #if 0
967                 odm_set_bb_reg(dm, R_0x8ac, MASKBYTE0, (BIT(7) | CHANNEL_WIDTH_20));
968
969                 /* ADC clock = 80M clock */
970                 odm_set_bb_reg(dm, R_0x8ac, (BIT(9) | BIT(8)), 0x3);
971                 odm_set_bb_reg(dm, R_0x8ac, BIT(16), 0x0);
972
973                 /* DAC clock = 160M clock for BW20 */
974                 odm_set_bb_reg(dm, R_0x8ac, (BIT(21) | BIT(20)), 0x3);
975                 odm_set_bb_reg(dm, R_0x8ac, BIT(28), 0x0);
976 #endif
977                 bb_reg8ac = odm_get_bb_reg(dm, R_0x8ac, MASKDWORD);
978                 bb_reg8ac &= 0xefcefc00;
979                 bb_reg8ac |= (0x3 << 20) | (0x3 << 8) | BIT(7);
980                 odm_set_bb_reg(dm, R_0x8ac, MASKDWORD, bb_reg8ac);
981
982                 /* ADC buffer clock */
983                 odm_set_bb_reg(dm, R_0x8c4, BIT(30), 0x0);
984                 odm_set_bb_reg(dm, R_0x8c8, BIT(31), 0x1);
985
986                 /* RF bandwidth */
987                 rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
988
989                 break;
990         }
991         default:
992                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
993                           "[%s]: Fail to switch bandwidth (bw: %d, primary ch: %d)\n",
994                           __func__, bandwidth, primary_ch_idx);
995         }
996
997         /* Write RF register */
998         odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREGOFFSETMASK, rf_reg18);
999
1000         if (!rf_reg_status) {
1001                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1002                           "[%s]: Fail to switch bandwidth (bw: %d, primary ch: %d), because writing RF register is fail\n",
1003                           __func__, bandwidth, primary_ch_idx);
1004                 return false;
1005         }
1006
1007         /* Modify RX DFIR parameters */
1008         phydm_rxdfirpar_by_bw_8821c(dm, bandwidth);
1009
1010         /* Modify CCA parameters */
1011         phydm_ccapar_by_bw_8821c(dm, bandwidth);
1012         phydm_ccapar_8821c(dm);
1013
1014         /* Toggle RX path to avoid RX dead zone issue */
1015         /*odm_set_bb_reg(dm, R_0x808, MASKBYTE0, 0x0);*/
1016         /*odm_set_bb_reg(dm, R_0x808, MASKBYTE0, 0x11);*/
1017
1018         PHYDM_DBG(dm, ODM_PHY_CONFIG,
1019                   "[%s]: Success to switch bandwidth (bw: %d, primary ch: %d)\n",
1020                   __func__, bandwidth, primary_ch_idx);
1021         return true;
1022 }
1023
1024 __iram_odm_func__
1025 boolean
1026 config_phydm_switch_channel_bw_8821c(struct dm_struct *dm, u8 central_ch,
1027                                      u8 primary_ch_idx,
1028                                      enum channel_width bandwidth)
1029 {
1030         /* Switch band */
1031         if (config_phydm_switch_band_8821c(dm, central_ch) == false)
1032                 return false;
1033
1034         /* Switch channel */
1035         if (config_phydm_switch_channel_8821c(dm, central_ch) == false)
1036                 return false;
1037
1038         /* Switch bandwidth */
1039         if (config_phydm_switch_bandwidth_8821c(dm, primary_ch_idx, bandwidth) == false)
1040                 return false;
1041
1042         return true;
1043 }
1044
1045 __iram_odm_func__
1046 boolean
1047 config_phydm_trx_mode_8821c(struct dm_struct *dm, enum bb_path tx_path,
1048                             enum bb_path rx_path, boolean is_tx2_path)
1049 {
1050         return true;
1051 }
1052
1053 __iram_odm_func__
1054 boolean
1055 config_phydm_parameter_init_8821c(struct dm_struct *dm,
1056                                   enum odm_parameter_init type)
1057 {
1058         if (type == ODM_PRE_SETTING) {
1059                 odm_set_bb_reg(dm, R_0x808, (BIT(28) | BIT(29)), 0x0);
1060                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1061                           "[%s]: Pre setting: disable OFDM and CCK block\n",
1062                           __func__);
1063         } else if (type == ODM_POST_SETTING) {
1064                 odm_set_bb_reg(dm, R_0x808, (BIT(28) | BIT(29)), 0x3);
1065                 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1066                           "[%s]: Post setting: enable OFDM and CCK block\n",
1067                           __func__);
1068                 rega24_8821c = odm_get_bb_reg(dm, R_0xa24, MASKDWORD);
1069                 rega28_8821c = odm_get_bb_reg(dm, R_0xa28, MASKDWORD);
1070                 regaac_8821c = odm_get_bb_reg(dm, R_0xaac, MASKDWORD);
1071 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1072         } else if (type == ODM_INIT_FW_SETTING) {
1073                 u8 h2c_content[4] = {0};
1074
1075                 h2c_content[0] = dm->rfe_type_expand;
1076                 h2c_content[1] = dm->rf_type;
1077                 h2c_content[2] = dm->cut_version;
1078                 h2c_content[3] = (dm->tx_ant_status << 4) | dm->rx_ant_status;
1079
1080                 odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_GENERAL_INIT, 4, h2c_content);
1081 #endif
1082         } else {
1083                 PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: Wrong type!!\n", __func__);
1084                 return false;
1085         }
1086
1087         return true;
1088 }
1089
1090 __iram_odm_func__
1091 void config_phydm_switch_rf_set_8821c(struct dm_struct *dm, u8 rf_set)
1092 {
1093 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1094 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1095         void *adapter = dm->adapter;
1096         PMGNT_INFO mgnt_info = &(((PADAPTER)(adapter))->MgntInfo);
1097 #endif
1098
1099         u32 bb_reg32;
1100
1101         odm_set_bb_reg(dm, R_0x1080, BIT(16), 0x1);
1102         odm_set_bb_reg(dm, R_0x00, BIT(26), 0x1);
1103         /*odm_set_mac_reg(dm, R_0x70, BIT(26), 0x1);*/
1104         /*odm_set_mac_reg(dm, R_0x1704, MASKLWORD, 0x4000);*/
1105         /*odm_set_mac_reg(dm, R_0x1700, (BIT(31) | BIT(30)), 0x3); */
1106
1107         bb_reg32 = odm_get_bb_reg(dm, R_0xcb8, MASKDWORD);
1108         switch (rf_set) {
1109         case SWITCH_TO_BTG:
1110
1111                 dm->current_rf_set_8821c = SWITCH_TO_BTG;
1112
1113                 bb_reg32 = (bb_reg32 | BIT(16));
1114                 bb_reg32 &= (~(BIT(18) | BIT(20) | BIT(21) | BIT(22) | BIT(23)));
1115                 odm_set_bb_reg(dm, R_0xa84, MASKBYTE2, 0xe);
1116                 odm_set_bb_reg(dm, R_0xa80, MASKLWORD, 0xfc84);
1117
1118 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1119                 if (*dm->mp_mode == true && mgnt_info->RegPHYParaFromFolder == 0) {
1120 #else
1121                 if (*dm->mp_mode == true) {
1122 #endif
1123                         odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x14);
1124                         odm_config_bb_with_header_file(dm, CONFIG_BB_AGC_TAB_DIFF);
1125                         /*Toggle initial gain twice for valid gain table*/
1126                         odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), 0x22);
1127                         odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), 0x20);
1128                 }
1129                 break;
1130         case SWITCH_TO_WLG:
1131
1132                 dm->current_rf_set_8821c = SWITCH_TO_WLG;
1133
1134                 bb_reg32 = (bb_reg32 | BIT(20) | BIT(21) | BIT(22));
1135                 bb_reg32 &= (~(BIT(16) | BIT(18) | BIT(23)));
1136                 odm_set_bb_reg(dm, R_0xa84, MASKBYTE2, 0x12);
1137                 odm_set_bb_reg(dm, R_0xa80, MASKLWORD, 0x7532);
1138
1139 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1140                 if (*dm->mp_mode == true && mgnt_info->RegPHYParaFromFolder == 0) {
1141 #else
1142                 if (*dm->mp_mode == true) {
1143 #endif
1144                         odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x13);
1145                         odm_config_bb_with_header_file(dm, CONFIG_BB_AGC_TAB_DIFF);
1146                         /*Toggle initial gain twice for valid gain table*/
1147                         odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), 0x22);
1148                         odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), 0x20);
1149                 }
1150                 break;
1151         case SWITCH_TO_WLA:
1152
1153                 dm->current_rf_set_8821c = SWITCH_TO_WLA;
1154
1155                 bb_reg32 = (bb_reg32 | BIT(20) | BIT(22) | BIT(23));
1156                 bb_reg32 &= (~(BIT(16) | BIT(18) | BIT(21)));
1157
1158                 break;
1159         case SWITCH_TO_BT:
1160
1161                 dm->current_rf_set_8821c = SWITCH_TO_BT;
1162
1163                 break;
1164         default:
1165                 break;
1166         }
1167
1168         odm_set_bb_reg(dm, R_0xcb8, MASKDWORD, bb_reg32);
1169 #endif
1170 }
1171
1172 __iram_odm_func__
1173 void config_phydm_set_ant_path(struct dm_struct *dm, u8 rf_set, u8 ant_num)
1174 {
1175 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1176         boolean switch_polarity_inverse = false;
1177         u8 regval_0xcb7 = 0;
1178
1179         dm->current_ant_num_8821c = ant_num;
1180         config_phydm_switch_rf_set_8821c(dm, rf_set);
1181
1182         if (rf_set == SWITCH_TO_BT)
1183                 phydm_set_gnt_state_8821c(dm, false, true); /* GNT_WL=0, GNT_BT=1 for BT test */
1184         else
1185                 phydm_set_gnt_state_8821c(dm, true, false); /* GNT_WL=1, GNT_BT=0 for WL test */
1186
1187         /*switch does not exist*/
1188         if (dm->rfe_type_expand == 0x5 || dm->rfe_type_expand == 0x6 ||
1189             dm->rfe_type_expand == 0x25 || dm->rfe_type_expand == 0x26 ||
1190             dm->rfe_type_expand == 0x2a || dm->rfe_type_expand == 0x2d ||
1191             dm->rfe_type_expand == 0x2e)
1192                 return;
1193
1194         if (dm->current_ant_num_8821c) /*Ant1 = 0, Ant2 = 1*/
1195                 switch_polarity_inverse = !switch_polarity_inverse;
1196
1197         if (rf_set == SWITCH_TO_WLG)
1198                 switch_polarity_inverse = !switch_polarity_inverse;
1199
1200         /*set antenna control by WL 0xcb4[29:28]*/
1201         odm_set_bb_reg(dm, R_0x4c, BIT(24) | BIT(23), 0x2);
1202
1203         /*set RFE_ctrl8 and RFE_ctrl9 as antenna control pins by software*/
1204         odm_set_bb_reg(dm, R_0xcb4, 0x000000ff, 0x77);
1205
1206         /*0xcb4[29:28] = 2b'01 for no switch_polatiry_inverse, DPDT_SEL_N =1, DPDT_SEL_P =0*/
1207         regval_0xcb7 = (!switch_polarity_inverse ? 0x1 : 0x2);
1208
1209         odm_set_bb_reg(dm, R_0xcb4, 0x30000000, regval_0xcb7);
1210 #endif
1211 }
1212
1213 __iram_odm_func__
1214 u32 query_phydm_trx_capability_8821c(struct dm_struct *dm)
1215 {
1216 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1217         u32 value32 = 0x00000000;
1218
1219         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: trx_capability = 0x%x\n", __func__,
1220                   value32);
1221         return value32;
1222 #else
1223         return 0;
1224 #endif
1225 }
1226
1227 __iram_odm_func__
1228 u32 query_phydm_stbc_capability_8821c(struct dm_struct *dm)
1229 {
1230 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1231         u32 value32 = 0x00010001;
1232
1233         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: stbc_capability = 0x%x\n",
1234                   __func__, value32);
1235         return value32;
1236 #else
1237         return 0;
1238 #endif
1239 }
1240
1241 __iram_odm_func__
1242 u32 query_phydm_ldpc_capability_8821c(struct dm_struct *dm)
1243 {
1244 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1245         u32 value32 = 0x01000100;
1246
1247         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: ldpc_capability = 0x%x\n",
1248                   __func__, value32);
1249         return value32;
1250 #else
1251         return 0;
1252 #endif
1253 }
1254
1255 __iram_odm_func__
1256 u32 query_phydm_txbf_parameters_8821c(struct dm_struct *dm)
1257 {
1258 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1259         u32 value32 = 0x00030003;
1260
1261         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: txbf_parameters = 0x%x\n",
1262                   __func__, value32);
1263         return value32;
1264 #else
1265         return 0;
1266 #endif
1267 }
1268
1269 __iram_odm_func__
1270 u32 query_phydm_txbf_capability_8821c(struct dm_struct *dm)
1271 {
1272 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1273         u32 value32 = 0x01010001;
1274
1275         PHYDM_DBG(dm, ODM_PHY_CONFIG, "[%s]: txbf_capability = 0x%x\n",
1276                   __func__, value32);
1277         return value32;
1278 #else
1279         return 0;
1280 #endif
1281 }
1282
1283 __iram_odm_func__
1284 u8 query_phydm_default_rf_set_8821c(struct dm_struct *dm)
1285 {
1286 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1287         return dm->default_rf_set_8821c;
1288 #else
1289         return 0;
1290 #endif
1291 }
1292
1293 __iram_odm_func__
1294 u8 query_phydm_current_rf_set_8821c(struct dm_struct *dm)
1295 {
1296 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1297         return dm->current_rf_set_8821c;
1298 #else
1299         return 0;
1300 #endif
1301 }
1302
1303 __iram_odm_func__
1304 u8 query_phydm_rfetype_8821c(struct dm_struct *dm)
1305 {
1306 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1307         return dm->rfe_type_expand;
1308 #else
1309         return 0;
1310 #endif
1311 }
1312
1313 __iram_odm_func__
1314 u8 query_phydm_current_ant_num_8821c(struct dm_struct *dm)
1315 {
1316 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1317         u32 regval_0xcb4 = odm_get_bb_reg(dm, R_0xcb4, BIT(29) | BIT(28));
1318
1319         if (dm->current_rf_set_8821c == SWITCH_TO_BTG || dm->current_rf_set_8821c == SWITCH_TO_WLA || dm->current_rf_set_8821c == SWITCH_TO_BT) {
1320                 if (regval_0xcb4 == 1)
1321                         dm->current_ant_num_8821c = SWITCH_TO_ANT1;
1322                 else if (regval_0xcb4 == 2)
1323                         dm->current_ant_num_8821c = SWITCH_TO_ANT2;
1324                 else if (regval_0xcb4 == 1)
1325                         dm->current_ant_num_8821c = SWITCH_TO_ANT2;
1326                 else if (regval_0xcb4 == 2)
1327                         dm->current_ant_num_8821c = SWITCH_TO_ANT1;
1328         }
1329
1330         return dm->current_ant_num_8821c;
1331 #else
1332         return 0;
1333 #endif
1334 }
1335
1336 __iram_odm_func__
1337 u8 query_phydm_ant_num_map_8821c(struct dm_struct *dm)
1338 {
1339 #if (PHYDM_FW_API_FUNC_ENABLE_8821C == 1)
1340         u8 mapping_table = 0;
1341
1342         /* mapping table meaning
1343          * 1: choose ant1 or ant2
1344          * 2: only ant1
1345          * 3: only ant2
1346          * 4: cannot choose
1347          */
1348
1349         if (dm->rfe_type_expand == 0 || dm->rfe_type_expand == 7 || dm->rfe_type_expand == 0x20 ||
1350             dm->rfe_type_expand == 0x27 || dm->rfe_type_expand == 0x28 || dm->rfe_type_expand == 0x2f)
1351                 mapping_table = 1;
1352         else if (dm->rfe_type_expand == 1 || dm->rfe_type_expand == 2 || dm->rfe_type_expand == 0x21 ||
1353                  dm->rfe_type_expand == 0x22 || dm->rfe_type_expand == 0x29 || dm->rfe_type_expand == 0x2a)
1354                 mapping_table = 2;
1355         else if (dm->rfe_type_expand == 3 || dm->rfe_type_expand == 4 || dm->rfe_type_expand == 0x23 ||
1356                  dm->rfe_type_expand == 0x24 || dm->rfe_type_expand == 0x2b || dm->rfe_type_expand == 0x2c)
1357                 mapping_table = 3;
1358         else if (dm->rfe_type_expand == 5 || dm->rfe_type_expand == 6 || dm->rfe_type_expand == 0x25 ||
1359                  dm->rfe_type_expand == 0x26 || dm->rfe_type_expand == 0x2d || dm->rfe_type_expand == 0x2e)
1360                 mapping_table = 4;
1361
1362         return mapping_table;
1363 #else
1364         return 0;
1365 #endif
1366 }
1367
1368 /* ======================================================================== */
1369 #endif /*PHYDM_FW_API_ENABLE_8821C == 1*/
1370 #endif /* RTL8821C_SUPPORT == 1 */