Convert RSSI into signal strength (relative to noise floor)
[dragonfly/port-amd64.git] / sys / dev / netif / bwi / bwirf.c
blobc0fa5110d6705a02711248c1da43de6b842edd34
1 /*
2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sys/dev/netif/bwi/bwirf.c,v 1.2 2007/09/15 09:59:29 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/endian.h>
39 #include <sys/kernel.h>
40 #include <sys/bus.h>
41 #include <sys/malloc.h>
42 #include <sys/proc.h>
43 #include <sys/rman.h>
44 #include <sys/serialize.h>
45 #include <sys/socket.h>
47 #include <net/ethernet.h>
48 #include <net/if.h>
49 #include <net/bpf.h>
50 #include <net/if_arp.h>
51 #include <net/if_dl.h>
52 #include <net/if_media.h>
53 #include <net/ifq_var.h>
55 #include <netproto/802_11/ieee80211_var.h>
57 #include <bus/pci/pcireg.h>
58 #include <bus/pci/pcivar.h>
59 #include <bus/pci/pcidevs.h>
61 #include "bitops.h"
62 #include "if_bwireg.h"
63 #include "if_bwivar.h"
64 #include "bwiphy.h"
65 #include "bwirf.h"
66 #include "bwimac.h"
68 #define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo))
70 #define BWI_RF_2GHZ_CHAN(chan) \
71 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
73 #define BWI_DEFAULT_IDLE_TSSI 52
75 struct rf_saveregs {
76 uint16_t phy_15;
77 uint16_t phy_2a;
78 uint16_t phy_35;
79 uint16_t phy_60;
80 uint16_t phy_429;
81 uint16_t phy_802;
82 uint16_t phy_811;
83 uint16_t phy_812;
84 uint16_t phy_814;
85 uint16_t phy_815;
87 uint16_t rf_43;
88 uint16_t rf_52;
89 uint16_t rf_7a;
92 #define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n)
93 #define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n)
95 #define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n)
96 #define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
98 static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
99 static void bwi_rf_work_around(struct bwi_mac *, u_int);
100 static int bwi_rf_gain_max_reached(struct bwi_mac *, int);
101 static uint16_t bwi_rf_calibval(struct bwi_mac *);
102 static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *);
103 static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
104 static void bwi_rf_lo_measure(struct bwi_mac *,
105 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
106 static uint8_t _bwi_rf_lo_update(struct bwi_mac *, uint16_t);
108 static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
110 static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
111 static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
112 static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
113 static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
114 static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
116 static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
118 static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
119 const struct bwi_rxbuf_hdr *);
120 static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
121 const struct bwi_rxbuf_hdr *);
122 static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
123 const struct bwi_rxbuf_hdr *);
125 static void bwi_rf_on_11a(struct bwi_mac *);
126 static void bwi_rf_on_11bg(struct bwi_mac *);
128 static void bwi_rf_off_11a(struct bwi_mac *);
129 static void bwi_rf_off_11bg(struct bwi_mac *);
130 static void bwi_rf_off_11g_rev5(struct bwi_mac *);
132 static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] =
133 { BWI_TXPOWER_MAP_11B };
134 static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] =
135 { BWI_TXPOWER_MAP_11G };
137 static __inline int16_t
138 bwi_nrssi_11g(struct bwi_mac *mac)
140 int16_t val;
142 #define NRSSI_11G_MASK __BITS(13, 8)
144 val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
145 if (val >= 32)
146 val -= 64;
147 return val;
149 #undef NRSSI_11G_MASK
152 static __inline struct bwi_rf_lo *
153 bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
155 int n;
157 n = rf_atten + (14 * (bbp_atten / 2));
158 KKASSERT(n < BWI_RFLO_MAX);
160 return &mac->mac_rf.rf_lo[n];
163 static __inline int
164 bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
166 struct bwi_rf *rf = &mac->mac_rf;
167 int idx;
169 idx = lo - rf->rf_lo;
170 KKASSERT(idx >= 0 && idx < BWI_RFLO_MAX);
172 return isset(rf->rf_lo_used, idx);
175 void
176 bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
178 struct bwi_softc *sc = mac->mac_sc;
180 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
181 CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
184 uint16_t
185 bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
187 struct bwi_rf *rf = &mac->mac_rf;
188 struct bwi_softc *sc = mac->mac_sc;
190 ctrl |= rf->rf_ctrl_rd;
191 if (rf->rf_ctrl_adj) {
192 /* XXX */
193 if (ctrl < 0x70)
194 ctrl += 0x80;
195 else if (ctrl < 0x80)
196 ctrl += 0x70;
199 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
200 return CSR_READ_2(sc, BWI_RF_DATA_LO);
204 bwi_rf_attach(struct bwi_mac *mac)
206 struct bwi_softc *sc = mac->mac_sc;
207 struct bwi_rf *rf = &mac->mac_rf;
208 uint16_t type, manu;
209 uint8_t rev;
212 * Get RF manufacture/type/revision
214 if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
216 * Fake a BCM2050 RF
218 manu = BWI_RF_MANUFACT_BCM;
219 type = BWI_RF_T_BCM2050;
220 if (sc->sc_bbp_rev == 0)
221 rev = 3;
222 else if (sc->sc_bbp_rev == 1)
223 rev = 4;
224 else
225 rev = 5;
226 } else {
227 uint32_t val;
229 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
230 val = CSR_READ_2(sc, BWI_RF_DATA_HI);
231 val <<= 16;
233 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
234 val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
236 manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
237 type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
238 rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
240 device_printf(sc->sc_dev, "RF: manu 0x%03x, type 0x%04x, rev %u\n",
241 manu, type, rev);
244 * Verify whether the RF is supported
246 rf->rf_ctrl_rd = 0;
247 rf->rf_ctrl_adj = 0;
248 switch (mac->mac_phy.phy_mode) {
249 case IEEE80211_MODE_11A:
250 if (manu != BWI_RF_MANUFACT_BCM ||
251 type != BWI_RF_T_BCM2060 ||
252 rev != 1) {
253 device_printf(sc->sc_dev, "only BCM2060 rev 1 RF "
254 "is supported for 11A PHY\n");
255 return ENXIO;
257 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
258 rf->rf_on = bwi_rf_on_11a;
259 rf->rf_off = bwi_rf_off_11a;
260 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
261 break;
262 case IEEE80211_MODE_11B:
263 if (type == BWI_RF_T_BCM2050) {
264 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
265 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
266 } else if (type == BWI_RF_T_BCM2053) {
267 rf->rf_ctrl_adj = 1;
268 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
269 } else {
270 device_printf(sc->sc_dev, "only BCM2050/BCM2053 RF "
271 "is supported for 11B PHY\n");
272 return ENXIO;
274 rf->rf_on = bwi_rf_on_11bg;
275 rf->rf_off = bwi_rf_off_11bg;
276 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
277 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
278 break;
279 case IEEE80211_MODE_11G:
280 if (type != BWI_RF_T_BCM2050) {
281 device_printf(sc->sc_dev, "only BCM2050 RF "
282 "is supported for 11G PHY\n");
283 return ENXIO;
285 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
286 rf->rf_on = bwi_rf_on_11bg;
287 if (mac->mac_rev >= 5)
288 rf->rf_off = bwi_rf_off_11g_rev5;
289 else
290 rf->rf_off = bwi_rf_off_11bg;
291 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
292 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
293 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
294 break;
295 default:
296 device_printf(sc->sc_dev, "unsupported PHY mode\n");
297 return ENXIO;
300 rf->rf_type = type;
301 rf->rf_rev = rev;
302 rf->rf_manu = manu;
303 rf->rf_curchan = IEEE80211_CHAN_ANY;
304 rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
305 return 0;
308 void
309 bwi_rf_set_chan(struct bwi_mac *mac, u_int chan, int work_around)
311 struct bwi_softc *sc = mac->mac_sc;
313 if (chan == IEEE80211_CHAN_ANY)
314 return;
316 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
318 /* TODO: 11A */
320 if (work_around)
321 bwi_rf_work_around(mac, chan);
323 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
325 if (chan == 14) {
326 if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
327 HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
328 else
329 HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
330 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
331 } else {
332 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
334 DELAY(8000); /* DELAY(2000); */
336 mac->mac_rf.rf_curchan = chan;
339 void
340 bwi_rf_get_gains(struct bwi_mac *mac)
342 #define SAVE_PHY_MAX 15
343 #define SAVE_RF_MAX 3
345 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
346 { 0x52, 0x43, 0x7a };
347 static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
348 0x0429, 0x0001, 0x0811, 0x0812,
349 0x0814, 0x0815, 0x005a, 0x0059,
350 0x0058, 0x000a, 0x0003, 0x080f,
351 0x0810, 0x002b, 0x0015
354 struct bwi_phy *phy = &mac->mac_phy;
355 struct bwi_rf *rf = &mac->mac_rf;
356 uint16_t save_phy[SAVE_PHY_MAX];
357 uint16_t save_rf[SAVE_RF_MAX];
358 uint16_t trsw;
359 int i, j, loop1_max, loop1, loop2;
362 * Save PHY/RF registers for later restoration
364 for (i = 0; i < SAVE_PHY_MAX; ++i)
365 save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
366 PHY_READ(mac, 0x2d); /* dummy read */
368 for (i = 0; i < SAVE_RF_MAX; ++i)
369 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
371 PHY_CLRBITS(mac, 0x429, 0xc000);
372 PHY_SETBITS(mac, 0x1, 0x8000);
374 PHY_SETBITS(mac, 0x811, 0x2);
375 PHY_CLRBITS(mac, 0x812, 0x2);
376 PHY_SETBITS(mac, 0x811, 0x1);
377 PHY_CLRBITS(mac, 0x812, 0x1);
379 PHY_SETBITS(mac, 0x814, 0x1);
380 PHY_CLRBITS(mac, 0x815, 0x1);
381 PHY_SETBITS(mac, 0x814, 0x2);
382 PHY_CLRBITS(mac, 0x815, 0x2);
384 PHY_SETBITS(mac, 0x811, 0xc);
385 PHY_SETBITS(mac, 0x812, 0xc);
386 PHY_SETBITS(mac, 0x811, 0x30);
387 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
389 PHY_WRITE(mac, 0x5a, 0x780);
390 PHY_WRITE(mac, 0x59, 0xc810);
391 PHY_WRITE(mac, 0x58, 0xd);
392 PHY_SETBITS(mac, 0xa, 0x2000);
394 PHY_SETBITS(mac, 0x814, 0x4);
395 PHY_CLRBITS(mac, 0x815, 0x4);
397 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
399 if (rf->rf_rev == 8) {
400 loop1_max = 15;
401 RF_WRITE(mac, 0x43, loop1_max);
402 } else {
403 loop1_max = 9;
404 RF_WRITE(mac, 0x52, 0x0);
405 RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
408 bwi_phy_set_bbp_atten(mac, 11);
410 if (phy->phy_rev >= 3)
411 PHY_WRITE(mac, 0x80f, 0xc020);
412 else
413 PHY_WRITE(mac, 0x80f, 0x8020);
414 PHY_WRITE(mac, 0x810, 0);
416 PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
417 PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
418 PHY_SETBITS(mac, 0x811, 0x100);
419 PHY_CLRBITS(mac, 0x812, 0x3000);
421 if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
422 phy->phy_rev >= 7) {
423 PHY_SETBITS(mac, 0x811, 0x800);
424 PHY_SETBITS(mac, 0x812, 0x8000);
426 RF_CLRBITS(mac, 0x7a, 0xff08);
429 * Find out 'loop1/loop2', which will be used to calculate
430 * max loopback gain later
432 j = 0;
433 for (i = 0; i < loop1_max; ++i) {
434 for (j = 0; j < 16; ++j) {
435 RF_WRITE(mac, 0x43, i);
437 if (bwi_rf_gain_max_reached(mac, j))
438 goto loop1_exit;
441 loop1_exit:
442 loop1 = i;
443 loop2 = j;
446 * Find out 'trsw', which will be used to calculate
447 * TRSW(TX/RX switch) RX gain later
449 if (loop2 >= 8) {
450 PHY_SETBITS(mac, 0x812, 0x30);
451 trsw = 0x1b;
452 for (i = loop2 - 8; i < 16; ++i) {
453 trsw -= 3;
454 if (bwi_rf_gain_max_reached(mac, i))
455 break;
457 } else {
458 trsw = 0x18;
462 * Restore saved PHY/RF registers
464 /* First 4 saved PHY registers need special processing */
465 for (i = 4; i < SAVE_PHY_MAX; ++i)
466 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
468 bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
470 for (i = 0; i < SAVE_RF_MAX; ++i)
471 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
473 PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
474 DELAY(10);
475 PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
476 PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
477 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
478 PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
481 * Calculate gains
483 rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
484 rf->rf_rx_gain = trsw * 2;
485 DPRINTF(mac->mac_sc, "lo gain: %u, rx gain: %u\n",
486 rf->rf_lo_gain, rf->rf_rx_gain);
488 #undef SAVE_RF_MAX
489 #undef SAVE_PHY_MAX
492 void
493 bwi_rf_init(struct bwi_mac *mac)
495 struct bwi_rf *rf = &mac->mac_rf;
497 if (rf->rf_type == BWI_RF_T_BCM2060) {
498 /* TODO: 11A */
499 } else {
500 if (rf->rf_flags & BWI_RF_F_INITED)
501 RF_WRITE(mac, 0x78, rf->rf_calib);
502 else
503 bwi_rf_init_bcm2050(mac);
507 static void
508 bwi_rf_off_11a(struct bwi_mac *mac)
510 RF_WRITE(mac, 0x4, 0xff);
511 RF_WRITE(mac, 0x5, 0xfb);
513 PHY_SETBITS(mac, 0x10, 0x8);
514 PHY_SETBITS(mac, 0x11, 0x8);
516 PHY_WRITE(mac, 0x15, 0xaa00);
519 static void
520 bwi_rf_off_11bg(struct bwi_mac *mac)
522 PHY_WRITE(mac, 0x15, 0xaa00);
525 static void
526 bwi_rf_off_11g_rev5(struct bwi_mac *mac)
528 PHY_SETBITS(mac, 0x811, 0x8c);
529 PHY_CLRBITS(mac, 0x812, 0x8c);
532 static void
533 bwi_rf_work_around(struct bwi_mac *mac, u_int chan)
535 struct bwi_softc *sc = mac->mac_sc;
536 struct bwi_rf *rf = &mac->mac_rf;
538 if (chan == IEEE80211_CHAN_ANY) {
539 if_printf(&mac->mac_sc->sc_ic.ic_if,
540 "%s invalid channel!!\n", __func__);
541 return;
544 if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
545 return;
547 if (chan <= 10)
548 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
549 else
550 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
551 DELAY(1000);
552 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
555 static __inline struct bwi_rf_lo *
556 bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
558 uint16_t rf_atten, bbp_atten;
559 int remap_rf_atten;
561 remap_rf_atten = 1;
562 if (tpctl == NULL) {
563 bbp_atten = 2;
564 rf_atten = 3;
565 } else {
566 if (tpctl->tp_ctrl1 == 3)
567 remap_rf_atten = 0;
569 bbp_atten = tpctl->bbp_atten;
570 rf_atten = tpctl->rf_atten;
572 if (bbp_atten > 6)
573 bbp_atten = 6;
576 if (remap_rf_atten) {
577 #define MAP_MAX 10
578 static const uint16_t map[MAP_MAX] =
579 { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
581 #if 0
582 KKASSERT(rf_atten < MAP_MAX);
583 rf_atten = map[rf_atten];
584 #else
585 if (rf_atten >= MAP_MAX) {
586 rf_atten = 0; /* XXX */
587 } else {
588 rf_atten = map[rf_atten];
590 #endif
591 #undef MAP_MAX
594 return bwi_get_rf_lo(mac, rf_atten, bbp_atten);
597 void
598 bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
600 const struct bwi_rf_lo *lo;
602 lo = bwi_rf_lo_find(mac, tpctl);
603 RF_LO_WRITE(mac, lo);
606 static void
607 bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
609 uint16_t val;
611 val = (uint8_t)lo->ctrl_lo;
612 val |= ((uint8_t)lo->ctrl_hi) << 8;
614 PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
617 static int
618 bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
620 PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
621 PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
622 PHY_SETBITS(mac, 0x15, 0xf000);
624 DELAY(20);
626 return (PHY_READ(mac, 0x2d) >= 0xdfc);
629 /* XXX use bitmap array */
630 static __inline uint16_t
631 bitswap4(uint16_t val)
633 uint16_t ret;
635 ret = (val & 0x8) >> 3;
636 ret |= (val & 0x4) >> 1;
637 ret |= (val & 0x2) << 1;
638 ret |= (val & 0x1) << 3;
639 return ret;
642 static __inline uint16_t
643 bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
645 struct bwi_softc *sc = mac->mac_sc;
646 struct bwi_phy *phy = &mac->mac_phy;
647 struct bwi_rf *rf = &mac->mac_rf;
648 uint16_t lo_gain, ext_lna, loop;
650 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
651 return 0;
653 lo_gain = rf->rf_lo_gain;
654 if (rf->rf_rev == 8)
655 lo_gain += 0x3e;
656 else
657 lo_gain += 0x26;
659 if (lo_gain >= 0x46) {
660 lo_gain -= 0x46;
661 ext_lna = 0x3000;
662 } else if (lo_gain >= 0x3a) {
663 lo_gain -= 0x3a;
664 ext_lna = 0x1000;
665 } else if (lo_gain >= 0x2e) {
666 lo_gain -= 0x2e;
667 ext_lna = 0x2000;
668 } else {
669 lo_gain -= 0x10;
670 ext_lna = 0;
673 for (loop = 0; loop < 16; ++loop) {
674 lo_gain -= (6 * loop);
675 if (lo_gain < 6)
676 break;
679 if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
680 if (ext_lna)
681 ext_lna |= 0x8000;
682 ext_lna |= (loop << 8);
683 switch (lpd) {
684 case 0x011:
685 return 0x8f92;
686 case 0x001:
687 return (0x8092 | ext_lna);
688 case 0x101:
689 return (0x2092 | ext_lna);
690 case 0x100:
691 return (0x2093 | ext_lna);
692 default:
693 panic("unsupported lpd\n");
695 } else {
696 ext_lna |= (loop << 8);
697 switch (lpd) {
698 case 0x011:
699 return 0xf92;
700 case 0x001:
701 case 0x101:
702 return (0x92 | ext_lna);
703 case 0x100:
704 return (0x93 | ext_lna);
705 default:
706 panic("unsupported lpd\n");
710 panic("never reached\n");
711 return 0;
714 void
715 bwi_rf_init_bcm2050(struct bwi_mac *mac)
717 #define SAVE_RF_MAX 3
718 #define SAVE_PHY_COMM_MAX 4
719 #define SAVE_PHY_11G_MAX 6
721 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
722 { 0x0043, 0x0051, 0x0052 };
723 static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
724 { 0x0015, 0x005a, 0x0059, 0x0058 };
725 static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
726 { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
728 uint16_t save_rf[SAVE_RF_MAX];
729 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
730 uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
731 uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
732 uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
733 uint16_t phy812_val;
734 uint16_t calib;
735 uint32_t test_lim, test;
736 struct bwi_softc *sc = mac->mac_sc;
737 struct bwi_phy *phy = &mac->mac_phy;
738 struct bwi_rf *rf = &mac->mac_rf;
739 int i;
742 * Save registers for later restoring
744 for (i = 0; i < SAVE_RF_MAX; ++i)
745 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
746 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
747 save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
749 if (phy->phy_mode == IEEE80211_MODE_11B) {
750 phyr_30 = PHY_READ(mac, 0x30);
751 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
753 PHY_WRITE(mac, 0x30, 0xff);
754 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
755 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
756 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
757 save_phy_11g[i] =
758 PHY_READ(mac, save_phy_regs_11g[i]);
761 PHY_SETBITS(mac, 0x814, 0x3);
762 PHY_CLRBITS(mac, 0x815, 0x3);
763 PHY_CLRBITS(mac, 0x429, 0x8000);
764 PHY_CLRBITS(mac, 0x802, 0x3);
766 phyr_80f = PHY_READ(mac, 0x80f);
767 phyr_810 = PHY_READ(mac, 0x810);
769 if (phy->phy_rev >= 3)
770 PHY_WRITE(mac, 0x80f, 0xc020);
771 else
772 PHY_WRITE(mac, 0x80f, 0x8020);
773 PHY_WRITE(mac, 0x810, 0);
775 phy812_val = bwi_phy812_value(mac, 0x011);
776 PHY_WRITE(mac, 0x812, phy812_val);
777 if (phy->phy_rev < 7 ||
778 (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
779 PHY_WRITE(mac, 0x811, 0x1b3);
780 else
781 PHY_WRITE(mac, 0x811, 0x9b3);
783 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
785 phyr_35 = PHY_READ(mac, 0x35);
786 PHY_CLRBITS(mac, 0x35, 0x80);
788 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
789 rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
791 if (phy->phy_version == 0) {
792 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
793 } else {
794 if (phy->phy_version >= 2)
795 PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
796 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
799 calib = bwi_rf_calibval(mac);
801 if (phy->phy_mode == IEEE80211_MODE_11B)
802 RF_WRITE(mac, 0x78, 0x26);
804 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
805 phy812_val = bwi_phy812_value(mac, 0x011);
806 PHY_WRITE(mac, 0x812, phy812_val);
809 PHY_WRITE(mac, 0x15, 0xbfaf);
810 PHY_WRITE(mac, 0x2b, 0x1403);
812 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
813 phy812_val = bwi_phy812_value(mac, 0x001);
814 PHY_WRITE(mac, 0x812, phy812_val);
817 PHY_WRITE(mac, 0x15, 0xbfa0);
819 RF_SETBITS(mac, 0x51, 0x4);
820 if (rf->rf_rev == 8) {
821 RF_WRITE(mac, 0x43, 0x1f);
822 } else {
823 RF_WRITE(mac, 0x52, 0);
824 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
827 test_lim = 0;
828 PHY_WRITE(mac, 0x58, 0);
829 for (i = 0; i < 16; ++i) {
830 PHY_WRITE(mac, 0x5a, 0x480);
831 PHY_WRITE(mac, 0x59, 0xc810);
833 PHY_WRITE(mac, 0x58, 0xd);
834 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
835 phy812_val = bwi_phy812_value(mac, 0x101);
836 PHY_WRITE(mac, 0x812, phy812_val);
838 PHY_WRITE(mac, 0x15, 0xafb0);
839 DELAY(10);
841 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
842 phy812_val = bwi_phy812_value(mac, 0x101);
843 PHY_WRITE(mac, 0x812, phy812_val);
845 PHY_WRITE(mac, 0x15, 0xefb0);
846 DELAY(10);
848 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
849 phy812_val = bwi_phy812_value(mac, 0x100);
850 PHY_WRITE(mac, 0x812, phy812_val);
852 PHY_WRITE(mac, 0x15, 0xfff0);
853 DELAY(20);
855 test_lim += PHY_READ(mac, 0x2d);
857 PHY_WRITE(mac, 0x58, 0);
858 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
859 phy812_val = bwi_phy812_value(mac, 0x101);
860 PHY_WRITE(mac, 0x812, phy812_val);
862 PHY_WRITE(mac, 0x15, 0xafb0);
864 ++test_lim;
865 test_lim >>= 9;
867 DELAY(10);
869 test = 0;
870 PHY_WRITE(mac, 0x58, 0);
871 for (i = 0; i < 16; ++i) {
872 int j;
874 rfr_78 = (bitswap4(i) << 1) | 0x20;
875 RF_WRITE(mac, 0x78, rfr_78);
876 DELAY(10);
878 /* NB: This block is slight different than the above one */
879 for (j = 0; j < 16; ++j) {
880 PHY_WRITE(mac, 0x5a, 0xd80);
881 PHY_WRITE(mac, 0x59, 0xc810);
883 PHY_WRITE(mac, 0x58, 0xd);
884 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
885 phy->phy_rev >= 2) {
886 phy812_val = bwi_phy812_value(mac, 0x101);
887 PHY_WRITE(mac, 0x812, phy812_val);
889 PHY_WRITE(mac, 0x15, 0xafb0);
890 DELAY(10);
892 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
893 phy->phy_rev >= 2) {
894 phy812_val = bwi_phy812_value(mac, 0x101);
895 PHY_WRITE(mac, 0x812, phy812_val);
897 PHY_WRITE(mac, 0x15, 0xefb0);
898 DELAY(10);
900 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
901 phy->phy_rev >= 2) {
902 phy812_val = bwi_phy812_value(mac, 0x100);
903 PHY_WRITE(mac, 0x812, phy812_val);
905 PHY_WRITE(mac, 0x15, 0xfff0);
906 DELAY(10);
908 test += PHY_READ(mac, 0x2d);
910 PHY_WRITE(mac, 0x58, 0);
911 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
912 phy->phy_rev >= 2) {
913 phy812_val = bwi_phy812_value(mac, 0x101);
914 PHY_WRITE(mac, 0x812, phy812_val);
916 PHY_WRITE(mac, 0x15, 0xafb0);
919 ++test;
920 test >>= 8;
922 if (test > test_lim)
923 break;
925 if (i > 15)
926 rf->rf_calib = rfr_78;
927 else
928 rf->rf_calib = calib;
929 if (rf->rf_calib != 0xffff) {
930 DPRINTF(sc, "RF calibration value: 0x%04x\n", rf->rf_calib);
931 rf->rf_flags |= BWI_RF_F_INITED;
935 * Restore trashes registers
937 PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
939 for (i = 0; i < SAVE_RF_MAX; ++i) {
940 int pos = (i + 1) % SAVE_RF_MAX;
942 RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
944 for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
945 PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
947 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
948 if (phy->phy_version != 0)
949 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
951 PHY_WRITE(mac, 0x35, phyr_35);
952 bwi_rf_work_around(mac, rf->rf_curchan);
954 if (phy->phy_mode == IEEE80211_MODE_11B) {
955 PHY_WRITE(mac, 0x30, phyr_30);
956 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
957 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
958 /* XXX Spec only says when PHY is linked (gmode) */
959 CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
961 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
962 PHY_WRITE(mac, save_phy_regs_11g[i],
963 save_phy_11g[i]);
966 PHY_WRITE(mac, 0x80f, phyr_80f);
967 PHY_WRITE(mac, 0x810, phyr_810);
970 #undef SAVE_PHY_11G_MAX
971 #undef SAVE_PHY_COMM_MAX
972 #undef SAVE_RF_MAX
975 static uint16_t
976 bwi_rf_calibval(struct bwi_mac *mac)
978 /* http://bcm-specs.sipsolutions.net/RCCTable */
979 static const uint16_t rf_calibvals[] = {
980 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
981 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
983 uint16_t val, calib;
984 int idx;
986 val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
987 idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
988 KKASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
990 calib = rf_calibvals[idx] << 1;
991 if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
992 calib |= 0x1;
993 calib |= 0x20;
995 return calib;
998 static __inline int32_t
999 _bwi_adjust_devide(int32_t num, int32_t den)
1001 if (num < 0)
1002 return (num / den);
1003 else
1004 return (num + den / 2) / den;
1008 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
1009 * "calculating table entries"
1011 static int
1012 bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
1014 int32_t m1, m2, f, dbm;
1015 int i;
1017 m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
1018 m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
1020 #define ITER_MAX 16
1022 f = 256;
1023 for (i = 0; i < ITER_MAX; ++i) {
1024 int32_t q, d;
1026 q = _bwi_adjust_devide(
1027 f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
1028 d = abs(q - f);
1029 f = q;
1031 if (d < 2)
1032 break;
1034 if (i == ITER_MAX)
1035 return EINVAL;
1037 #undef ITER_MAX
1039 dbm = _bwi_adjust_devide(m1 * f, 8192);
1040 if (dbm < -127)
1041 dbm = -127;
1042 else if (dbm > 128)
1043 dbm = 128;
1045 *txpwr = dbm;
1046 return 0;
1050 bwi_rf_map_txpower(struct bwi_mac *mac)
1052 struct bwi_softc *sc = mac->mac_sc;
1053 struct bwi_rf *rf = &mac->mac_rf;
1054 struct bwi_phy *phy = &mac->mac_phy;
1055 uint16_t sprom_ofs, val, mask;
1056 int16_t pa_params[3];
1057 int error = 0, i, ant_gain, reg_txpower_max;
1060 * Find out max TX power
1062 val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
1063 if (phy->phy_mode == IEEE80211_MODE_11A) {
1064 rf->rf_txpower_max = __SHIFTOUT(val,
1065 BWI_SPROM_MAX_TXPWR_MASK_11A);
1066 } else {
1067 rf->rf_txpower_max = __SHIFTOUT(val,
1068 BWI_SPROM_MAX_TXPWR_MASK_11BG);
1070 if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
1071 phy->phy_mode == IEEE80211_MODE_11G)
1072 rf->rf_txpower_max -= 3;
1074 if (rf->rf_txpower_max <= 0) {
1075 device_printf(sc->sc_dev, "invalid max txpower in sprom\n");
1076 rf->rf_txpower_max = 74;
1078 DPRINTF(sc, "max txpower from sprom: %d dBm\n", rf->rf_txpower_max);
1081 * Find out region/domain max TX power, which is adjusted
1082 * by antenna gain and 1.5 dBm fluctuation as mentioned
1083 * in v3 spec.
1085 val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
1086 if (phy->phy_mode == IEEE80211_MODE_11A)
1087 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
1088 else
1089 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
1090 if (ant_gain == 0xff) {
1091 device_printf(sc->sc_dev, "invalid antenna gain in sprom\n");
1092 ant_gain = 2;
1094 ant_gain *= 4;
1095 DPRINTF(sc, "ant gain %d dBm\n", ant_gain);
1097 reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */
1098 DPRINTF(sc, "region/domain max txpower %d dBm\n", reg_txpower_max);
1101 * Force max TX power within region/domain TX power limit
1103 if (rf->rf_txpower_max > reg_txpower_max)
1104 rf->rf_txpower_max = reg_txpower_max;
1105 DPRINTF(sc, "max txpower %d dBm\n", rf->rf_txpower_max);
1108 * Create TSSI to TX power mapping
1111 if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
1112 rf->rf_type != BWI_RF_T_BCM2050) {
1113 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
1114 bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0,
1115 sizeof(rf->rf_txpower_map0));
1116 goto back;
1119 #define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1)
1120 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1123 * Extract PA parameters
1125 if (phy->phy_mode == IEEE80211_MODE_11A)
1126 sprom_ofs = BWI_SPROM_PA_PARAM_11A;
1127 else
1128 sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
1129 for (i = 0; i < N(pa_params); ++i)
1130 pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
1132 for (i = 0; i < N(pa_params); ++i) {
1134 * If one of the PA parameters from SPROM is not valid,
1135 * fall back to the default values, if there are any.
1137 if (!IS_VALID_PA_PARAM(pa_params[i])) {
1138 const int8_t *txpower_map;
1140 if (phy->phy_mode == IEEE80211_MODE_11A) {
1141 if_printf(&sc->sc_ic.ic_if,
1142 "no tssi2dbm table for 11a PHY\n");
1143 return ENXIO;
1146 if (phy->phy_mode == IEEE80211_MODE_11G) {
1147 DPRINTF(sc, "%s\n", "use default 11g TSSI map");
1148 txpower_map = bwi_txpower_map_11g;
1149 } else {
1150 txpower_map = bwi_txpower_map_11b;
1153 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
1154 bcopy(txpower_map, rf->rf_txpower_map0,
1155 sizeof(rf->rf_txpower_map0));
1156 goto back;
1160 #undef N
1163 * All of the PA parameters from SPROM are valid.
1167 * Extract idle TSSI from SPROM.
1169 val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
1170 DPRINTF(sc, "sprom idle tssi: 0x%04x\n", val);
1172 if (phy->phy_mode == IEEE80211_MODE_11A)
1173 mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
1174 else
1175 mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
1177 rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
1178 if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
1179 rf->rf_idle_tssi0 = 62;
1181 #undef IS_VALID_PA_PARAM
1184 * Calculate TX power map, which is indexed by TSSI
1186 device_printf(sc->sc_dev, "TSSI-TX power map:\n");
1187 for (i = 0; i < BWI_TSSI_MAX; ++i) {
1188 error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
1189 pa_params);
1190 if (error) {
1191 if_printf(&sc->sc_ic.ic_if,
1192 "bwi_rf_calc_txpower failed\n");
1193 break;
1195 if (i != 0 && i % 8 == 0)
1196 kprintf("\n");
1197 kprintf("%d ", rf->rf_txpower_map0[i]);
1199 kprintf("\n");
1200 back:
1201 DPRINTF(sc, "idle tssi0: %d\n", rf->rf_idle_tssi0);
1202 return error;
1205 void
1206 bwi_rf_lo_update(struct bwi_mac *mac)
1208 struct bwi_softc *sc = mac->mac_sc;
1209 struct ifnet *ifp = &sc->sc_ic.ic_if;
1210 struct bwi_rf *rf = &mac->mac_rf;
1211 struct bwi_phy *phy = &mac->mac_phy;
1212 struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1213 struct rf_saveregs regs;
1214 uint16_t ant_div, chan_ex;
1215 uint8_t devi_ctrl;
1216 u_int orig_chan;
1219 * Save RF/PHY registers for later restoration
1221 orig_chan = rf->rf_curchan;
1222 bzero(&regs, sizeof(regs));
1224 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1225 SAVE_PHY_REG(mac, &regs, 429);
1226 SAVE_PHY_REG(mac, &regs, 802);
1228 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
1229 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
1232 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1233 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
1234 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1236 SAVE_PHY_REG(mac, &regs, 15);
1237 SAVE_PHY_REG(mac, &regs, 2a);
1238 SAVE_PHY_REG(mac, &regs, 35);
1239 SAVE_PHY_REG(mac, &regs, 60);
1240 SAVE_RF_REG(mac, &regs, 43);
1241 SAVE_RF_REG(mac, &regs, 7a);
1242 SAVE_RF_REG(mac, &regs, 52);
1243 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1244 SAVE_PHY_REG(mac, &regs, 811);
1245 SAVE_PHY_REG(mac, &regs, 812);
1246 SAVE_PHY_REG(mac, &regs, 814);
1247 SAVE_PHY_REG(mac, &regs, 815);
1250 /* Force to channel 6 */
1251 bwi_rf_set_chan(mac, 6, 0);
1253 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1254 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
1255 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
1256 bwi_mac_dummy_xmit(mac);
1258 RF_WRITE(mac, 0x43, 0x6);
1260 bwi_phy_set_bbp_atten(mac, 2);
1262 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
1264 PHY_WRITE(mac, 0x2e, 0x7f);
1265 PHY_WRITE(mac, 0x80f, 0x78);
1266 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
1267 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
1268 PHY_WRITE(mac, 0x2b, 0x203);
1269 PHY_WRITE(mac, 0x2a, 0x8a3);
1271 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1272 PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
1273 PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
1274 PHY_WRITE(mac, 0x811, 0x1b3);
1275 PHY_WRITE(mac, 0x812, 0xb2);
1278 if ((ifp->if_flags & IFF_RUNNING) == 0)
1279 tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
1280 PHY_WRITE(mac, 0x80f, 0x8078);
1283 * Measure all RF LO
1285 devi_ctrl = _bwi_rf_lo_update(mac, regs.rf_7a);
1288 * Restore saved RF/PHY registers
1290 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1291 PHY_WRITE(mac, 0x15, 0xe300);
1292 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
1293 DELAY(5);
1294 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
1295 DELAY(2);
1296 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
1297 } else {
1298 PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
1301 if ((ifp->if_flags & IFF_RUNNING) == 0)
1302 tpctl = NULL;
1303 bwi_rf_lo_adjust(mac, tpctl);
1305 PHY_WRITE(mac, 0x2e, 0x807f);
1306 if (phy->phy_flags & BWI_PHY_F_LINKED)
1307 PHY_WRITE(mac, 0x2f, 0x202);
1308 else
1309 PHY_WRITE(mac, 0x2f, 0x101);
1311 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
1313 RESTORE_PHY_REG(mac, &regs, 15);
1314 RESTORE_PHY_REG(mac, &regs, 2a);
1315 RESTORE_PHY_REG(mac, &regs, 35);
1316 RESTORE_PHY_REG(mac, &regs, 60);
1318 RESTORE_RF_REG(mac, &regs, 43);
1319 RESTORE_RF_REG(mac, &regs, 7a);
1321 regs.rf_52 &= 0xf0;
1322 regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
1323 RF_WRITE(mac, 0x52, regs.rf_52);
1325 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
1327 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1328 RESTORE_PHY_REG(mac, &regs, 811);
1329 RESTORE_PHY_REG(mac, &regs, 812);
1330 RESTORE_PHY_REG(mac, &regs, 814);
1331 RESTORE_PHY_REG(mac, &regs, 815);
1332 RESTORE_PHY_REG(mac, &regs, 429);
1333 RESTORE_PHY_REG(mac, &regs, 802);
1336 bwi_rf_set_chan(mac, orig_chan, 1);
1339 static uint32_t
1340 bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
1342 struct bwi_phy *phy = &mac->mac_phy;
1343 uint32_t devi = 0;
1344 int i;
1346 if (phy->phy_flags & BWI_PHY_F_LINKED)
1347 ctrl <<= 8;
1349 for (i = 0; i < 8; ++i) {
1350 if (phy->phy_flags & BWI_PHY_F_LINKED) {
1351 PHY_WRITE(mac, 0x15, 0xe300);
1352 PHY_WRITE(mac, 0x812, ctrl | 0xb0);
1353 DELAY(5);
1354 PHY_WRITE(mac, 0x812, ctrl | 0xb2);
1355 DELAY(2);
1356 PHY_WRITE(mac, 0x812, ctrl | 0xb3);
1357 DELAY(4);
1358 PHY_WRITE(mac, 0x15, 0xf300);
1359 } else {
1360 PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
1361 DELAY(2);
1362 PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
1363 DELAY(4);
1364 PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
1366 DELAY(8);
1367 devi += PHY_READ(mac, 0x2d);
1369 return devi;
1372 static uint16_t
1373 bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
1375 uint32_t devi_min;
1376 uint16_t tp_ctrl2 = 0;
1377 int i;
1379 RF_WRITE(mac, 0x52, 0);
1380 DELAY(10);
1381 devi_min = bwi_rf_lo_devi_measure(mac, 0);
1383 for (i = 0; i < 16; ++i) {
1384 uint32_t devi;
1386 RF_WRITE(mac, 0x52, i);
1387 DELAY(10);
1388 devi = bwi_rf_lo_devi_measure(mac, 0);
1390 if (devi < devi_min) {
1391 devi_min = devi;
1392 tp_ctrl2 = i;
1395 return tp_ctrl2;
1398 static uint8_t
1399 _bwi_rf_lo_update(struct bwi_mac *mac, uint16_t orig_rf7a)
1401 #define RF_ATTEN_LISTSZ 14
1402 #define BBP_ATTEN_MAX 4 /* half */
1404 static const int rf_atten_list[RF_ATTEN_LISTSZ] =
1405 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
1406 static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
1407 { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
1408 static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
1409 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
1411 struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if;
1412 struct bwi_rf_lo lo_save, *lo;
1413 uint8_t devi_ctrl = 0;
1414 int idx, adj_rf7a = 0;
1416 bzero(&lo_save, sizeof(lo_save));
1417 for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
1418 int init_rf_atten = rf_atten_init_list[idx];
1419 int rf_atten = rf_atten_list[idx];
1420 int bbp_atten;
1422 for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
1423 uint16_t tp_ctrl2, rf7a;
1425 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1426 if (idx == 0) {
1427 bzero(&lo_save, sizeof(lo_save));
1428 } else if (init_rf_atten < 0) {
1429 lo = bwi_get_rf_lo(mac,
1430 rf_atten, 2 * bbp_atten);
1431 bcopy(lo, &lo_save, sizeof(lo_save));
1432 } else {
1433 lo = bwi_get_rf_lo(mac,
1434 init_rf_atten, 0);
1435 bcopy(lo, &lo_save, sizeof(lo_save));
1438 devi_ctrl = 0;
1439 adj_rf7a = 0;
1442 * XXX
1443 * Linux driver overflows 'val'
1445 if (init_rf_atten >= 0) {
1446 int val;
1448 val = rf_atten * 2 + bbp_atten;
1449 if (val > 14) {
1450 adj_rf7a = 1;
1451 if (val > 17)
1452 devi_ctrl = 1;
1453 if (val > 19)
1454 devi_ctrl = 2;
1457 } else {
1458 lo = bwi_get_rf_lo(mac,
1459 rf_atten, 2 * bbp_atten);
1460 if (!bwi_rf_lo_isused(mac, lo))
1461 continue;
1462 bcopy(lo, &lo_save, sizeof(lo_save));
1464 devi_ctrl = 3;
1465 adj_rf7a = 0;
1468 RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
1470 tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
1471 if (init_rf_atten < 0)
1472 tp_ctrl2 |= (3 << 4);
1473 RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
1475 DELAY(10);
1477 bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
1479 rf7a = orig_rf7a & 0xfff0;
1480 if (adj_rf7a)
1481 rf7a |= 0x8;
1482 RF_WRITE(mac, 0x7a, rf7a);
1484 lo = bwi_get_rf_lo(mac,
1485 rf_lo_measure_order[idx], bbp_atten * 2);
1486 bwi_rf_lo_measure(mac, &lo_save, lo, devi_ctrl);
1489 return devi_ctrl;
1491 #undef RF_ATTEN_LISTSZ
1492 #undef BBP_ATTEN_MAX
1495 static void
1496 bwi_rf_lo_measure(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
1497 struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
1499 #define LO_ADJUST_MIN 1
1500 #define LO_ADJUST_MAX 8
1501 #define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo }
1502 static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
1503 LO_ADJUST(1, 1),
1504 LO_ADJUST(1, 0),
1505 LO_ADJUST(1, -1),
1506 LO_ADJUST(0, -1),
1507 LO_ADJUST(-1, -1),
1508 LO_ADJUST(-1, 0),
1509 LO_ADJUST(-1, 1),
1510 LO_ADJUST(0, 1)
1512 #undef LO_ADJUST
1514 struct bwi_rf_lo lo_min;
1515 uint32_t devi_min;
1516 int found, loop_count, adjust_state;
1518 bcopy(src_lo, &lo_min, sizeof(lo_min));
1519 RF_LO_WRITE(mac, &lo_min);
1520 devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
1522 loop_count = 12; /* XXX */
1523 adjust_state = 0;
1524 do {
1525 struct bwi_rf_lo lo_base;
1526 int i, fin;
1528 found = 0;
1529 if (adjust_state == 0) {
1530 i = LO_ADJUST_MIN;
1531 fin = LO_ADJUST_MAX;
1532 } else if (adjust_state % 2 == 0) {
1533 i = adjust_state - 1;
1534 fin = adjust_state + 1;
1535 } else {
1536 i = adjust_state - 2;
1537 fin = adjust_state + 2;
1540 if (i < LO_ADJUST_MIN)
1541 i += LO_ADJUST_MAX;
1542 KKASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
1544 if (fin > LO_ADJUST_MAX)
1545 fin -= LO_ADJUST_MAX;
1546 KKASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
1548 bcopy(&lo_min, &lo_base, sizeof(lo_base));
1549 for (;;) {
1550 struct bwi_rf_lo lo;
1552 lo.ctrl_hi = lo_base.ctrl_hi +
1553 rf_lo_adjust[i - 1].ctrl_hi;
1554 lo.ctrl_lo = lo_base.ctrl_lo +
1555 rf_lo_adjust[i - 1].ctrl_lo;
1557 if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
1558 uint32_t devi;
1560 RF_LO_WRITE(mac, &lo);
1561 devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
1562 if (devi < devi_min) {
1563 devi_min = devi;
1564 adjust_state = i;
1565 found = 1;
1566 bcopy(&lo, &lo_min, sizeof(lo_min));
1569 if (i == fin)
1570 break;
1571 if (i == LO_ADJUST_MAX)
1572 i = LO_ADJUST_MIN;
1573 else
1574 ++i;
1576 } while (loop_count-- && found);
1578 bcopy(&lo_min, dst_lo, sizeof(*dst_lo));
1580 #undef LO_ADJUST_MIN
1581 #undef LO_ADJUST_MAX
1584 static void
1585 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
1587 #define SAVE_RF_MAX 3
1588 #define SAVE_PHY_MAX 8
1590 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1591 { 0x7a, 0x52, 0x43 };
1592 static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
1593 { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
1595 struct bwi_softc *sc = mac->mac_sc;
1596 struct bwi_rf *rf = &mac->mac_rf;
1597 struct bwi_phy *phy = &mac->mac_phy;
1598 uint16_t save_rf[SAVE_RF_MAX];
1599 uint16_t save_phy[SAVE_PHY_MAX];
1600 uint16_t ant_div, bbp_atten, chan_ex;
1601 int16_t nrssi[2];
1602 int i;
1605 * Save RF/PHY registers for later restoration
1607 for (i = 0; i < SAVE_RF_MAX; ++i)
1608 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1609 for (i = 0; i < SAVE_PHY_MAX; ++i)
1610 save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
1612 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1613 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
1614 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1617 * Calculate nrssi0
1619 if (phy->phy_rev >= 5)
1620 RF_CLRBITS(mac, 0x7a, 0xff80);
1621 else
1622 RF_CLRBITS(mac, 0x7a, 0xfff0);
1623 PHY_WRITE(mac, 0x30, 0xff);
1625 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
1627 PHY_WRITE(mac, 0x26, 0);
1628 PHY_SETBITS(mac, 0x15, 0x20);
1629 PHY_WRITE(mac, 0x2a, 0x8a3);
1630 RF_SETBITS(mac, 0x7a, 0x80);
1632 nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
1635 * Calculate nrssi1
1637 RF_CLRBITS(mac, 0x7a, 0xff80);
1638 if (phy->phy_version >= 2)
1639 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
1640 else if (phy->phy_version == 0)
1641 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
1642 else
1643 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
1645 PHY_WRITE(mac, 0x20, 0x3f3f);
1646 PHY_WRITE(mac, 0x15, 0xf330);
1648 RF_WRITE(mac, 0x5a, 0x60);
1649 RF_CLRBITS(mac, 0x43, 0xff0f);
1651 PHY_WRITE(mac, 0x5a, 0x480);
1652 PHY_WRITE(mac, 0x59, 0x810);
1653 PHY_WRITE(mac, 0x58, 0xd);
1655 DELAY(20);
1657 nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
1660 * Restore saved RF/PHY registers
1662 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
1663 RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
1665 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
1667 for (i = 1; i < 4; ++i)
1668 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
1670 bwi_rf_work_around(mac, rf->rf_curchan);
1672 if (phy->phy_version != 0)
1673 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
1675 for (; i < SAVE_PHY_MAX; ++i)
1676 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
1678 for (i = 1; i < SAVE_RF_MAX; ++i)
1679 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
1682 * Install calculated narrow RSSI values
1684 if (nrssi[0] == nrssi[1])
1685 rf->rf_nrssi_slope = 0x10000;
1686 else
1687 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
1688 if (nrssi[0] <= -4) {
1689 rf->rf_nrssi[0] = nrssi[0];
1690 rf->rf_nrssi[1] = nrssi[1];
1693 #undef SAVE_RF_MAX
1694 #undef SAVE_PHY_MAX
1697 static void
1698 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
1700 #define SAVE_RF_MAX 2
1701 #define SAVE_PHY_COMM_MAX 10
1702 #define SAVE_PHY6_MAX 8
1704 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1705 { 0x7a, 0x43 };
1706 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
1707 0x0001, 0x0811, 0x0812, 0x0814,
1708 0x0815, 0x005a, 0x0059, 0x0058,
1709 0x000a, 0x0003
1711 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
1712 0x002e, 0x002f, 0x080f, 0x0810,
1713 0x0801, 0x0060, 0x0014, 0x0478
1716 struct bwi_phy *phy = &mac->mac_phy;
1717 uint16_t save_rf[SAVE_RF_MAX];
1718 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
1719 uint16_t save_phy6[SAVE_PHY6_MAX];
1720 uint16_t rf7b = 0xffff;
1721 int16_t nrssi;
1722 int i, phy6_idx = 0;
1724 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
1725 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
1726 for (i = 0; i < SAVE_RF_MAX; ++i)
1727 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1729 PHY_CLRBITS(mac, 0x429, 0x8000);
1730 PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
1731 PHY_SETBITS(mac, 0x811, 0xc);
1732 PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
1733 PHY_CLRBITS(mac, 0x802, 0x3);
1735 if (phy->phy_rev >= 6) {
1736 for (i = 0; i < SAVE_PHY6_MAX; ++i)
1737 save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
1739 PHY_WRITE(mac, 0x2e, 0);
1740 PHY_WRITE(mac, 0x2f, 0);
1741 PHY_WRITE(mac, 0x80f, 0);
1742 PHY_WRITE(mac, 0x810, 0);
1743 PHY_SETBITS(mac, 0x478, 0x100);
1744 PHY_SETBITS(mac, 0x801, 0x40);
1745 PHY_SETBITS(mac, 0x60, 0x40);
1746 PHY_SETBITS(mac, 0x14, 0x200);
1749 RF_SETBITS(mac, 0x7a, 0x70);
1750 RF_SETBITS(mac, 0x7a, 0x80);
1752 DELAY(30);
1754 nrssi = bwi_nrssi_11g(mac);
1755 if (nrssi == 31) {
1756 for (i = 7; i >= 4; --i) {
1757 RF_WRITE(mac, 0x7b, i);
1758 DELAY(20);
1759 nrssi = bwi_nrssi_11g(mac);
1760 if (nrssi < 31 && rf7b == 0xffff)
1761 rf7b = i;
1763 if (rf7b == 0xffff)
1764 rf7b = 4;
1765 } else {
1766 struct bwi_gains gains;
1768 RF_CLRBITS(mac, 0x7a, 0xff80);
1770 PHY_SETBITS(mac, 0x814, 0x1);
1771 PHY_CLRBITS(mac, 0x815, 0x1);
1772 PHY_SETBITS(mac, 0x811, 0xc);
1773 PHY_SETBITS(mac, 0x812, 0xc);
1774 PHY_SETBITS(mac, 0x811, 0x30);
1775 PHY_SETBITS(mac, 0x812, 0x30);
1776 PHY_WRITE(mac, 0x5a, 0x480);
1777 PHY_WRITE(mac, 0x59, 0x810);
1778 PHY_WRITE(mac, 0x58, 0xd);
1779 if (phy->phy_version == 0)
1780 PHY_WRITE(mac, 0x3, 0x122);
1781 else
1782 PHY_SETBITS(mac, 0xa, 0x2000);
1783 PHY_SETBITS(mac, 0x814, 0x4);
1784 PHY_CLRBITS(mac, 0x815, 0x4);
1785 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
1786 RF_SETBITS(mac, 0x7a, 0xf);
1788 bzero(&gains, sizeof(gains));
1789 gains.tbl_gain1 = 3;
1790 gains.tbl_gain2 = 0;
1791 gains.phy_gain = 1;
1792 bwi_set_gains(mac, &gains);
1794 RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
1795 DELAY(30);
1797 nrssi = bwi_nrssi_11g(mac);
1798 if (nrssi == -32) {
1799 for (i = 0; i < 4; ++i) {
1800 RF_WRITE(mac, 0x7b, i);
1801 DELAY(20);
1802 nrssi = bwi_nrssi_11g(mac);
1803 if (nrssi > -31 && rf7b == 0xffff)
1804 rf7b = i;
1806 if (rf7b == 0xffff)
1807 rf7b = 3;
1808 } else {
1809 rf7b = 0;
1812 RF_WRITE(mac, 0x7b, rf7b);
1815 * Restore saved RF/PHY registers
1817 if (phy->phy_rev >= 6) {
1818 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
1819 PHY_WRITE(mac, save_phy6_regs[phy6_idx],
1820 save_phy6[phy6_idx]);
1824 /* Saved PHY registers 0, 1, 2 are handled later */
1825 for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
1826 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
1828 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
1829 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
1831 PHY_SETBITS(mac, 0x802, 0x3);
1832 PHY_SETBITS(mac, 0x429, 0x8000);
1834 bwi_set_gains(mac, NULL);
1836 if (phy->phy_rev >= 6) {
1837 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
1838 PHY_WRITE(mac, save_phy6_regs[phy6_idx],
1839 save_phy6[phy6_idx]);
1843 PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
1844 PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
1845 PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
1847 #undef SAVE_RF_MAX
1848 #undef SAVE_PHY_COMM_MAX
1849 #undef SAVE_PHY6_MAX
1852 static void
1853 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
1855 #define SAVE_RF_MAX 3
1856 #define SAVE_PHY_COMM_MAX 4
1857 #define SAVE_PHY3_MAX 8
1859 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1860 { 0x7a, 0x52, 0x43 };
1861 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
1862 { 0x15, 0x5a, 0x59, 0x58 };
1863 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
1864 0x002e, 0x002f, 0x080f, 0x0810,
1865 0x0801, 0x0060, 0x0014, 0x0478
1868 struct bwi_softc *sc = mac->mac_sc;
1869 struct bwi_phy *phy = &mac->mac_phy;
1870 struct bwi_rf *rf = &mac->mac_rf;
1871 uint16_t save_rf[SAVE_RF_MAX];
1872 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
1873 uint16_t save_phy3[SAVE_PHY3_MAX];
1874 uint16_t ant_div, bbp_atten, chan_ex;
1875 struct bwi_gains gains;
1876 int16_t nrssi[2];
1877 int i, phy3_idx = 0;
1879 if (rf->rf_rev >= 9)
1880 return;
1881 else if (rf->rf_rev == 8)
1882 bwi_rf_set_nrssi_ofs_11g(mac);
1884 PHY_CLRBITS(mac, 0x429, 0x8000);
1885 PHY_CLRBITS(mac, 0x802, 0x3);
1888 * Save RF/PHY registers for later restoration
1890 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1891 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
1893 for (i = 0; i < SAVE_RF_MAX; ++i)
1894 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1895 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
1896 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
1898 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
1899 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1901 if (phy->phy_rev >= 3) {
1902 for (i = 0; i < SAVE_PHY3_MAX; ++i)
1903 save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
1905 PHY_WRITE(mac, 0x2e, 0);
1906 PHY_WRITE(mac, 0x810, 0);
1908 if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
1909 phy->phy_rev == 7) {
1910 PHY_SETBITS(mac, 0x478, 0x100);
1911 PHY_SETBITS(mac, 0x810, 0x40);
1912 } else if (phy->phy_rev == 3 || phy->phy_rev == 5) {
1913 PHY_CLRBITS(mac, 0x810, 0x40);
1916 PHY_SETBITS(mac, 0x60, 0x40);
1917 PHY_SETBITS(mac, 0x14, 0x200);
1921 * Calculate nrssi0
1923 RF_SETBITS(mac, 0x7a, 0x70);
1925 bzero(&gains, sizeof(gains));
1926 gains.tbl_gain1 = 0;
1927 gains.tbl_gain2 = 8;
1928 gains.phy_gain = 0;
1929 bwi_set_gains(mac, &gains);
1931 RF_CLRBITS(mac, 0x7a, 0xff08);
1932 if (phy->phy_rev >= 2) {
1933 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
1934 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
1937 RF_SETBITS(mac, 0x7a, 0x80);
1938 DELAY(20);
1939 nrssi[0] = bwi_nrssi_11g(mac);
1942 * Calculate nrssi1
1944 RF_CLRBITS(mac, 0x7a, 0xff80);
1945 if (phy->phy_version >= 2)
1946 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
1947 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
1949 RF_SETBITS(mac, 0x7a, 0xf);
1950 PHY_WRITE(mac, 0x15, 0xf330);
1951 if (phy->phy_rev >= 2) {
1952 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
1953 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
1956 bzero(&gains, sizeof(gains));
1957 gains.tbl_gain1 = 3;
1958 gains.tbl_gain2 = 0;
1959 gains.phy_gain = 1;
1960 bwi_set_gains(mac, &gains);
1962 if (rf->rf_rev == 8) {
1963 RF_WRITE(mac, 0x43, 0x1f);
1964 } else {
1965 RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
1966 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
1968 PHY_WRITE(mac, 0x5a, 0x480);
1969 PHY_WRITE(mac, 0x59, 0x810);
1970 PHY_WRITE(mac, 0x58, 0xd);
1971 DELAY(20);
1973 nrssi[1] = bwi_nrssi_11g(mac);
1976 * Install calculated narrow RSSI values
1978 if (nrssi[1] == nrssi[0])
1979 rf->rf_nrssi_slope = 0x10000;
1980 else
1981 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
1982 if (nrssi[0] >= -4) {
1983 rf->rf_nrssi[0] = nrssi[1];
1984 rf->rf_nrssi[1] = nrssi[0];
1988 * Restore saved RF/PHY registers
1990 if (phy->phy_rev >= 3) {
1991 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
1992 PHY_WRITE(mac, save_phy3_regs[phy3_idx],
1993 save_phy3[phy3_idx]);
1996 if (phy->phy_rev >= 2) {
1997 PHY_CLRBITS(mac, 0x812, 0x30);
1998 PHY_CLRBITS(mac, 0x811, 0x30);
2001 for (i = 0; i < SAVE_RF_MAX; ++i)
2002 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
2004 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
2005 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
2006 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
2008 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2009 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
2011 bwi_rf_work_around(mac, rf->rf_curchan);
2012 PHY_SETBITS(mac, 0x802, 0x3);
2013 bwi_set_gains(mac, NULL);
2014 PHY_SETBITS(mac, 0x429, 0x8000);
2016 if (phy->phy_rev >= 3) {
2017 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
2018 PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2019 save_phy3[phy3_idx]);
2023 bwi_rf_init_sw_nrssi_table(mac);
2024 bwi_rf_set_nrssi_thr_11g(mac);
2026 #undef SAVE_RF_MAX
2027 #undef SAVE_PHY_COMM_MAX
2028 #undef SAVE_PHY3_MAX
2031 static void
2032 bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
2034 struct bwi_rf *rf = &mac->mac_rf;
2035 int d, i;
2037 d = 0x1f - rf->rf_nrssi[0];
2038 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
2039 int val;
2041 val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
2042 if (val < 0)
2043 val = 0;
2044 else if (val > 0x3f)
2045 val = 0x3f;
2047 rf->rf_nrssi_table[i] = val;
2051 void
2052 bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
2054 int i;
2056 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
2057 int16_t val;
2059 val = bwi_nrssi_read(mac, i);
2061 val -= adjust;
2062 if (val < -32)
2063 val = -32;
2064 else if (val > 31);
2065 val = 31;
2067 bwi_nrssi_write(mac, i, val);
2071 static void
2072 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
2074 struct bwi_rf *rf = &mac->mac_rf;
2075 int32_t thr;
2077 if (rf->rf_type != BWI_RF_T_BCM2050 ||
2078 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
2079 return;
2082 * Calculate nrssi threshold
2084 if (rf->rf_rev >= 6) {
2085 thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
2086 thr += 20 * (rf->rf_nrssi[0] + 1);
2087 thr /= 40;
2088 } else {
2089 thr = rf->rf_nrssi[1] - 5;
2091 if (thr < 0)
2092 thr = 0;
2093 else if (thr > 0x3e)
2094 thr = 0x3e;
2096 PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B); /* dummy read */
2097 PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
2099 if (rf->rf_rev >= 6) {
2100 PHY_WRITE(mac, 0x87, 0xe0d);
2101 PHY_WRITE(mac, 0x86, 0xc0b);
2102 PHY_WRITE(mac, 0x85, 0xa09);
2103 PHY_WRITE(mac, 0x84, 0x808);
2104 PHY_WRITE(mac, 0x83, 0x808);
2105 PHY_WRITE(mac, 0x82, 0x604);
2106 PHY_WRITE(mac, 0x81, 0x302);
2107 PHY_WRITE(mac, 0x80, 0x100);
2111 static __inline int32_t
2112 _nrssi_threshold(const struct bwi_rf *rf, int32_t val)
2114 val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
2115 val += (rf->rf_nrssi[0] << 6);
2116 if (val < 32)
2117 val += 31;
2118 else
2119 val += 32;
2120 val >>= 6;
2121 if (val < -31)
2122 val = -31;
2123 else if (val > 31)
2124 val = 31;
2125 return val;
2128 static void
2129 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
2131 int32_t thr1, thr2;
2132 uint16_t thr;
2135 * Find the two nrssi thresholds
2137 if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
2138 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
2139 int16_t nrssi;
2141 nrssi = bwi_nrssi_read(mac, 0x20);
2142 if (nrssi >= 32)
2143 nrssi -= 64;
2145 if (nrssi < 3) {
2146 thr1 = 0x2b;
2147 thr2 = 0x27;
2148 } else {
2149 thr1 = 0x2d;
2150 thr2 = 0x2b;
2152 } else {
2153 /* TODO Interfere mode */
2154 thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
2155 thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
2158 #define NRSSI_THR1_MASK __BITS(5, 0)
2159 #define NRSSI_THR2_MASK __BITS(11, 6)
2161 thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
2162 __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
2163 PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
2165 #undef NRSSI_THR1_MASK
2166 #undef NRSSI_THR2_MASK
2169 void
2170 bwi_rf_clear_tssi(struct bwi_mac *mac)
2172 /* XXX use function pointer */
2173 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
2174 /* TODO:11A */
2175 } else {
2176 uint16_t val;
2177 int i;
2179 val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
2180 __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
2182 for (i = 0; i < 2; ++i) {
2183 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
2184 BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
2187 for (i = 0; i < 2; ++i) {
2188 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
2189 BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
2194 void
2195 bwi_rf_clear_state(struct bwi_rf *rf)
2197 int i;
2199 rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
2200 bzero(rf->rf_lo, sizeof(rf->rf_lo));
2201 bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used));
2203 rf->rf_nrssi_slope = 0;
2204 rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
2205 rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
2207 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
2208 rf->rf_nrssi_table[i] = i;
2210 rf->rf_lo_gain = 0;
2211 rf->rf_rx_gain = 0;
2213 bcopy(rf->rf_txpower_map0, rf->rf_txpower_map,
2214 sizeof(rf->rf_txpower_map));
2215 rf->rf_idle_tssi = rf->rf_idle_tssi0;
2218 static void
2219 bwi_rf_on_11a(struct bwi_mac *mac)
2221 /* TODO:11A */
2224 static void
2225 bwi_rf_on_11bg(struct bwi_mac *mac)
2227 struct bwi_phy *phy = &mac->mac_phy;
2229 PHY_WRITE(mac, 0x15, 0x8000);
2230 PHY_WRITE(mac, 0x15, 0xcc00);
2231 if (phy->phy_flags & BWI_PHY_F_LINKED)
2232 PHY_WRITE(mac, 0x15, 0xc0);
2233 else
2234 PHY_WRITE(mac, 0x15, 0);
2236 bwi_rf_set_chan(mac, 6 /* XXX */, 1);
2239 void
2240 bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
2242 struct bwi_softc *sc = mac->mac_sc;
2243 struct bwi_phy *phy = &mac->mac_phy;
2244 uint16_t val;
2246 KKASSERT(ant_mode == BWI_ANT_MODE_0 ||
2247 ant_mode == BWI_ANT_MODE_1 ||
2248 ant_mode == BWI_ANT_MODE_AUTO);
2250 HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
2252 if (phy->phy_mode == IEEE80211_MODE_11B) {
2253 /* NOTE: v4/v3 conflicts, take v3 */
2254 if (mac->mac_rev == 2)
2255 val = BWI_ANT_MODE_AUTO;
2256 else
2257 val = ant_mode;
2258 val <<= 7;
2259 PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
2260 } else { /* 11a/g */
2261 /* XXX reg/value naming */
2262 val = ant_mode << 7;
2263 PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
2265 if (ant_mode == BWI_ANT_MODE_AUTO)
2266 PHY_CLRBITS(mac, 0x42b, 0x100);
2268 if (phy->phy_mode == IEEE80211_MODE_11A) {
2269 /* TODO:11A */
2270 } else { /* 11g */
2271 if (ant_mode == BWI_ANT_MODE_AUTO)
2272 PHY_SETBITS(mac, 0x48c, 0x2000);
2273 else
2274 PHY_CLRBITS(mac, 0x48c, 0x2000);
2276 if (phy->phy_rev >= 2) {
2277 PHY_SETBITS(mac, 0x461, 0x10);
2278 PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
2279 if (phy->phy_rev == 2) {
2280 PHY_WRITE(mac, 0x427, 0x8);
2281 } else {
2282 PHY_FILT_SETBITS(mac, 0x427,
2283 0xff00, 0x8);
2286 if (phy->phy_rev >= 6)
2287 PHY_WRITE(mac, 0x49b, 0xdc);
2292 /* XXX v4 set AUTO_ANTDIV unconditionally */
2293 if (ant_mode == BWI_ANT_MODE_AUTO)
2294 HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
2296 val = ant_mode << 8;
2297 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
2298 0xfc3f, val);
2299 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
2300 0xfc3f, val);
2301 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
2302 0xfc3f, val);
2304 /* XXX what's these */
2305 if (phy->phy_mode == IEEE80211_MODE_11B)
2306 CSR_SETBITS_2(sc, 0x5e, 0x4);
2308 CSR_WRITE_4(sc, 0x100, 0x1000000);
2309 if (mac->mac_rev < 5)
2310 CSR_WRITE_4(sc, 0x10c, 0x1000000);
2312 mac->mac_rf.rf_ant_mode = ant_mode;
2316 bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
2318 int i;
2320 for (i = 0; i < 4; ) {
2321 uint16_t val;
2323 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
2324 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
2325 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
2328 for (i = 0; i < 4; ++i) {
2329 if (tssi[i] == BWI_INVALID_TSSI)
2330 return EINVAL;
2332 return 0;
2336 bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
2338 struct bwi_rf *rf = &mac->mac_rf;
2339 int pwr_idx;
2341 pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
2342 #if 0
2343 if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
2344 return EINVAL;
2345 #else
2346 if (pwr_idx < 0)
2347 pwr_idx = 0;
2348 else if (pwr_idx >= BWI_TSSI_MAX)
2349 pwr_idx = BWI_TSSI_MAX - 1;
2350 #endif
2352 *txpwr = rf->rf_txpower_map[pwr_idx];
2353 return 0;
2356 static int
2357 bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2359 uint16_t flags1, flags3;
2360 int rssi, lna_gain;
2362 rssi = hdr->rxh_rssi;
2363 flags1 = le16toh(hdr->rxh_flags1);
2364 flags3 = le16toh(hdr->rxh_flags3);
2366 #define NEW_BCM2050_RSSI
2367 #ifdef NEW_BCM2050_RSSI
2368 if (flags1 & BWI_RXH_F1_OFDM) {
2369 if (rssi > 127)
2370 rssi -= 256;
2371 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2372 rssi += 17;
2373 else
2374 rssi -= 4;
2375 return rssi;
2378 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
2379 struct bwi_rf *rf = &mac->mac_rf;
2381 if (rssi >= BWI_NRSSI_TBLSZ)
2382 rssi = BWI_NRSSI_TBLSZ - 1;
2384 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
2385 rssi -= 67;
2386 } else {
2387 rssi = ((31 - rssi) * -149) / 128;
2388 rssi -= 68;
2391 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
2392 return rssi;
2394 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2395 rssi += 20;
2397 lna_gain = __SHIFTOUT(le16toh(hdr->rxh_phyinfo),
2398 BWI_RXH_PHYINFO_LNAGAIN);
2399 #if 0
2400 DPRINTF(mac->mac_sc, "lna_gain %d, phyinfo 0x%04x\n",
2401 lna_gain, le16toh(hdr->rxh_phyinfo));
2402 #endif
2403 switch (lna_gain) {
2404 case 0:
2405 rssi += 27;
2406 break;
2407 case 1:
2408 rssi += 6;
2409 break;
2410 case 2:
2411 rssi += 12;
2412 break;
2413 case 3:
2415 * XXX
2416 * According to v3 spec, we should do _nothing_ here,
2417 * but it seems that the result RSSI will be too low
2418 * (relative to what ath(4) says). Raise it a little
2419 * bit.
2421 rssi += 5;
2422 break;
2423 default:
2424 panic("impossible lna gain %d", lna_gain);
2426 #else /* !NEW_BCM2050_RSSI */
2427 lna_gain = 0; /* shut up gcc warning */
2429 if (flags1 & BWI_RXH_F1_OFDM) {
2430 if (rssi > 127)
2431 rssi -= 256;
2432 rssi = (rssi * 73) / 64;
2434 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2435 rssi += 25;
2436 else
2437 rssi -= 3;
2438 return rssi;
2441 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
2442 struct bwi_rf *rf = &mac->mac_rf;
2444 if (rssi >= BWI_NRSSI_TBLSZ)
2445 rssi = BWI_NRSSI_TBLSZ - 1;
2447 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
2448 rssi -= 57;
2449 } else {
2450 rssi = ((31 - rssi) * -149) / 128;
2451 rssi -= 68;
2454 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
2455 return rssi;
2457 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2458 rssi += 25;
2459 #endif /* NEW_BCM2050_RSSI */
2460 return rssi;
2463 static int
2464 bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2466 uint16_t flags1;
2467 int rssi;
2469 rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
2471 flags1 = le16toh(hdr->rxh_flags1);
2472 if (flags1 & BWI_RXH_F1_BCM2053_RSSI)
2473 rssi -= 109;
2474 else
2475 rssi -= 83;
2476 return rssi;
2479 static int
2480 bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2482 int rssi;
2484 rssi = hdr->rxh_rssi;
2485 if (rssi > 127)
2486 rssi -= 256;
2487 return rssi;