Merge tag 'metag-for-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan...
[deliverable/linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192de / rf.c
CommitLineData
f219eff1
CL
1/******************************************************************************
2 *
6a57b08e 3 * Copyright(c) 2009-2012 Realtek Corporation.
f219eff1
CL
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "dm.h"
36#include "hw.h"
37
38void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
39{
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
41 struct rtl_phy *rtlphy = &(rtlpriv->phy);
42 u8 rfpath;
43
44 switch (bandwidth) {
45 case HT_CHANNEL_WIDTH_20:
46 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
47 rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval
48 [rfpath] & 0xfffff3ff) | 0x0400);
49 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) |
50 BIT(11), 0x01);
51
52 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
f30d7507
JP
53 "20M RF 0x18 = 0x%x\n",
54 rtlphy->rfreg_chnlval[rfpath]);
f219eff1
CL
55 }
56
57 break;
58 case HT_CHANNEL_WIDTH_20_40:
59 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
60 rtlphy->rfreg_chnlval[rfpath] =
61 ((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff));
62 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
63 0x00);
64 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
f30d7507
JP
65 "40M RF 0x18 = 0x%x\n",
66 rtlphy->rfreg_chnlval[rfpath]);
f219eff1
CL
67 }
68 break;
69 default:
70 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 71 "unknown bandwidth: %#X\n", bandwidth);
f219eff1
CL
72 break;
73 }
74}
75
76void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
77 u8 *ppowerlevel)
78{
79 struct rtl_priv *rtlpriv = rtl_priv(hw);
80 struct rtl_phy *rtlphy = &(rtlpriv->phy);
81 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
82 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
83 u32 tx_agc[2] = {0, 0}, tmpval;
84 bool turbo_scanoff = false;
85 u8 idx1, idx2;
86 u8 *ptr;
87
88 if (rtlefuse->eeprom_regulatory != 0)
89 turbo_scanoff = true;
9928c7d1 90 if (mac->act_scanning) {
f219eff1
CL
91 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
92 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
93 if (turbo_scanoff) {
94 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
95 tx_agc[idx1] = ppowerlevel[idx1] |
96 (ppowerlevel[idx1] << 8) |
97 (ppowerlevel[idx1] << 16) |
98 (ppowerlevel[idx1] << 24);
99 }
100 }
101 } else {
102 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
103 tx_agc[idx1] = ppowerlevel[idx1] |
104 (ppowerlevel[idx1] << 8) |
105 (ppowerlevel[idx1] << 16) |
106 (ppowerlevel[idx1] << 24);
107 }
108 if (rtlefuse->eeprom_regulatory == 0) {
da17fcff
LF
109 tmpval = (rtlphy->mcs_offset[0][6]) +
110 (rtlphy->mcs_offset[0][7] << 8);
f219eff1 111 tx_agc[RF90_PATH_A] += tmpval;
da17fcff
LF
112 tmpval = (rtlphy->mcs_offset[0][14]) +
113 (rtlphy->mcs_offset[0][15] << 24);
f219eff1
CL
114 tx_agc[RF90_PATH_B] += tmpval;
115 }
116 }
117
118 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
119 ptr = (u8 *) (&(tx_agc[idx1]));
120 for (idx2 = 0; idx2 < 4; idx2++) {
121 if (*ptr > RF6052_MAX_TX_PWR)
122 *ptr = RF6052_MAX_TX_PWR;
123 ptr++;
124 }
125 }
126
127 tmpval = tx_agc[RF90_PATH_A] & 0xff;
25b13dbc 128 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
f219eff1 129 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
130 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
131 tmpval, RTXAGC_A_CCK1_MCS32);
f219eff1
CL
132 tmpval = tx_agc[RF90_PATH_A] >> 8;
133 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
134 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
135 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
136 tmpval, RTXAGC_B_CCK11_A_CCK2_11);
f219eff1 137 tmpval = tx_agc[RF90_PATH_B] >> 24;
25b13dbc 138 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
f219eff1 139 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
140 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
141 tmpval, RTXAGC_B_CCK11_A_CCK2_11);
f219eff1
CL
142 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
143 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
144 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
145 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
146 tmpval, RTXAGC_B_CCK1_55_MCS32);
f219eff1
CL
147}
148
149static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
150 u8 *ppowerlevel, u8 channel,
151 u32 *ofdmbase, u32 *mcsbase)
152{
153 struct rtl_priv *rtlpriv = rtl_priv(hw);
154 struct rtl_phy *rtlphy = &(rtlpriv->phy);
155 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
156 u32 powerbase0, powerbase1;
157 u8 legacy_pwrdiff, ht20_pwrdiff;
158 u8 i, powerlevel[2];
159
160 for (i = 0; i < 2; i++) {
161 powerlevel[i] = ppowerlevel[i];
162 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
163 powerbase0 = powerlevel[i] + legacy_pwrdiff;
164 powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
165 (powerbase0 << 8) | powerbase0;
166 *(ofdmbase + i) = powerbase0;
167 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
168 " [OFDM power base index rf(%c) = 0x%x]\n",
169 i == 0 ? 'A' : 'B', *(ofdmbase + i));
f219eff1
CL
170 }
171
172 for (i = 0; i < 2; i++) {
173 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
174 ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
175 powerlevel[i] += ht20_pwrdiff;
176 }
177 powerbase1 = powerlevel[i];
178 powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
179 (powerbase1 << 8) | powerbase1;
180 *(mcsbase + i) = powerbase1;
181 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
182 " [MCS power base index rf(%c) = 0x%x]\n",
183 i == 0 ? 'A' : 'B', *(mcsbase + i));
f219eff1
CL
184 }
185}
186
187static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
188{
189 u8 group;
190 u8 channel_info[59] = {
191 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
192 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
193 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
194 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
195 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
196 161, 163, 165
197 };
198
199 if (channel_info[chnlindex] <= 3) /* Chanel 1-3 */
200 group = 0;
201 else if (channel_info[chnlindex] <= 9) /* Channel 4-9 */
202 group = 1;
203 else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */
204 group = 2;
205 else if (channel_info[chnlindex] <= 64)
206 group = 6;
207 else if (channel_info[chnlindex] <= 140)
208 group = 7;
209 else
210 group = 8;
211 return group;
212}
213
214static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
215 u8 channel, u8 index,
216 u32 *powerbase0,
217 u32 *powerbase1,
218 u32 *p_outwriteval)
219{
220 struct rtl_priv *rtlpriv = rtl_priv(hw);
221 struct rtl_phy *rtlphy = &(rtlpriv->phy);
222 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
223 u8 i, chnlgroup = 0, pwr_diff_limit[4];
224 u32 writeval = 0, customer_limit, rf;
225
226 for (rf = 0; rf < 2; rf++) {
227 switch (rtlefuse->eeprom_regulatory) {
228 case 0:
229 chnlgroup = 0;
da17fcff 230 writeval = rtlphy->mcs_offset
f219eff1
CL
231 [chnlgroup][index +
232 (rf ? 8 : 0)] + ((index < 2) ?
233 powerbase0[rf] :
234 powerbase1[rf]);
4c48869f
JP
235 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
236 "RTK better performance, writeval(%c) = 0x%x\n",
237 rf == 0 ? 'A' : 'B', writeval);
f219eff1
CL
238 break;
239 case 1:
240 if (rtlphy->pwrgroup_cnt == 1)
241 chnlgroup = 0;
242 if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) {
243 chnlgroup = _rtl92d_phy_get_chnlgroup_bypg(
244 channel - 1);
245 if (rtlphy->current_chan_bw ==
246 HT_CHANNEL_WIDTH_20)
247 chnlgroup++;
248 else
249 chnlgroup += 4;
da17fcff 250 writeval = rtlphy->mcs_offset
f219eff1
CL
251 [chnlgroup][index +
252 (rf ? 8 : 0)] + ((index < 2) ?
253 powerbase0[rf] :
254 powerbase1[rf]);
255 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
256 "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
257 rf == 0 ? 'A' : 'B', writeval);
f219eff1
CL
258 }
259 break;
260 case 2:
261 writeval = ((index < 2) ? powerbase0[rf] :
262 powerbase1[rf]);
4c48869f
JP
263 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
264 "Better regulatory, writeval(%c) = 0x%x\n",
265 rf == 0 ? 'A' : 'B', writeval);
f219eff1
CL
266 break;
267 case 3:
268 chnlgroup = 0;
269 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
270 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
271 "customer's limit, 40MHz rf(%c) = 0x%x\n",
272 rf == 0 ? 'A' : 'B',
f219eff1 273 rtlefuse->pwrgroup_ht40[rf]
4c48869f 274 [channel - 1]);
f219eff1
CL
275 } else {
276 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
277 "customer's limit, 20MHz rf(%c) = 0x%x\n",
278 rf == 0 ? 'A' : 'B',
f219eff1 279 rtlefuse->pwrgroup_ht20[rf]
4c48869f 280 [channel - 1]);
f219eff1
CL
281 }
282 for (i = 0; i < 4; i++) {
da17fcff 283 pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset
f219eff1
CL
284 [chnlgroup][index + (rf ? 8 : 0)] &
285 (0x7f << (i * 8))) >> (i * 8));
286 if (rtlphy->current_chan_bw ==
287 HT_CHANNEL_WIDTH_20_40) {
288 if (pwr_diff_limit[i] >
289 rtlefuse->pwrgroup_ht40[rf]
290 [channel - 1])
291 pwr_diff_limit[i] =
292 rtlefuse->pwrgroup_ht40
293 [rf][channel - 1];
294 } else {
295 if (pwr_diff_limit[i] >
296 rtlefuse->pwrgroup_ht20[rf][
297 channel - 1])
298 pwr_diff_limit[i] =
299 rtlefuse->pwrgroup_ht20[rf]
300 [channel - 1];
301 }
302 }
303 customer_limit = (pwr_diff_limit[3] << 24) |
304 (pwr_diff_limit[2] << 16) |
305 (pwr_diff_limit[1] << 8) |
306 (pwr_diff_limit[0]);
307 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
308 "Customer's limit rf(%c) = 0x%x\n",
309 rf == 0 ? 'A' : 'B', customer_limit);
f219eff1
CL
310 writeval = customer_limit + ((index < 2) ?
311 powerbase0[rf] : powerbase1[rf]);
312 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
313 "Customer, writeval rf(%c)= 0x%x\n",
314 rf == 0 ? 'A' : 'B', writeval);
f219eff1
CL
315 break;
316 default:
317 chnlgroup = 0;
da17fcff 318 writeval = rtlphy->mcs_offset[chnlgroup][index +
f219eff1
CL
319 (rf ? 8 : 0)] + ((index < 2) ?
320 powerbase0[rf] : powerbase1[rf]);
321 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f
JP
322 "RTK better performance, writeval rf(%c) = 0x%x\n",
323 rf == 0 ? 'A' : 'B', writeval);
f219eff1
CL
324 break;
325 }
326 *(p_outwriteval + rf) = writeval;
327 }
328}
329
330static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
331 u8 index, u32 *pvalue)
332{
333 struct rtl_priv *rtlpriv = rtl_priv(hw);
334 struct rtl_phy *rtlphy = &(rtlpriv->phy);
335 static u16 regoffset_a[6] = {
336 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
337 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
338 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
339 };
340 static u16 regoffset_b[6] = {
341 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
342 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
343 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
344 };
345 u8 i, rf, pwr_val[4];
346 u32 writeval;
347 u16 regoffset;
348
349 for (rf = 0; rf < 2; rf++) {
350 writeval = pvalue[rf];
351 for (i = 0; i < 4; i++) {
352 pwr_val[i] = (u8) ((writeval & (0x7f <<
353 (i * 8))) >> (i * 8));
354 if (pwr_val[i] > RF6052_MAX_TX_PWR)
355 pwr_val[i] = RF6052_MAX_TX_PWR;
356 }
357 writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
358 (pwr_val[1] << 8) | pwr_val[0];
359 if (rf == 0)
360 regoffset = regoffset_a[index];
361 else
362 regoffset = regoffset_b[index];
25b13dbc 363 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
f219eff1 364 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
4c48869f 365 "Set 0x%x = %08x\n", regoffset, writeval);
f219eff1
CL
366 if (((get_rf_type(rtlphy) == RF_2T2R) &&
367 (regoffset == RTXAGC_A_MCS15_MCS12 ||
368 regoffset == RTXAGC_B_MCS15_MCS12)) ||
369 ((get_rf_type(rtlphy) != RF_2T2R) &&
370 (regoffset == RTXAGC_A_MCS07_MCS04 ||
371 regoffset == RTXAGC_B_MCS07_MCS04))) {
372 writeval = pwr_val[3];
373 if (regoffset == RTXAGC_A_MCS15_MCS12 ||
374 regoffset == RTXAGC_A_MCS07_MCS04)
375 regoffset = 0xc90;
376 if (regoffset == RTXAGC_B_MCS15_MCS12 ||
377 regoffset == RTXAGC_B_MCS07_MCS04)
378 regoffset = 0xc98;
379 for (i = 0; i < 3; i++) {
380 if (i != 2)
381 writeval = (writeval > 8) ?
382 (writeval - 8) : 0;
383 else
384 writeval = (writeval > 6) ?
385 (writeval - 6) : 0;
386 rtl_write_byte(rtlpriv, (u32) (regoffset + i),
387 (u8) writeval);
388 }
389 }
390 }
391}
392
393void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
394 u8 *ppowerlevel, u8 channel)
395{
396 u32 writeval[2], powerbase0[2], powerbase1[2];
397 u8 index;
398
399 _rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
400 &powerbase0[0], &powerbase1[0]);
401 for (index = 0; index < 6; index++) {
402 _rtl92d_get_txpower_writeval_by_regulatory(hw,
403 channel, index, &powerbase0[0],
404 &powerbase1[0], &writeval[0]);
405 _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
406 }
407}
408
409bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
410{
411 struct rtl_priv *rtlpriv = rtl_priv(hw);
412 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
413 u8 u1btmp;
9928c7d1
LF
414 u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
415 u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
416 u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
f219eff1
CL
417 bool bresult = true; /* true: need to enable BB/RF power */
418
419 rtlhal->during_mac0init_radiob = false;
420 rtlhal->during_mac1init_radioa = false;
f30d7507 421 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
f219eff1
CL
422 /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
423 u1btmp = rtl_read_byte(rtlpriv, mac_reg);
424 if (!(u1btmp & mac_on_bit)) {
f30d7507 425 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
f219eff1
CL
426 /* Enable BB and RF power */
427 rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
428 rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
429 BIT(29) | BIT(16) | BIT(17), direct);
430 } else {
431 /* We think if MAC1 is ON,then radio_a.txt
432 * and radio_b.txt has been load. */
433 bresult = false;
434 }
f30d7507 435 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
f219eff1
CL
436 return bresult;
437
438}
439
440void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
441{
442 struct rtl_priv *rtlpriv = rtl_priv(hw);
443 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
444 u8 u1btmp;
9928c7d1
LF
445 u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
446 u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
447 u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
f219eff1
CL
448
449 rtlhal->during_mac0init_radiob = false;
450 rtlhal->during_mac1init_radioa = false;
f30d7507 451 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
f219eff1
CL
452 /* check MAC0 enable or not again now, if
453 * enabled, not power down radio A. */
454 u1btmp = rtl_read_byte(rtlpriv, mac_reg);
455 if (!(u1btmp & mac_on_bit)) {
f30d7507 456 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
f219eff1
CL
457 /* power down RF radio A according to YuNan's advice. */
458 rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
459 0x00000000, direct);
460 }
f30d7507 461 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
f219eff1
CL
462}
463
464bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
465{
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 struct rtl_phy *rtlphy = &(rtlpriv->phy);
468 bool rtstatus = true;
469 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
470 u32 u4_regvalue = 0;
471 u8 rfpath;
472 struct bb_reg_def *pphyreg;
473 bool mac1_initradioa_first = false, mac0_initradiob_first = false;
474 bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
475 bool true_bpath = false;
476
477 if (rtlphy->rf_type == RF_1T1R)
478 rtlphy->num_total_rfpath = 1;
479 else
480 rtlphy->num_total_rfpath = 2;
481
482 /* Single phy mode: use radio_a radio_b config path_A path_B */
483 /* seperately by MAC0, and MAC1 needn't configure RF; */
484 /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
485 /* MAC1 use radio_b config 2nd PHY path_A. */
486 /* DMDP,MAC0 on G band,MAC1 on A band. */
487 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
488 if (rtlhal->current_bandtype == BAND_ON_2_4G &&
489 rtlhal->interfaceindex == 0) {
490 /* MAC0 needs PHY1 load radio_b.txt.
491 * Driver use DBI to write. */
492 if (rtl92d_phy_enable_anotherphy(hw, true)) {
493 rtlphy->num_total_rfpath = 2;
494 mac0_initradiob_first = true;
495 } else {
496 /* We think if MAC1 is ON,then radio_a.txt and
497 * radio_b.txt has been load. */
498 return rtstatus;
499 }
500 } else if (rtlhal->current_bandtype == BAND_ON_5G &&
501 rtlhal->interfaceindex == 1) {
502 /* MAC1 needs PHY0 load radio_a.txt.
503 * Driver use DBI to write. */
504 if (rtl92d_phy_enable_anotherphy(hw, false)) {
505 rtlphy->num_total_rfpath = 2;
506 mac1_initradioa_first = true;
507 } else {
508 /* We think if MAC0 is ON,then radio_a.txt and
509 * radio_b.txt has been load. */
510 return rtstatus;
511 }
512 } else if (rtlhal->interfaceindex == 1) {
513 /* MAC0 enabled, only init radia B. */
514 true_bpath = true;
515 }
516 }
517
518 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
519 /* Mac1 use PHY0 write */
520 if (mac1_initradioa_first) {
521 if (rfpath == RF90_PATH_A) {
522 rtlhal->during_mac1init_radioa = true;
523 need_pwrdown_radioa = true;
524 } else if (rfpath == RF90_PATH_B) {
525 rtlhal->during_mac1init_radioa = false;
526 mac1_initradioa_first = false;
527 rfpath = RF90_PATH_A;
528 true_bpath = true;
529 rtlphy->num_total_rfpath = 1;
530 }
531 } else if (mac0_initradiob_first) {
532 /* Mac0 use PHY1 write */
533 if (rfpath == RF90_PATH_A)
534 rtlhal->during_mac0init_radiob = false;
535 if (rfpath == RF90_PATH_B) {
536 rtlhal->during_mac0init_radiob = true;
537 mac0_initradiob_first = false;
538 need_pwrdown_radiob = true;
539 rfpath = RF90_PATH_A;
540 true_bpath = true;
541 rtlphy->num_total_rfpath = 1;
542 }
543 }
544 pphyreg = &rtlphy->phyreg_def[rfpath];
545 switch (rfpath) {
546 case RF90_PATH_A:
547 case RF90_PATH_C:
548 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
549 BRFSI_RFENV);
550 break;
551 case RF90_PATH_B:
552 case RF90_PATH_D:
553 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
554 BRFSI_RFENV << 16);
555 break;
556 }
557 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
558 udelay(1);
559 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
560 udelay(1);
561 /* Set bit number of Address and Data for RF register */
562 /* Set 1 to 4 bits for 8255 */
563 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
564 B3WIREADDRESSLENGTH, 0x0);
565 udelay(1);
566 /* Set 0 to 12 bits for 8255 */
567 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
568 udelay(1);
569 switch (rfpath) {
570 case RF90_PATH_A:
9928c7d1 571 if (true_bpath)
f219eff1
CL
572 rtstatus = rtl92d_phy_config_rf_with_headerfile(
573 hw, radiob_txt,
574 (enum radio_path)rfpath);
575 else
576 rtstatus = rtl92d_phy_config_rf_with_headerfile(
577 hw, radioa_txt,
578 (enum radio_path)rfpath);
579 break;
580 case RF90_PATH_B:
581 rtstatus =
582 rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
583 (enum radio_path) rfpath);
584 break;
585 case RF90_PATH_C:
586 break;
587 case RF90_PATH_D:
588 break;
589 }
590 switch (rfpath) {
591 case RF90_PATH_A:
592 case RF90_PATH_C:
593 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
594 u4_regvalue);
595 break;
596 case RF90_PATH_B:
597 case RF90_PATH_D:
598 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
599 u4_regvalue);
600 break;
601 }
23677ce3 602 if (!rtstatus) {
f219eff1 603 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
f30d7507 604 "Radio[%d] Fail!!", rfpath);
f219eff1
CL
605 goto phy_rf_cfg_fail;
606 }
607
608 }
609
610 /* check MAC0 enable or not again, if enabled,
611 * not power down radio A. */
612 /* check MAC1 enable or not again, if enabled,
613 * not power down radio B. */
614 if (need_pwrdown_radioa)
615 rtl92d_phy_powerdown_anotherphy(hw, false);
616 else if (need_pwrdown_radiob)
617 rtl92d_phy_powerdown_anotherphy(hw, true);
f30d7507 618 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
f219eff1
CL
619 return rtstatus;
620
621phy_rf_cfg_fail:
622 return rtstatus;
623}
This page took 0.365979 seconds and 5 git commands to generate.