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
odm_config_rf_reg_8821c(struct dm_struct * dm,u32 addr,u32 data,enum rf_path rf_path,u32 reg_addr)21 void odm_config_rf_reg_8821c(struct dm_struct *dm, u32 addr, u32 data,
22 enum rf_path rf_path, u32 reg_addr)
23 {
24 if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD) {
25 if (addr == 0xffe) {
26 phydm_set_reg_by_fw(dm,
27 PHYDM_HALMAC_CMD_DELAY_MS,
28 reg_addr,
29 data,
30 RFREGOFFSETMASK,
31 rf_path,
32 50);
33 } else if (addr == 0xfe) {
34 phydm_set_reg_by_fw(dm,
35 PHYDM_HALMAC_CMD_DELAY_US,
36 reg_addr,
37 data,
38 RFREGOFFSETMASK,
39 rf_path,
40 100);
41 } else {
42 phydm_set_reg_by_fw(dm,
43 PHYDM_HALMAC_CMD_RF_W,
44 reg_addr,
45 data,
46 RFREGOFFSETMASK,
47 rf_path,
48 0);
49 phydm_set_reg_by_fw(dm,
50 PHYDM_HALMAC_CMD_DELAY_US,
51 reg_addr,
52 data,
53 RFREGOFFSETMASK,
54 rf_path,
55 1);
56 }
57 } else {
58 if (addr == 0xffe) {
59 #ifdef CONFIG_LONG_DELAY_ISSUE
60 ODM_sleep_ms(50);
61 #else
62 ODM_delay_ms(50);
63 #endif
64 } else if (addr == 0xfe) {
65 #ifdef CONFIG_LONG_DELAY_ISSUE
66 ODM_sleep_us(100);
67 #else
68 ODM_delay_us(100);
69 #endif
70 } else {
71 odm_set_rf_reg(dm, rf_path, reg_addr, RFREGOFFSETMASK, data);
72
73 /* Add 1us delay between BB/RF register setting. */
74 ODM_delay_us(1);
75 }
76 }
77 }
78
odm_config_rf_radio_a_8821c(struct dm_struct * dm,u32 addr,u32 data)79 void odm_config_rf_radio_a_8821c(struct dm_struct *dm, u32 addr, u32 data)
80 {
81 u32 content = 0x1000; /* RF_Content: radioa_txt */
82 u32 maskfor_phy_set = (u32)(content & 0xE000);
83
84 odm_config_rf_reg_8821c(dm, addr, data, RF_PATH_A, addr | maskfor_phy_set);
85
86 PHYDM_DBG(dm, ODM_COMP_INIT,
87 "===> odm_config_rf_with_header_file: [RadioA] %08X %08X\n",
88 addr, data);
89 }
90
odm_config_mac_8821c(struct dm_struct * dm,u32 addr,u8 data)91 void odm_config_mac_8821c(struct dm_struct *dm, u32 addr, u8 data)
92 {
93 if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD)
94 phydm_set_reg_by_fw(dm,
95 PHYDM_HALMAC_CMD_MAC_W8,
96 addr,
97 data,
98 0,
99 (enum rf_path)0,
100 0);
101 else
102 odm_write_1byte(dm, addr, data);
103 PHYDM_DBG(dm, ODM_COMP_INIT, "===> config_mac: [MAC_REG] %08X %08X\n",
104 addr, data);
105 }
106
odm_update_agc_big_jump_lmt_8821c(struct dm_struct * dm,u32 addr,u32 data)107 void odm_update_agc_big_jump_lmt_8821c(struct dm_struct *dm, u32 addr, u32 data)
108 {
109 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
110 u8 rf_gain_idx = (u8)((data & 0xFF000000) >> 24);
111 u8 bb_gain_idx = (u8)((data & 0x00ff0000) >> 16);
112 u8 agc_table_idx = (u8)((data & 0x00000f00) >> 8);
113 static boolean is_limit;
114
115 if (addr != 0x81c)
116 return;
117
118 /*dbg_print("data = 0x%x, rf_gain_idx = 0x%x, bb_gain_idx = 0x%x, agc_table_idx = 0x%x\n", data, rf_gain_idx, bb_gain_idx, agc_table_idx);*/
119 /*dbg_print("rf_gain_idx = 0x%x, dig_t->rf_gain_idx = 0x%x\n", rf_gain_idx, dig_t->rf_gain_idx);*/
120
121 if (bb_gain_idx > 0x3c) {
122 if (rf_gain_idx == dig_t->rf_gain_idx && is_limit == false) {
123 is_limit = true;
124 dig_t->big_jump_lmt[agc_table_idx] = bb_gain_idx - 2;
125 PHYDM_DBG(dm, DBG_DIG,
126 "===> [AGC_TAB] big_jump_lmt [%d] = 0x%x\n",
127 agc_table_idx,
128 dig_t->big_jump_lmt[agc_table_idx]);
129 }
130 } else {
131 is_limit = false;
132 }
133
134 dig_t->rf_gain_idx = rf_gain_idx;
135 }
136
odm_config_bb_agc_8821c(struct dm_struct * dm,u32 addr,u32 bitmask,u32 data)137 void odm_config_bb_agc_8821c(struct dm_struct *dm, u32 addr, u32 bitmask,
138 u32 data)
139 {
140 odm_update_agc_big_jump_lmt_8821c(dm, addr, data);
141
142 if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD)
143 phydm_set_reg_by_fw(dm,
144 PHYDM_HALMAC_CMD_BB_W32,
145 addr,
146 data,
147 bitmask,
148 (enum rf_path)0,
149 0);
150 else
151 odm_set_bb_reg(dm, addr, bitmask, data);
152
153 PHYDM_DBG(dm, ODM_COMP_INIT, "===> config_bb: [AGC_TAB] %08X %08X\n",
154 addr, data);
155 }
156
odm_config_bb_phy_reg_pg_8821c(struct dm_struct * dm,u32 band,u32 rf_path,u32 tx_num,u32 addr,u32 bitmask,u32 data)157 void odm_config_bb_phy_reg_pg_8821c(struct dm_struct *dm, u32 band, u32 rf_path,
158 u32 tx_num, u32 addr, u32 bitmask, u32 data)
159 {
160 #if (DM_ODM_SUPPORT_TYPE & ODM_CE)
161 phy_store_tx_power_by_rate(dm->adapter, band, rf_path, tx_num, addr, bitmask, data);
162 #elif (DM_ODM_SUPPORT_TYPE & ODM_WIN)
163 PHY_StoreTxPowerByRate(dm->adapter, band, rf_path, tx_num, addr, bitmask, data);
164 #endif
165
166 PHYDM_DBG(dm, ODM_COMP_INIT,
167 "===> odm_config_bb_with_header_file: [PHY_REG] %08X %08X %08X\n",
168 addr, bitmask, data);
169 }
170
odm_config_bb_phy_8821c(struct dm_struct * dm,u32 addr,u32 bitmask,u32 data)171 void odm_config_bb_phy_8821c(struct dm_struct *dm, u32 addr, u32 bitmask,
172 u32 data)
173 {
174 if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD) {
175 u32 delay_time = 0;
176
177 if (addr >= 0xf9 && addr <= 0xfe) {
178 if (addr == 0xfe || addr == 0xfb)
179 delay_time = 50;
180 else if (addr == 0xfd || addr == 0xfa)
181 delay_time = 5;
182 else
183 delay_time = 1;
184
185 if (addr >= 0xfc && addr <= 0xfe)
186 phydm_set_reg_by_fw(dm,
187 PHYDM_HALMAC_CMD_DELAY_MS,
188 addr,
189 data,
190 bitmask,
191 (enum rf_path)0,
192 delay_time);
193 else
194 phydm_set_reg_by_fw(dm,
195 PHYDM_HALMAC_CMD_DELAY_US,
196 addr,
197 data,
198 bitmask,
199 (enum rf_path)0,
200 delay_time);
201 } else {
202 phydm_set_reg_by_fw(dm,
203 PHYDM_HALMAC_CMD_BB_W32,
204 addr,
205 data,
206 bitmask,
207 (enum rf_path)0,
208 0);
209 }
210 } else {
211 if (addr == 0xfe)
212 #ifdef CONFIG_LONG_DELAY_ISSUE
213 ODM_sleep_ms(50);
214 #else
215 ODM_delay_ms(50);
216 #endif
217 else if (addr == 0xfd)
218 ODM_delay_ms(5);
219 else if (addr == 0xfc)
220 ODM_delay_ms(1);
221 else if (addr == 0xfb)
222 ODM_delay_us(50);
223 else if (addr == 0xfa)
224 ODM_delay_us(5);
225 else if (addr == 0xf9)
226 ODM_delay_us(1);
227 else
228 odm_set_bb_reg(dm, addr, bitmask, data);
229 }
230
231 PHYDM_DBG(dm, ODM_COMP_INIT, "===> config_bb: [PHY_REG] %08X %08X\n",
232 addr, data);
233 }
234
odm_config_bb_txpwr_lmt_8821c_ex(struct dm_struct * dm,u8 regulation,u8 band,u8 bandwidth,u8 rate_section,u8 rf_path,u8 channel,s8 power_limit)235 void odm_config_bb_txpwr_lmt_8821c_ex(struct dm_struct *dm, u8 regulation,
236 u8 band, u8 bandwidth, u8 rate_section,
237 u8 rf_path, u8 channel, s8 power_limit)
238 {
239
240 #if (DM_ODM_SUPPORT_TYPE & ODM_CE)
241 phy_set_tx_power_limit_ex(dm, regulation, band, bandwidth, rate_section,
242 rf_path, channel, power_limit);
243 #endif
244 #if 0
245 PHY_SetTxPowerLimit_ex(dm, regulation, band, bandwidth, rate_section,
246 rf_path, channel, power_limit);
247 #endif
248 }
odm_config_bb_txpwr_lmt_8821c(struct dm_struct * dm,u8 * regulation,u8 * band,u8 * bandwidth,u8 * rate_section,u8 * rf_path,u8 * channel,u8 * power_limit)249 void odm_config_bb_txpwr_lmt_8821c(struct dm_struct *dm, u8 *regulation,
250 u8 *band, u8 *bandwidth, u8 *rate_section,
251 u8 *rf_path, u8 *channel, u8 *power_limit)
252 {
253 #if (DM_ODM_SUPPORT_TYPE & ODM_CE)
254 phy_set_tx_power_limit(dm, regulation, band,
255 bandwidth, rate_section, rf_path, channel, power_limit);
256 #elif (DM_ODM_SUPPORT_TYPE & ODM_WIN)
257 PHY_SetTxPowerLimit(dm, regulation, band,
258 bandwidth, rate_section, rf_path, channel, power_limit);
259 #endif
260 }
261
262 #endif
263