Changed debugging message in ic_addba_response hook
[ralink_drivers/rt2870_fbsd8.git] / rt2870_rf.c
blob388216c0aac9213afd771d551e0b0e061b9e0b47
2 /*-
3 * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "rt2870_rf.h"
20 #include "rt2870_reg.h"
21 #include "rt2870_eeprom.h"
22 #include "rt2870_io.h"
23 #include "rt2870_debug.h"
26 * Static variables
29 static const struct rt2870_rf_prog
31 uint8_t chan;
32 uint32_t r1, r2, r3, r4;
33 } rt2870_rf_2850[] =
35 { 1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b },
36 { 2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f },
37 { 3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b },
38 { 4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f },
39 { 5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b },
40 { 6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f },
41 { 7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b },
42 { 8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f },
43 { 9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b },
44 { 10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f },
45 { 11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b },
46 { 12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f },
47 { 13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b },
48 { 14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193 },
49 { 36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3 },
50 { 38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193 },
51 { 40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183 },
52 { 44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3 },
53 { 46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b },
54 { 48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b },
55 { 52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193 },
56 { 54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3 },
57 { 56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b },
58 { 60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183 },
59 { 62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193 },
60 { 64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3 },
61 { 100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783 },
62 { 102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793 },
63 { 104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3 },
64 { 108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193 },
65 { 110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183 },
66 { 112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b },
67 { 116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3 },
68 { 118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193 },
69 { 120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183 },
70 { 124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193 },
71 { 126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b },
72 { 128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3 },
73 { 132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b },
74 { 134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193 },
75 { 136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b },
76 { 140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183 },
77 { 149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7 },
78 { 151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187 },
79 { 153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f },
80 { 157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f },
81 { 159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7 },
82 { 161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187 },
83 { 165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197 },
84 { 184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b },
85 { 188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13 },
86 { 192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b },
87 { 196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23 },
88 { 208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13 },
89 { 212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b },
90 { 216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23 },
94 * rt2870_rf_name
96 const char *rt2870_rf_name(int rf_rev)
98 switch (rf_rev)
100 case RT2870_EEPROM_RF_2820:
101 return "RT2820";
103 case RT2870_EEPROM_RF_2850:
104 return "RT2850";
106 case RT2870_EEPROM_RF_2720:
107 return "RT2720";
109 case RT2870_EEPROM_RF_2750:
110 return "RT2750";
112 case RT2870_EEPROM_RF_3020:
113 return "RT3020";
115 case RT2870_EEPROM_RF_2020:
116 return "RT2020";
118 default:
119 return "unknown";
124 * rt2870_rf_select_chan_group
126 void rt2870_rf_select_chan_group(struct rt2870_softc *sc,
127 struct ieee80211_channel *c)
129 struct ifnet *ifp;
130 struct ieee80211com *ic;
131 int chan, group;
132 uint32_t tmp;
134 ifp = sc->ifp;
135 ic = ifp->if_l2com;
137 chan = ieee80211_chan2ieee(ic, c);
138 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
139 return;
141 if (chan <= 14)
142 group = 0;
143 else if (chan <= 64)
144 group = 1;
145 else if (chan <= 128)
146 group = 2;
147 else
148 group = 3;
150 rt2870_io_bbp_write(sc, 62, 0x37 - sc->lna_gain[group]);
151 rt2870_io_bbp_write(sc, 63, 0x37 - sc->lna_gain[group]);
152 rt2870_io_bbp_write(sc, 64, 0x37 - sc->lna_gain[group]);
153 rt2870_io_bbp_write(sc, 86, 0x00);
155 if (group == 0)
157 if (sc->ext_lna_2ghz)
159 rt2870_io_bbp_write(sc, 82, 0x62);
160 rt2870_io_bbp_write(sc, 75, 0x46);
162 else
164 rt2870_io_bbp_write(sc, 82, 0x84);
165 rt2870_io_bbp_write(sc, 75, 0x50);
168 else
170 rt2870_io_bbp_write(sc, 82, 0xf2);
172 if (sc->ext_lna_5ghz)
173 rt2870_io_bbp_write(sc, 75, 0x46);
174 else
175 rt2870_io_bbp_write(sc, 75, 0x50);
178 if (group == 0)
180 tmp = 0x2e + sc->lna_gain[group];
182 else
184 if ((ic->ic_flags & IEEE80211_F_SCAN) || !IEEE80211_IS_CHAN_HT40(c))
185 tmp = 0x32 + sc->lna_gain[group] * 5 / 3;
186 else
187 tmp = 0x3a + sc->lna_gain[group] * 5 / 3;
190 rt2870_io_bbp_write(sc, 66, tmp);
192 tmp = RT2870_REG_RFTR_ENABLE | RT2870_REG_TRSW_ENABLE;
194 if (group == 0)
196 tmp |= RT2870_REG_LNA_PE_A1_ENABLE |
197 RT2870_REG_LNA_PE_G0_ENABLE |
198 RT2870_REG_LNA_PE_A0_ENABLE |
199 RT2870_REG_PA_PE_A1_ENABLE |
200 RT2870_REG_PA_PE_G0_ENABLE |
201 RT2870_REG_PA_PE_A0_ENABLE;
203 if (sc->ntxpath > 1)
204 tmp |= RT2870_REG_PA_PE_G1_ENABLE;
206 if (sc->nrxpath > 1)
207 tmp |= RT2870_REG_LNA_PE_G1_ENABLE;
209 else
211 tmp |= RT2870_REG_LNA_PE_G1_ENABLE |
212 RT2870_REG_LNA_PE_G0_ENABLE |
213 RT2870_REG_LNA_PE_A0_ENABLE |
214 RT2870_REG_PA_PE_G1_ENABLE |
215 RT2870_REG_PA_PE_G0_ENABLE |
216 RT2870_REG_PA_PE_A0_ENABLE;
218 if (sc->ntxpath > 1)
219 tmp |= RT2870_REG_PA_PE_A1_ENABLE;
221 if (sc->nrxpath > 1)
222 tmp |= RT2870_REG_LNA_PE_A1_ENABLE;
225 rt2870_io_mac_write(sc, RT2870_REG_TX_PIN_CFG, tmp);
227 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_BAND_CFG);
229 tmp &= ~(RT2870_REG_TX_BAND_BG | RT2870_REG_TX_BAND_A | RT2870_REG_TX_BAND_HT40_ABOVE);
231 if (group == 0)
232 tmp |= RT2870_REG_TX_BAND_BG;
233 else
234 tmp |= RT2870_REG_TX_BAND_A;
236 /* set central channel position */
238 if (IEEE80211_IS_CHAN_HT40U(c))
239 tmp |= RT2870_REG_TX_BAND_HT40_BELOW;
240 else if (IEEE80211_IS_CHAN_HT40D(c))
241 tmp |= RT2870_REG_TX_BAND_HT40_ABOVE;
242 else
243 tmp |= RT2870_REG_TX_BAND_HT40_BELOW;
245 rt2870_io_mac_write(sc, RT2870_REG_TX_BAND_CFG, tmp);
247 /* set bandwidth (20MHz or 40MHz) */
249 tmp = rt2870_io_bbp_read(sc, 4);
251 tmp &= ~0x18;
253 if (IEEE80211_IS_CHAN_HT40(c))
254 tmp |= 0x10;
256 rt2870_io_bbp_write(sc, 4, tmp);
258 /* set central channel position */
260 tmp = rt2870_io_bbp_read(sc, 3);
262 tmp &= ~0x20;
264 if (IEEE80211_IS_CHAN_HT40D(c))
265 tmp |= 0x20;
267 rt2870_io_bbp_write(sc, 3, tmp);
269 if (sc->mac_rev == 0x28600100)
271 if (!IEEE80211_IS_CHAN_HT40(c))
273 rt2870_io_bbp_write(sc, 69, 0x16);
274 rt2870_io_bbp_write(sc, 70, 0x08);
275 rt2870_io_bbp_write(sc, 73, 0x12);
277 else
279 rt2870_io_bbp_write(sc, 69, 0x1a);
280 rt2870_io_bbp_write(sc, 70, 0x0a);
281 rt2870_io_bbp_write(sc, 73, 0x16);
287 * rt2870_rf_set_chan
289 void rt2870_rf_set_chan(struct rt2870_softc *sc,
290 struct ieee80211_channel *c)
292 struct ifnet *ifp;
293 struct ieee80211com *ic;
294 const struct rt2870_rf_prog *prog;
295 uint32_t r1, r2, r3, r4;
296 int8_t txpow1, txpow2;
297 int i, chan;
299 ifp = sc->ifp;
300 ic = ifp->if_l2com;
301 prog = rt2870_rf_2850;
303 /* get central channel position */
305 chan = ieee80211_chan2ieee(ic, c);
307 if (IEEE80211_IS_CHAN_HT40U(c))
308 chan += 2;
309 else if (IEEE80211_IS_CHAN_HT40D(c))
310 chan -= 2;
312 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
313 "%s: RF set channel: channel=%u, HT%s%s\n",
314 device_get_nameunit(sc->dev),
315 ieee80211_chan2ieee(ic, c),
316 !IEEE80211_IS_CHAN_HT(c) ? " disabled" :
317 IEEE80211_IS_CHAN_HT20(c) ? "20":
318 IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
319 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
321 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
322 return;
324 for (i = 0; prog[i].chan != chan; i++);
326 r1 = prog[i].r1;
327 r2 = prog[i].r2;
328 r3 = prog[i].r3;
329 r4 = prog[i].r4;
331 txpow1 = sc->txpow1[i];
332 txpow2 = sc->txpow2[i];
334 if (sc->ntxpath == 1)
335 r2 |= (1 << 14);
337 if (sc->nrxpath == 2)
338 r2 |= (1 << 6);
339 else if (sc->nrxpath == 1)
340 r2 |= (1 << 17) | (1 << 6);
342 if (IEEE80211_IS_CHAN_2GHZ(c))
344 r3 = (r3 & 0xffffc1ff) | (txpow1 << 9);
345 r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15) | (txpow2 << 6);
347 else
349 r3 = r3 & 0xffffc1ff;
350 r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15);
352 if (txpow1 >= RT2870_EEPROM_TXPOW_5GHZ_MIN && txpow1 < 0)
354 txpow1 = (-RT2870_EEPROM_TXPOW_5GHZ_MIN + txpow1);
355 if (txpow1 > RT2870_EEPROM_TXPOW_5GHZ_MAX)
356 txpow1 = RT2870_EEPROM_TXPOW_5GHZ_MAX;
358 r3 |= (txpow1 << 10);
360 else
362 if (txpow1 > RT2870_EEPROM_TXPOW_5GHZ_MAX)
363 txpow1 = RT2870_EEPROM_TXPOW_5GHZ_MAX;
365 r3 |= (txpow1 << 10) | (1 << 9);
368 if (txpow2 >= RT2870_EEPROM_TXPOW_5GHZ_MIN && txpow2 < 0)
370 txpow2 = (-RT2870_EEPROM_TXPOW_5GHZ_MIN + txpow2);
371 if (txpow2 > RT2870_EEPROM_TXPOW_5GHZ_MAX)
372 txpow2 = RT2870_EEPROM_TXPOW_5GHZ_MAX;
374 r4 |= (txpow2 << 7);
376 else
378 if (txpow2 > RT2870_EEPROM_TXPOW_5GHZ_MAX)
379 txpow2 = RT2870_EEPROM_TXPOW_5GHZ_MAX;
381 r4 |= (txpow2 << 7) | (1 << 6);
385 if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
386 r4 |= (1 << 21);
388 rt2870_io_rf_write(sc, RT2870_REG_RF_R1, r1);
389 rt2870_io_rf_write(sc, RT2870_REG_RF_R2, r2);
390 rt2870_io_rf_write(sc, RT2870_REG_RF_R3, r3 & ~(1 << 2));
391 rt2870_io_rf_write(sc, RT2870_REG_RF_R4, r4);
393 DELAY(200);
395 rt2870_io_rf_write(sc, RT2870_REG_RF_R1, r1);
396 rt2870_io_rf_write(sc, RT2870_REG_RF_R2, r2);
397 rt2870_io_rf_write(sc, RT2870_REG_RF_R3, r3 | (1 << 2));
398 rt2870_io_rf_write(sc, RT2870_REG_RF_R4, r4);
400 DELAY(200);
402 rt2870_io_rf_write(sc, RT2870_REG_RF_R1, r1);
403 rt2870_io_rf_write(sc, RT2870_REG_RF_R2, r2);
404 rt2870_io_rf_write(sc, RT2870_REG_RF_R3, r3 & ~(1 << 2));
405 rt2870_io_rf_write(sc, RT2870_REG_RF_R4, r4);
407 rt2870_rf_select_chan_group(sc, c);
409 DELAY(1000);