2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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
34 * $DragonFly: src/sys/dev/netif/bwi/bwirf.c,v 1.8 2008/01/15 09:01:13 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/bitops.h>
39 #include <sys/endian.h>
40 #include <sys/kernel.h>
42 #include <sys/malloc.h>
45 #include <sys/serialize.h>
46 #include <sys/socket.h>
47 #include <sys/sysctl.h>
49 #include <net/ethernet.h>
52 #include <net/if_arp.h>
53 #include <net/if_dl.h>
54 #include <net/if_media.h>
55 #include <net/ifq_var.h>
57 #include <netproto/802_11/ieee80211_radiotap.h>
58 #include <netproto/802_11/ieee80211_var.h>
59 #include <netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h>
61 #include <bus/pci/pcireg.h>
62 #include <bus/pci/pcivar.h>
63 #include <bus/pci/pcidevs.h>
65 #include <dev/netif/bwi/if_bwireg.h>
66 #include <dev/netif/bwi/if_bwivar.h>
67 #include <dev/netif/bwi/bwiphy.h>
68 #include <dev/netif/bwi/bwirf.h>
69 #include <dev/netif/bwi/bwimac.h>
71 #define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo))
73 #define BWI_RF_2GHZ_CHAN(chan) \
74 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
76 #define BWI_DEFAULT_IDLE_TSSI 52
99 #define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n)
100 #define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n)
102 #define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n)
103 #define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
105 static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
106 static void bwi_rf_workaround(struct bwi_mac
*, u_int
);
107 static int bwi_rf_gain_max_reached(struct bwi_mac
*, int);
108 static uint16_t bwi_rf_calibval(struct bwi_mac
*);
109 static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac
*);
111 static void bwi_rf_lo_update_11b(struct bwi_mac
*);
112 static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac
*);
114 static void bwi_rf_lo_update_11g(struct bwi_mac
*);
115 static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac
*, uint16_t);
116 static void bwi_rf_lo_measure_11g(struct bwi_mac
*,
117 const struct bwi_rf_lo
*, struct bwi_rf_lo
*, uint8_t);
118 static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac
*, uint16_t);
119 static void bwi_rf_lo_write(struct bwi_mac
*, const struct bwi_rf_lo
*);
121 static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac
*);
122 static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac
*);
123 static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac
*);
124 static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac
*);
125 static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac
*);
127 static void bwi_rf_init_sw_nrssi_table(struct bwi_mac
*);
129 static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac
*,
130 const struct bwi_rxbuf_hdr
*);
131 static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac
*,
132 const struct bwi_rxbuf_hdr
*);
133 static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac
*,
134 const struct bwi_rxbuf_hdr
*);
136 static void bwi_rf_on_11a(struct bwi_mac
*);
137 static void bwi_rf_on_11bg(struct bwi_mac
*);
139 static void bwi_rf_off_11a(struct bwi_mac
*);
140 static void bwi_rf_off_11bg(struct bwi_mac
*);
141 static void bwi_rf_off_11g_rev5(struct bwi_mac
*);
143 static const int8_t bwi_txpower_map_11b
[BWI_TSSI_MAX
] =
144 { BWI_TXPOWER_MAP_11B
};
145 static const int8_t bwi_txpower_map_11g
[BWI_TSSI_MAX
] =
146 { BWI_TXPOWER_MAP_11G
};
148 static __inline
int16_t
149 bwi_nrssi_11g(struct bwi_mac
*mac
)
153 #define NRSSI_11G_MASK __BITS(13, 8)
155 val
= (int16_t)__SHIFTOUT(PHY_READ(mac
, 0x47f), NRSSI_11G_MASK
);
160 #undef NRSSI_11G_MASK
163 static __inline
struct bwi_rf_lo
*
164 bwi_get_rf_lo(struct bwi_mac
*mac
, uint16_t rf_atten
, uint16_t bbp_atten
)
168 n
= rf_atten
+ (14 * (bbp_atten
/ 2));
169 KKASSERT(n
< BWI_RFLO_MAX
);
171 return &mac
->mac_rf
.rf_lo
[n
];
175 bwi_rf_lo_isused(struct bwi_mac
*mac
, const struct bwi_rf_lo
*lo
)
177 struct bwi_rf
*rf
= &mac
->mac_rf
;
180 idx
= lo
- rf
->rf_lo
;
181 KKASSERT(idx
>= 0 && idx
< BWI_RFLO_MAX
);
183 return isset(rf
->rf_lo_used
, idx
);
187 bwi_rf_write(struct bwi_mac
*mac
, uint16_t ctrl
, uint16_t data
)
189 struct bwi_softc
*sc
= mac
->mac_sc
;
191 CSR_WRITE_2(sc
, BWI_RF_CTRL
, ctrl
);
192 CSR_WRITE_2(sc
, BWI_RF_DATA_LO
, data
);
196 bwi_rf_read(struct bwi_mac
*mac
, uint16_t ctrl
)
198 struct bwi_rf
*rf
= &mac
->mac_rf
;
199 struct bwi_softc
*sc
= mac
->mac_sc
;
201 ctrl
|= rf
->rf_ctrl_rd
;
202 if (rf
->rf_ctrl_adj
) {
206 else if (ctrl
< 0x80)
210 CSR_WRITE_2(sc
, BWI_RF_CTRL
, ctrl
);
211 return CSR_READ_2(sc
, BWI_RF_DATA_LO
);
215 bwi_rf_attach(struct bwi_mac
*mac
)
217 struct bwi_softc
*sc
= mac
->mac_sc
;
218 struct bwi_phy
*phy
= &mac
->mac_phy
;
219 struct bwi_rf
*rf
= &mac
->mac_rf
;
224 * Get RF manufacture/type/revision
226 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4317
) {
230 manu
= BWI_RF_MANUFACT_BCM
;
231 type
= BWI_RF_T_BCM2050
;
232 if (sc
->sc_bbp_rev
== 0)
234 else if (sc
->sc_bbp_rev
== 1)
241 CSR_WRITE_2(sc
, BWI_RF_CTRL
, BWI_RF_CTRL_RFINFO
);
242 val
= CSR_READ_2(sc
, BWI_RF_DATA_HI
);
245 CSR_WRITE_2(sc
, BWI_RF_CTRL
, BWI_RF_CTRL_RFINFO
);
246 val
|= CSR_READ_2(sc
, BWI_RF_DATA_LO
);
248 manu
= __SHIFTOUT(val
, BWI_RFINFO_MANUFACT_MASK
);
249 type
= __SHIFTOUT(val
, BWI_RFINFO_TYPE_MASK
);
250 rev
= __SHIFTOUT(val
, BWI_RFINFO_REV_MASK
);
252 device_printf(sc
->sc_dev
, "RF: manu 0x%03x, type 0x%04x, rev %u\n",
256 * Verify whether the RF is supported
260 switch (phy
->phy_mode
) {
261 case IEEE80211_MODE_11A
:
262 if (manu
!= BWI_RF_MANUFACT_BCM
||
263 type
!= BWI_RF_T_BCM2060
||
265 device_printf(sc
->sc_dev
, "only BCM2060 rev 1 RF "
266 "is supported for 11A PHY\n");
269 rf
->rf_ctrl_rd
= BWI_RF_CTRL_RD_11A
;
270 rf
->rf_on
= bwi_rf_on_11a
;
271 rf
->rf_off
= bwi_rf_off_11a
;
272 rf
->rf_calc_rssi
= bwi_rf_calc_rssi_bcm2060
;
274 case IEEE80211_MODE_11B
:
275 if (type
== BWI_RF_T_BCM2050
) {
276 rf
->rf_ctrl_rd
= BWI_RF_CTRL_RD_11BG
;
277 rf
->rf_calc_rssi
= bwi_rf_calc_rssi_bcm2050
;
278 } else if (type
== BWI_RF_T_BCM2053
) {
280 rf
->rf_calc_rssi
= bwi_rf_calc_rssi_bcm2053
;
282 device_printf(sc
->sc_dev
, "only BCM2050/BCM2053 RF "
283 "is supported for 11B PHY\n");
286 rf
->rf_on
= bwi_rf_on_11bg
;
287 rf
->rf_off
= bwi_rf_off_11bg
;
288 rf
->rf_calc_nrssi_slope
= bwi_rf_calc_nrssi_slope_11b
;
289 rf
->rf_set_nrssi_thr
= bwi_rf_set_nrssi_thr_11b
;
290 if (phy
->phy_rev
== 6)
291 rf
->rf_lo_update
= bwi_rf_lo_update_11g
;
293 rf
->rf_lo_update
= bwi_rf_lo_update_11b
;
295 case IEEE80211_MODE_11G
:
296 if (type
!= BWI_RF_T_BCM2050
) {
297 device_printf(sc
->sc_dev
, "only BCM2050 RF "
298 "is supported for 11G PHY\n");
301 rf
->rf_ctrl_rd
= BWI_RF_CTRL_RD_11BG
;
302 rf
->rf_on
= bwi_rf_on_11bg
;
303 if (mac
->mac_rev
>= 5)
304 rf
->rf_off
= bwi_rf_off_11g_rev5
;
306 rf
->rf_off
= bwi_rf_off_11bg
;
307 rf
->rf_calc_nrssi_slope
= bwi_rf_calc_nrssi_slope_11g
;
308 rf
->rf_set_nrssi_thr
= bwi_rf_set_nrssi_thr_11g
;
309 rf
->rf_calc_rssi
= bwi_rf_calc_rssi_bcm2050
;
310 rf
->rf_lo_update
= bwi_rf_lo_update_11g
;
313 device_printf(sc
->sc_dev
, "unsupported PHY mode\n");
320 rf
->rf_curchan
= IEEE80211_CHAN_ANY
;
321 rf
->rf_ant_mode
= BWI_ANT_MODE_AUTO
;
326 bwi_rf_set_chan(struct bwi_mac
*mac
, u_int chan
, int work_around
)
328 struct bwi_softc
*sc
= mac
->mac_sc
;
330 if (chan
== IEEE80211_CHAN_ANY
)
333 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_CHAN
, chan
);
338 bwi_rf_workaround(mac
, chan
);
340 CSR_WRITE_2(sc
, BWI_RF_CHAN
, BWI_RF_2GHZ_CHAN(chan
));
343 if (sc
->sc_locale
== BWI_SPROM_LOCALE_JAPAN
)
344 HFLAGS_CLRBITS(mac
, BWI_HFLAG_NOT_JAPAN
);
346 HFLAGS_SETBITS(mac
, BWI_HFLAG_NOT_JAPAN
);
347 CSR_SETBITS_2(sc
, BWI_RF_CHAN_EX
, (1 << 11)); /* XXX */
349 CSR_CLRBITS_2(sc
, BWI_RF_CHAN_EX
, 0x840); /* XXX */
351 DELAY(8000); /* DELAY(2000); */
353 mac
->mac_rf
.rf_curchan
= chan
;
357 bwi_rf_get_gains(struct bwi_mac
*mac
)
359 #define SAVE_PHY_MAX 15
360 #define SAVE_RF_MAX 3
362 static const uint16_t save_rf_regs
[SAVE_RF_MAX
] =
363 { 0x52, 0x43, 0x7a };
364 static const uint16_t save_phy_regs
[SAVE_PHY_MAX
] = {
365 0x0429, 0x0001, 0x0811, 0x0812,
366 0x0814, 0x0815, 0x005a, 0x0059,
367 0x0058, 0x000a, 0x0003, 0x080f,
368 0x0810, 0x002b, 0x0015
371 struct bwi_phy
*phy
= &mac
->mac_phy
;
372 struct bwi_rf
*rf
= &mac
->mac_rf
;
373 uint16_t save_phy
[SAVE_PHY_MAX
];
374 uint16_t save_rf
[SAVE_RF_MAX
];
376 int i
, j
, loop1_max
, loop1
, loop2
;
379 * Save PHY/RF registers for later restoration
381 for (i
= 0; i
< SAVE_PHY_MAX
; ++i
)
382 save_phy
[i
] = PHY_READ(mac
, save_phy_regs
[i
]);
383 PHY_READ(mac
, 0x2d); /* dummy read */
385 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
386 save_rf
[i
] = RF_READ(mac
, save_rf_regs
[i
]);
388 PHY_CLRBITS(mac
, 0x429, 0xc000);
389 PHY_SETBITS(mac
, 0x1, 0x8000);
391 PHY_SETBITS(mac
, 0x811, 0x2);
392 PHY_CLRBITS(mac
, 0x812, 0x2);
393 PHY_SETBITS(mac
, 0x811, 0x1);
394 PHY_CLRBITS(mac
, 0x812, 0x1);
396 PHY_SETBITS(mac
, 0x814, 0x1);
397 PHY_CLRBITS(mac
, 0x815, 0x1);
398 PHY_SETBITS(mac
, 0x814, 0x2);
399 PHY_CLRBITS(mac
, 0x815, 0x2);
401 PHY_SETBITS(mac
, 0x811, 0xc);
402 PHY_SETBITS(mac
, 0x812, 0xc);
403 PHY_SETBITS(mac
, 0x811, 0x30);
404 PHY_FILT_SETBITS(mac
, 0x812, 0xffcf, 0x10);
406 PHY_WRITE(mac
, 0x5a, 0x780);
407 PHY_WRITE(mac
, 0x59, 0xc810);
408 PHY_WRITE(mac
, 0x58, 0xd);
409 PHY_SETBITS(mac
, 0xa, 0x2000);
411 PHY_SETBITS(mac
, 0x814, 0x4);
412 PHY_CLRBITS(mac
, 0x815, 0x4);
414 PHY_FILT_SETBITS(mac
, 0x3, 0xff9f, 0x40);
416 if (rf
->rf_rev
== 8) {
418 RF_WRITE(mac
, 0x43, loop1_max
);
421 RF_WRITE(mac
, 0x52, 0x0);
422 RF_FILT_SETBITS(mac
, 0x43, 0xfff0, loop1_max
);
425 bwi_phy_set_bbp_atten(mac
, 11);
427 if (phy
->phy_rev
>= 3)
428 PHY_WRITE(mac
, 0x80f, 0xc020);
430 PHY_WRITE(mac
, 0x80f, 0x8020);
431 PHY_WRITE(mac
, 0x810, 0);
433 PHY_FILT_SETBITS(mac
, 0x2b, 0xffc0, 0x1);
434 PHY_FILT_SETBITS(mac
, 0x2b, 0xc0ff, 0x800);
435 PHY_SETBITS(mac
, 0x811, 0x100);
436 PHY_CLRBITS(mac
, 0x812, 0x3000);
438 if ((mac
->mac_sc
->sc_card_flags
& BWI_CARD_F_EXT_LNA
) &&
440 PHY_SETBITS(mac
, 0x811, 0x800);
441 PHY_SETBITS(mac
, 0x812, 0x8000);
443 RF_CLRBITS(mac
, 0x7a, 0xff08);
446 * Find out 'loop1/loop2', which will be used to calculate
447 * max loopback gain later
450 for (i
= 0; i
< loop1_max
; ++i
) {
451 for (j
= 0; j
< 16; ++j
) {
452 RF_WRITE(mac
, 0x43, i
);
454 if (bwi_rf_gain_max_reached(mac
, j
))
463 * Find out 'trsw', which will be used to calculate
464 * TRSW(TX/RX switch) RX gain later
467 PHY_SETBITS(mac
, 0x812, 0x30);
469 for (i
= loop2
- 8; i
< 16; ++i
) {
471 if (bwi_rf_gain_max_reached(mac
, i
))
479 * Restore saved PHY/RF registers
481 /* First 4 saved PHY registers need special processing */
482 for (i
= 4; i
< SAVE_PHY_MAX
; ++i
)
483 PHY_WRITE(mac
, save_phy_regs
[i
], save_phy
[i
]);
485 bwi_phy_set_bbp_atten(mac
, mac
->mac_tpctl
.bbp_atten
);
487 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
488 RF_WRITE(mac
, save_rf_regs
[i
], save_rf
[i
]);
490 PHY_WRITE(mac
, save_phy_regs
[2], save_phy
[2] | 0x3);
492 PHY_WRITE(mac
, save_phy_regs
[2], save_phy
[2]);
493 PHY_WRITE(mac
, save_phy_regs
[3], save_phy
[3]);
494 PHY_WRITE(mac
, save_phy_regs
[0], save_phy
[0]);
495 PHY_WRITE(mac
, save_phy_regs
[1], save_phy
[1]);
500 rf
->rf_lo_gain
= (loop2
* 6) - (loop1
* 4) - 11;
501 rf
->rf_rx_gain
= trsw
* 2;
502 DPRINTF(mac
->mac_sc
, BWI_DBG_RF
| BWI_DBG_INIT
,
503 "lo gain: %u, rx gain: %u\n",
504 rf
->rf_lo_gain
, rf
->rf_rx_gain
);
511 bwi_rf_init(struct bwi_mac
*mac
)
513 struct bwi_rf
*rf
= &mac
->mac_rf
;
515 if (rf
->rf_type
== BWI_RF_T_BCM2060
) {
518 if (rf
->rf_flags
& BWI_RF_F_INITED
)
519 RF_WRITE(mac
, 0x78, rf
->rf_calib
);
521 bwi_rf_init_bcm2050(mac
);
526 bwi_rf_off_11a(struct bwi_mac
*mac
)
528 RF_WRITE(mac
, 0x4, 0xff);
529 RF_WRITE(mac
, 0x5, 0xfb);
531 PHY_SETBITS(mac
, 0x10, 0x8);
532 PHY_SETBITS(mac
, 0x11, 0x8);
534 PHY_WRITE(mac
, 0x15, 0xaa00);
538 bwi_rf_off_11bg(struct bwi_mac
*mac
)
540 PHY_WRITE(mac
, 0x15, 0xaa00);
544 bwi_rf_off_11g_rev5(struct bwi_mac
*mac
)
546 PHY_SETBITS(mac
, 0x811, 0x8c);
547 PHY_CLRBITS(mac
, 0x812, 0x8c);
551 bwi_rf_workaround(struct bwi_mac
*mac
, u_int chan
)
553 struct bwi_softc
*sc
= mac
->mac_sc
;
554 struct bwi_rf
*rf
= &mac
->mac_rf
;
556 if (chan
== IEEE80211_CHAN_ANY
) {
557 if_printf(&mac
->mac_sc
->sc_ic
.ic_if
,
558 "%s invalid channel!!\n", __func__
);
562 if (rf
->rf_type
!= BWI_RF_T_BCM2050
|| rf
->rf_rev
>= 6)
566 CSR_WRITE_2(sc
, BWI_RF_CHAN
, BWI_RF_2GHZ_CHAN(chan
+ 4));
568 CSR_WRITE_2(sc
, BWI_RF_CHAN
, BWI_RF_2GHZ_CHAN(1));
570 CSR_WRITE_2(sc
, BWI_RF_CHAN
, BWI_RF_2GHZ_CHAN(chan
));
573 static __inline
struct bwi_rf_lo
*
574 bwi_rf_lo_find(struct bwi_mac
*mac
, const struct bwi_tpctl
*tpctl
)
576 uint16_t rf_atten
, bbp_atten
;
584 if (tpctl
->tp_ctrl1
== 3)
587 bbp_atten
= tpctl
->bbp_atten
;
588 rf_atten
= tpctl
->rf_atten
;
594 if (remap_rf_atten
) {
596 static const uint16_t map
[MAP_MAX
] =
597 { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
600 KKASSERT(rf_atten
< MAP_MAX
);
601 rf_atten
= map
[rf_atten
];
603 if (rf_atten
>= MAP_MAX
) {
604 rf_atten
= 0; /* XXX */
606 rf_atten
= map
[rf_atten
];
612 return bwi_get_rf_lo(mac
, rf_atten
, bbp_atten
);
616 bwi_rf_lo_adjust(struct bwi_mac
*mac
, const struct bwi_tpctl
*tpctl
)
618 const struct bwi_rf_lo
*lo
;
620 lo
= bwi_rf_lo_find(mac
, tpctl
);
621 RF_LO_WRITE(mac
, lo
);
625 bwi_rf_lo_write(struct bwi_mac
*mac
, const struct bwi_rf_lo
*lo
)
629 val
= (uint8_t)lo
->ctrl_lo
;
630 val
|= ((uint8_t)lo
->ctrl_hi
) << 8;
632 PHY_WRITE(mac
, BWI_PHYR_RF_LO
, val
);
636 bwi_rf_gain_max_reached(struct bwi_mac
*mac
, int idx
)
638 PHY_FILT_SETBITS(mac
, 0x812, 0xf0ff, idx
<< 8);
639 PHY_FILT_SETBITS(mac
, 0x15, 0xfff, 0xa000);
640 PHY_SETBITS(mac
, 0x15, 0xf000);
644 return (PHY_READ(mac
, 0x2d) >= 0xdfc);
647 /* XXX use bitmap array */
648 static __inline
uint16_t
649 bitswap4(uint16_t val
)
653 ret
= (val
& 0x8) >> 3;
654 ret
|= (val
& 0x4) >> 1;
655 ret
|= (val
& 0x2) << 1;
656 ret
|= (val
& 0x1) << 3;
660 static __inline
uint16_t
661 bwi_phy812_value(struct bwi_mac
*mac
, uint16_t lpd
)
663 struct bwi_softc
*sc
= mac
->mac_sc
;
664 struct bwi_phy
*phy
= &mac
->mac_phy
;
665 struct bwi_rf
*rf
= &mac
->mac_rf
;
666 uint16_t lo_gain
, ext_lna
, loop
;
668 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) == 0)
671 lo_gain
= rf
->rf_lo_gain
;
677 if (lo_gain
>= 0x46) {
680 } else if (lo_gain
>= 0x3a) {
683 } else if (lo_gain
>= 0x2e) {
691 for (loop
= 0; loop
< 16; ++loop
) {
692 lo_gain
-= (6 * loop
);
697 if (phy
->phy_rev
>= 7 && (sc
->sc_card_flags
& BWI_CARD_F_EXT_LNA
)) {
700 ext_lna
|= (loop
<< 8);
705 return (0x8092 | ext_lna
);
707 return (0x2092 | ext_lna
);
709 return (0x2093 | ext_lna
);
711 panic("unsupported lpd\n");
714 ext_lna
|= (loop
<< 8);
720 return (0x92 | ext_lna
);
722 return (0x93 | ext_lna
);
724 panic("unsupported lpd\n");
728 panic("never reached\n");
733 bwi_rf_init_bcm2050(struct bwi_mac
*mac
)
735 #define SAVE_RF_MAX 3
736 #define SAVE_PHY_COMM_MAX 4
737 #define SAVE_PHY_11G_MAX 6
739 static const uint16_t save_rf_regs
[SAVE_RF_MAX
] =
740 { 0x0043, 0x0051, 0x0052 };
741 static const uint16_t save_phy_regs_comm
[SAVE_PHY_COMM_MAX
] =
742 { 0x0015, 0x005a, 0x0059, 0x0058 };
743 static const uint16_t save_phy_regs_11g
[SAVE_PHY_11G_MAX
] =
744 { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
746 uint16_t save_rf
[SAVE_RF_MAX
];
747 uint16_t save_phy_comm
[SAVE_PHY_COMM_MAX
];
748 uint16_t save_phy_11g
[SAVE_PHY_11G_MAX
];
749 uint16_t phyr_35
, phyr_30
= 0, rfr_78
, phyr_80f
= 0, phyr_810
= 0;
750 uint16_t bphy_ctrl
= 0, bbp_atten
, rf_chan_ex
;
753 uint32_t test_lim
, test
;
754 struct bwi_softc
*sc
= mac
->mac_sc
;
755 struct bwi_phy
*phy
= &mac
->mac_phy
;
756 struct bwi_rf
*rf
= &mac
->mac_rf
;
760 * Save registers for later restoring
762 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
763 save_rf
[i
] = RF_READ(mac
, save_rf_regs
[i
]);
764 for (i
= 0; i
< SAVE_PHY_COMM_MAX
; ++i
)
765 save_phy_comm
[i
] = PHY_READ(mac
, save_phy_regs_comm
[i
]);
767 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
768 phyr_30
= PHY_READ(mac
, 0x30);
769 bphy_ctrl
= CSR_READ_2(sc
, BWI_BPHY_CTRL
);
771 PHY_WRITE(mac
, 0x30, 0xff);
772 CSR_WRITE_2(sc
, BWI_BPHY_CTRL
, 0x3f3f);
773 } else if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
774 for (i
= 0; i
< SAVE_PHY_11G_MAX
; ++i
) {
776 PHY_READ(mac
, save_phy_regs_11g
[i
]);
779 PHY_SETBITS(mac
, 0x814, 0x3);
780 PHY_CLRBITS(mac
, 0x815, 0x3);
781 PHY_CLRBITS(mac
, 0x429, 0x8000);
782 PHY_CLRBITS(mac
, 0x802, 0x3);
784 phyr_80f
= PHY_READ(mac
, 0x80f);
785 phyr_810
= PHY_READ(mac
, 0x810);
787 if (phy
->phy_rev
>= 3)
788 PHY_WRITE(mac
, 0x80f, 0xc020);
790 PHY_WRITE(mac
, 0x80f, 0x8020);
791 PHY_WRITE(mac
, 0x810, 0);
793 phy812_val
= bwi_phy812_value(mac
, 0x011);
794 PHY_WRITE(mac
, 0x812, phy812_val
);
795 if (phy
->phy_rev
< 7 ||
796 (sc
->sc_card_flags
& BWI_CARD_F_EXT_LNA
) == 0)
797 PHY_WRITE(mac
, 0x811, 0x1b3);
799 PHY_WRITE(mac
, 0x811, 0x9b3);
801 CSR_SETBITS_2(sc
, BWI_RF_ANTDIV
, 0x8000);
803 phyr_35
= PHY_READ(mac
, 0x35);
804 PHY_CLRBITS(mac
, 0x35, 0x80);
806 bbp_atten
= CSR_READ_2(sc
, BWI_BBP_ATTEN
);
807 rf_chan_ex
= CSR_READ_2(sc
, BWI_RF_CHAN_EX
);
809 if (phy
->phy_version
== 0) {
810 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0x122);
812 if (phy
->phy_version
>= 2)
813 PHY_FILT_SETBITS(mac
, 0x3, 0xffbf, 0x40);
814 CSR_SETBITS_2(sc
, BWI_RF_CHAN_EX
, 0x2000);
817 calib
= bwi_rf_calibval(mac
);
819 if (phy
->phy_mode
== IEEE80211_MODE_11B
)
820 RF_WRITE(mac
, 0x78, 0x26);
822 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
823 phy812_val
= bwi_phy812_value(mac
, 0x011);
824 PHY_WRITE(mac
, 0x812, phy812_val
);
827 PHY_WRITE(mac
, 0x15, 0xbfaf);
828 PHY_WRITE(mac
, 0x2b, 0x1403);
830 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
831 phy812_val
= bwi_phy812_value(mac
, 0x001);
832 PHY_WRITE(mac
, 0x812, phy812_val
);
835 PHY_WRITE(mac
, 0x15, 0xbfa0);
837 RF_SETBITS(mac
, 0x51, 0x4);
838 if (rf
->rf_rev
== 8) {
839 RF_WRITE(mac
, 0x43, 0x1f);
841 RF_WRITE(mac
, 0x52, 0);
842 RF_FILT_SETBITS(mac
, 0x43, 0xfff0, 0x9);
846 PHY_WRITE(mac
, 0x58, 0);
847 for (i
= 0; i
< 16; ++i
) {
848 PHY_WRITE(mac
, 0x5a, 0x480);
849 PHY_WRITE(mac
, 0x59, 0xc810);
851 PHY_WRITE(mac
, 0x58, 0xd);
852 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
853 phy812_val
= bwi_phy812_value(mac
, 0x101);
854 PHY_WRITE(mac
, 0x812, phy812_val
);
856 PHY_WRITE(mac
, 0x15, 0xafb0);
859 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
860 phy812_val
= bwi_phy812_value(mac
, 0x101);
861 PHY_WRITE(mac
, 0x812, phy812_val
);
863 PHY_WRITE(mac
, 0x15, 0xefb0);
866 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
867 phy812_val
= bwi_phy812_value(mac
, 0x100);
868 PHY_WRITE(mac
, 0x812, phy812_val
);
870 PHY_WRITE(mac
, 0x15, 0xfff0);
873 test_lim
+= PHY_READ(mac
, 0x2d);
875 PHY_WRITE(mac
, 0x58, 0);
876 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
877 phy812_val
= bwi_phy812_value(mac
, 0x101);
878 PHY_WRITE(mac
, 0x812, phy812_val
);
880 PHY_WRITE(mac
, 0x15, 0xafb0);
888 PHY_WRITE(mac
, 0x58, 0);
889 for (i
= 0; i
< 16; ++i
) {
892 rfr_78
= (bitswap4(i
) << 1) | 0x20;
893 RF_WRITE(mac
, 0x78, rfr_78
);
896 /* NB: This block is slight different than the above one */
897 for (j
= 0; j
< 16; ++j
) {
898 PHY_WRITE(mac
, 0x5a, 0xd80);
899 PHY_WRITE(mac
, 0x59, 0xc810);
901 PHY_WRITE(mac
, 0x58, 0xd);
902 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) ||
904 phy812_val
= bwi_phy812_value(mac
, 0x101);
905 PHY_WRITE(mac
, 0x812, phy812_val
);
907 PHY_WRITE(mac
, 0x15, 0xafb0);
910 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) ||
912 phy812_val
= bwi_phy812_value(mac
, 0x101);
913 PHY_WRITE(mac
, 0x812, phy812_val
);
915 PHY_WRITE(mac
, 0x15, 0xefb0);
918 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) ||
920 phy812_val
= bwi_phy812_value(mac
, 0x100);
921 PHY_WRITE(mac
, 0x812, phy812_val
);
923 PHY_WRITE(mac
, 0x15, 0xfff0);
926 test
+= PHY_READ(mac
, 0x2d);
928 PHY_WRITE(mac
, 0x58, 0);
929 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) ||
931 phy812_val
= bwi_phy812_value(mac
, 0x101);
932 PHY_WRITE(mac
, 0x812, phy812_val
);
934 PHY_WRITE(mac
, 0x15, 0xafb0);
944 rf
->rf_calib
= rfr_78
;
946 rf
->rf_calib
= calib
;
947 if (rf
->rf_calib
!= 0xffff) {
948 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_INIT
,
949 "RF calibration value: 0x%04x\n", rf
->rf_calib
);
950 rf
->rf_flags
|= BWI_RF_F_INITED
;
954 * Restore trashes registers
956 PHY_WRITE(mac
, save_phy_regs_comm
[0], save_phy_comm
[0]);
958 for (i
= 0; i
< SAVE_RF_MAX
; ++i
) {
959 int pos
= (i
+ 1) % SAVE_RF_MAX
;
961 RF_WRITE(mac
, save_rf_regs
[pos
], save_rf
[pos
]);
963 for (i
= 1; i
< SAVE_PHY_COMM_MAX
; ++i
)
964 PHY_WRITE(mac
, save_phy_regs_comm
[i
], save_phy_comm
[i
]);
966 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, bbp_atten
);
967 if (phy
->phy_version
!= 0)
968 CSR_WRITE_2(sc
, BWI_RF_CHAN_EX
, rf_chan_ex
);
970 PHY_WRITE(mac
, 0x35, phyr_35
);
971 bwi_rf_workaround(mac
, rf
->rf_curchan
);
973 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
974 PHY_WRITE(mac
, 0x30, phyr_30
);
975 CSR_WRITE_2(sc
, BWI_BPHY_CTRL
, bphy_ctrl
);
976 } else if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) || phy
->phy_rev
>= 2) {
977 /* XXX Spec only says when PHY is linked (gmode) */
978 CSR_CLRBITS_2(sc
, BWI_RF_ANTDIV
, 0x8000);
980 for (i
= 0; i
< SAVE_PHY_11G_MAX
; ++i
) {
981 PHY_WRITE(mac
, save_phy_regs_11g
[i
],
985 PHY_WRITE(mac
, 0x80f, phyr_80f
);
986 PHY_WRITE(mac
, 0x810, phyr_810
);
989 #undef SAVE_PHY_11G_MAX
990 #undef SAVE_PHY_COMM_MAX
995 bwi_rf_calibval(struct bwi_mac
*mac
)
997 /* http://bcm-specs.sipsolutions.net/RCCTable */
998 static const uint16_t rf_calibvals
[] = {
999 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
1000 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
1002 uint16_t val
, calib
;
1005 val
= RF_READ(mac
, BWI_RFR_BBP_ATTEN
);
1006 idx
= __SHIFTOUT(val
, BWI_RFR_BBP_ATTEN_CALIB_IDX
);
1007 KKASSERT(idx
< (int)(sizeof(rf_calibvals
) / sizeof(rf_calibvals
[0])));
1009 calib
= rf_calibvals
[idx
] << 1;
1010 if (val
& BWI_RFR_BBP_ATTEN_CALIB_BIT
)
1017 static __inline
int32_t
1018 _bwi_adjust_devide(int32_t num
, int32_t den
)
1023 return (num
+ den
/ 2) / den
;
1027 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
1028 * "calculating table entries"
1031 bwi_rf_calc_txpower(int8_t *txpwr
, uint8_t idx
, const int16_t pa_params
[])
1033 int32_t m1
, m2
, f
, dbm
;
1036 m1
= _bwi_adjust_devide(16 * pa_params
[0] + idx
* pa_params
[1], 32);
1037 m2
= imax(_bwi_adjust_devide(32768 + idx
* pa_params
[2], 256), 1);
1042 for (i
= 0; i
< ITER_MAX
; ++i
) {
1045 q
= _bwi_adjust_devide(
1046 f
* 4096 - _bwi_adjust_devide(m2
* f
, 16) * f
, 2048);
1058 dbm
= _bwi_adjust_devide(m1
* f
, 8192);
1069 bwi_rf_map_txpower(struct bwi_mac
*mac
)
1071 struct bwi_softc
*sc
= mac
->mac_sc
;
1072 struct bwi_rf
*rf
= &mac
->mac_rf
;
1073 struct bwi_phy
*phy
= &mac
->mac_phy
;
1074 uint16_t sprom_ofs
, val
, mask
;
1075 int16_t pa_params
[3];
1076 int error
= 0, i
, ant_gain
, reg_txpower_max
;
1079 * Find out max TX power
1081 val
= bwi_read_sprom(sc
, BWI_SPROM_MAX_TXPWR
);
1082 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
1083 rf
->rf_txpower_max
= __SHIFTOUT(val
,
1084 BWI_SPROM_MAX_TXPWR_MASK_11A
);
1086 rf
->rf_txpower_max
= __SHIFTOUT(val
,
1087 BWI_SPROM_MAX_TXPWR_MASK_11BG
);
1089 if ((sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) &&
1090 phy
->phy_mode
== IEEE80211_MODE_11G
)
1091 rf
->rf_txpower_max
-= 3;
1093 if (rf
->rf_txpower_max
<= 0) {
1094 device_printf(sc
->sc_dev
, "invalid max txpower in sprom\n");
1095 rf
->rf_txpower_max
= 74;
1097 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1098 "max txpower from sprom: %d dBm\n", rf
->rf_txpower_max
);
1101 * Find out region/domain max TX power, which is adjusted
1102 * by antenna gain and 1.5 dBm fluctuation as mentioned
1105 val
= bwi_read_sprom(sc
, BWI_SPROM_ANT_GAIN
);
1106 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1107 ant_gain
= __SHIFTOUT(val
, BWI_SPROM_ANT_GAIN_MASK_11A
);
1109 ant_gain
= __SHIFTOUT(val
, BWI_SPROM_ANT_GAIN_MASK_11BG
);
1110 if (ant_gain
== 0xff) {
1111 device_printf(sc
->sc_dev
, "invalid antenna gain in sprom\n");
1115 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1116 "ant gain %d dBm\n", ant_gain
);
1118 reg_txpower_max
= 90 - ant_gain
- 6; /* XXX magic number */
1119 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1120 "region/domain max txpower %d dBm\n", reg_txpower_max
);
1123 * Force max TX power within region/domain TX power limit
1125 if (rf
->rf_txpower_max
> reg_txpower_max
)
1126 rf
->rf_txpower_max
= reg_txpower_max
;
1127 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1128 "max txpower %d dBm\n", rf
->rf_txpower_max
);
1131 * Create TSSI to TX power mapping
1134 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4301
&&
1135 rf
->rf_type
!= BWI_RF_T_BCM2050
) {
1136 rf
->rf_idle_tssi0
= BWI_DEFAULT_IDLE_TSSI
;
1137 bcopy(bwi_txpower_map_11b
, rf
->rf_txpower_map0
,
1138 sizeof(rf
->rf_txpower_map0
));
1142 #define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1)
1143 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1146 * Extract PA parameters
1148 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1149 sprom_ofs
= BWI_SPROM_PA_PARAM_11A
;
1151 sprom_ofs
= BWI_SPROM_PA_PARAM_11BG
;
1152 for (i
= 0; i
< N(pa_params
); ++i
)
1153 pa_params
[i
] = (int16_t)bwi_read_sprom(sc
, sprom_ofs
+ (i
* 2));
1155 for (i
= 0; i
< N(pa_params
); ++i
) {
1157 * If one of the PA parameters from SPROM is not valid,
1158 * fall back to the default values, if there are any.
1160 if (!IS_VALID_PA_PARAM(pa_params
[i
])) {
1161 const int8_t *txpower_map
;
1163 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
1164 if_printf(&sc
->sc_ic
.ic_if
,
1165 "no tssi2dbm table for 11a PHY\n");
1169 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
1171 BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1172 "%s\n", "use default 11g TSSI map");
1173 txpower_map
= bwi_txpower_map_11g
;
1176 BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1177 "%s\n", "use default 11b TSSI map");
1178 txpower_map
= bwi_txpower_map_11b
;
1181 rf
->rf_idle_tssi0
= BWI_DEFAULT_IDLE_TSSI
;
1182 bcopy(txpower_map
, rf
->rf_txpower_map0
,
1183 sizeof(rf
->rf_txpower_map0
));
1191 * All of the PA parameters from SPROM are valid.
1195 * Extract idle TSSI from SPROM.
1197 val
= bwi_read_sprom(sc
, BWI_SPROM_IDLE_TSSI
);
1198 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1199 "sprom idle tssi: 0x%04x\n", val
);
1201 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1202 mask
= BWI_SPROM_IDLE_TSSI_MASK_11A
;
1204 mask
= BWI_SPROM_IDLE_TSSI_MASK_11BG
;
1206 rf
->rf_idle_tssi0
= (int)__SHIFTOUT(val
, mask
);
1207 if (!IS_VALID_PA_PARAM(rf
->rf_idle_tssi0
))
1208 rf
->rf_idle_tssi0
= 62;
1210 #undef IS_VALID_PA_PARAM
1213 * Calculate TX power map, which is indexed by TSSI
1215 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_ATTACH
| BWI_DBG_TXPOWER
,
1216 "%s\n", "TSSI-TX power map:");
1217 for (i
= 0; i
< BWI_TSSI_MAX
; ++i
) {
1218 error
= bwi_rf_calc_txpower(&rf
->rf_txpower_map0
[i
], i
,
1221 if_printf(&sc
->sc_ic
.ic_if
,
1222 "bwi_rf_calc_txpower failed\n");
1227 if (i
!= 0 && i
% 8 == 0) {
1229 BWI_DBG_RF
| BWI_DBG_ATTACH
| BWI_DBG_TXPOWER
,
1233 _DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_ATTACH
| BWI_DBG_TXPOWER
,
1234 "%d ", rf
->rf_txpower_map0
[i
]);
1236 _DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_ATTACH
| BWI_DBG_TXPOWER
,
1239 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_TXPOWER
| BWI_DBG_ATTACH
,
1240 "idle tssi0: %d\n", rf
->rf_idle_tssi0
);
1245 bwi_rf_lo_update_11g(struct bwi_mac
*mac
)
1247 struct bwi_softc
*sc
= mac
->mac_sc
;
1248 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1249 struct bwi_rf
*rf
= &mac
->mac_rf
;
1250 struct bwi_phy
*phy
= &mac
->mac_phy
;
1251 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
1252 struct rf_saveregs regs
;
1253 uint16_t ant_div
, chan_ex
;
1257 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_INIT
, "%s enter\n", __func__
);
1260 * Save RF/PHY registers for later restoration
1262 orig_chan
= rf
->rf_curchan
;
1263 bzero(®s
, sizeof(regs
));
1265 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1266 SAVE_PHY_REG(mac
, ®s
, 429);
1267 SAVE_PHY_REG(mac
, ®s
, 802);
1269 PHY_WRITE(mac
, 0x429, regs
.phy_429
& 0x7fff);
1270 PHY_WRITE(mac
, 0x802, regs
.phy_802
& 0xfffc);
1273 ant_div
= CSR_READ_2(sc
, BWI_RF_ANTDIV
);
1274 CSR_WRITE_2(sc
, BWI_RF_ANTDIV
, ant_div
| 0x8000);
1275 chan_ex
= CSR_READ_2(sc
, BWI_RF_CHAN_EX
);
1277 SAVE_PHY_REG(mac
, ®s
, 15);
1278 SAVE_PHY_REG(mac
, ®s
, 2a
);
1279 SAVE_PHY_REG(mac
, ®s
, 35);
1280 SAVE_PHY_REG(mac
, ®s
, 60);
1281 SAVE_RF_REG(mac
, ®s
, 43);
1282 SAVE_RF_REG(mac
, ®s
, 7a
);
1283 SAVE_RF_REG(mac
, ®s
, 52);
1284 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1285 SAVE_PHY_REG(mac
, ®s
, 811);
1286 SAVE_PHY_REG(mac
, ®s
, 812);
1287 SAVE_PHY_REG(mac
, ®s
, 814);
1288 SAVE_PHY_REG(mac
, ®s
, 815);
1291 /* Force to channel 6 */
1292 bwi_rf_set_chan(mac
, 6, 0);
1294 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1295 PHY_WRITE(mac
, 0x429, regs
.phy_429
& 0x7fff);
1296 PHY_WRITE(mac
, 0x802, regs
.phy_802
& 0xfffc);
1297 bwi_mac_dummy_xmit(mac
);
1299 RF_WRITE(mac
, 0x43, 0x6);
1301 bwi_phy_set_bbp_atten(mac
, 2);
1303 CSR_WRITE_2(sc
, BWI_RF_CHAN_EX
, 0);
1305 PHY_WRITE(mac
, 0x2e, 0x7f);
1306 PHY_WRITE(mac
, 0x80f, 0x78);
1307 PHY_WRITE(mac
, 0x35, regs
.phy_35
& 0xff7f);
1308 RF_WRITE(mac
, 0x7a, regs
.rf_7a
& 0xfff0);
1309 PHY_WRITE(mac
, 0x2b, 0x203);
1310 PHY_WRITE(mac
, 0x2a, 0x8a3);
1312 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1313 PHY_WRITE(mac
, 0x814, regs
.phy_814
| 0x3);
1314 PHY_WRITE(mac
, 0x815, regs
.phy_815
& 0xfffc);
1315 PHY_WRITE(mac
, 0x811, 0x1b3);
1316 PHY_WRITE(mac
, 0x812, 0xb2);
1319 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1320 tpctl
->tp_ctrl2
= bwi_rf_get_tp_ctrl2(mac
);
1321 PHY_WRITE(mac
, 0x80f, 0x8078);
1326 devi_ctrl
= _bwi_rf_lo_update_11g(mac
, regs
.rf_7a
);
1329 * Restore saved RF/PHY registers
1331 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1332 PHY_WRITE(mac
, 0x15, 0xe300);
1333 PHY_WRITE(mac
, 0x812, (devi_ctrl
<< 8) | 0xa0);
1335 PHY_WRITE(mac
, 0x812, (devi_ctrl
<< 8) | 0xa2);
1337 PHY_WRITE(mac
, 0x812, (devi_ctrl
<< 8) | 0xa3);
1339 PHY_WRITE(mac
, 0x15, devi_ctrl
| 0xefa0);
1342 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1344 bwi_rf_lo_adjust(mac
, tpctl
);
1346 PHY_WRITE(mac
, 0x2e, 0x807f);
1347 if (phy
->phy_flags
& BWI_PHY_F_LINKED
)
1348 PHY_WRITE(mac
, 0x2f, 0x202);
1350 PHY_WRITE(mac
, 0x2f, 0x101);
1352 CSR_WRITE_2(sc
, BWI_RF_CHAN_EX
, chan_ex
);
1354 RESTORE_PHY_REG(mac
, ®s
, 15);
1355 RESTORE_PHY_REG(mac
, ®s
, 2a
);
1356 RESTORE_PHY_REG(mac
, ®s
, 35);
1357 RESTORE_PHY_REG(mac
, ®s
, 60);
1359 RESTORE_RF_REG(mac
, ®s
, 43);
1360 RESTORE_RF_REG(mac
, ®s
, 7a
);
1363 regs
.rf_52
|= (RF_READ(mac
, 0x52) & 0xf);
1364 RF_WRITE(mac
, 0x52, regs
.rf_52
);
1366 CSR_WRITE_2(sc
, BWI_RF_ANTDIV
, ant_div
);
1368 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1369 RESTORE_PHY_REG(mac
, ®s
, 811);
1370 RESTORE_PHY_REG(mac
, ®s
, 812);
1371 RESTORE_PHY_REG(mac
, ®s
, 814);
1372 RESTORE_PHY_REG(mac
, ®s
, 815);
1373 RESTORE_PHY_REG(mac
, ®s
, 429);
1374 RESTORE_PHY_REG(mac
, ®s
, 802);
1377 bwi_rf_set_chan(mac
, orig_chan
, 1);
1381 bwi_rf_lo_devi_measure(struct bwi_mac
*mac
, uint16_t ctrl
)
1383 struct bwi_phy
*phy
= &mac
->mac_phy
;
1387 if (phy
->phy_flags
& BWI_PHY_F_LINKED
)
1390 for (i
= 0; i
< 8; ++i
) {
1391 if (phy
->phy_flags
& BWI_PHY_F_LINKED
) {
1392 PHY_WRITE(mac
, 0x15, 0xe300);
1393 PHY_WRITE(mac
, 0x812, ctrl
| 0xb0);
1395 PHY_WRITE(mac
, 0x812, ctrl
| 0xb2);
1397 PHY_WRITE(mac
, 0x812, ctrl
| 0xb3);
1399 PHY_WRITE(mac
, 0x15, 0xf300);
1401 PHY_WRITE(mac
, 0x15, ctrl
| 0xefa0);
1403 PHY_WRITE(mac
, 0x15, ctrl
| 0xefe0);
1405 PHY_WRITE(mac
, 0x15, ctrl
| 0xffe0);
1408 devi
+= PHY_READ(mac
, 0x2d);
1414 bwi_rf_get_tp_ctrl2(struct bwi_mac
*mac
)
1417 uint16_t tp_ctrl2
= 0;
1420 RF_WRITE(mac
, 0x52, 0);
1422 devi_min
= bwi_rf_lo_devi_measure(mac
, 0);
1424 for (i
= 0; i
< 16; ++i
) {
1427 RF_WRITE(mac
, 0x52, i
);
1429 devi
= bwi_rf_lo_devi_measure(mac
, 0);
1431 if (devi
< devi_min
) {
1440 _bwi_rf_lo_update_11g(struct bwi_mac
*mac
, uint16_t orig_rf7a
)
1442 #define RF_ATTEN_LISTSZ 14
1443 #define BBP_ATTEN_MAX 4 /* half */
1445 static const int rf_atten_list
[RF_ATTEN_LISTSZ
] =
1446 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
1447 static const int rf_atten_init_list
[RF_ATTEN_LISTSZ
] =
1448 { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
1449 static const int rf_lo_measure_order
[RF_ATTEN_LISTSZ
] =
1450 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
1452 struct ifnet
*ifp
= &mac
->mac_sc
->sc_ic
.ic_if
;
1453 struct bwi_rf_lo lo_save
, *lo
;
1454 uint8_t devi_ctrl
= 0;
1455 int idx
, adj_rf7a
= 0;
1457 bzero(&lo_save
, sizeof(lo_save
));
1458 for (idx
= 0; idx
< RF_ATTEN_LISTSZ
; ++idx
) {
1459 int init_rf_atten
= rf_atten_init_list
[idx
];
1460 int rf_atten
= rf_atten_list
[idx
];
1463 for (bbp_atten
= 0; bbp_atten
< BBP_ATTEN_MAX
; ++bbp_atten
) {
1464 uint16_t tp_ctrl2
, rf7a
;
1466 if ((ifp
->if_flags
& IFF_RUNNING
) == 0) {
1468 bzero(&lo_save
, sizeof(lo_save
));
1469 } else if (init_rf_atten
< 0) {
1470 lo
= bwi_get_rf_lo(mac
,
1471 rf_atten
, 2 * bbp_atten
);
1472 bcopy(lo
, &lo_save
, sizeof(lo_save
));
1474 lo
= bwi_get_rf_lo(mac
,
1476 bcopy(lo
, &lo_save
, sizeof(lo_save
));
1484 * Linux driver overflows 'val'
1486 if (init_rf_atten
>= 0) {
1489 val
= rf_atten
* 2 + bbp_atten
;
1499 lo
= bwi_get_rf_lo(mac
,
1500 rf_atten
, 2 * bbp_atten
);
1501 if (!bwi_rf_lo_isused(mac
, lo
))
1503 bcopy(lo
, &lo_save
, sizeof(lo_save
));
1509 RF_WRITE(mac
, BWI_RFR_ATTEN
, rf_atten
);
1511 tp_ctrl2
= mac
->mac_tpctl
.tp_ctrl2
;
1512 if (init_rf_atten
< 0)
1513 tp_ctrl2
|= (3 << 4);
1514 RF_WRITE(mac
, BWI_RFR_TXPWR
, tp_ctrl2
);
1518 bwi_phy_set_bbp_atten(mac
, bbp_atten
* 2);
1520 rf7a
= orig_rf7a
& 0xfff0;
1523 RF_WRITE(mac
, 0x7a, rf7a
);
1525 lo
= bwi_get_rf_lo(mac
,
1526 rf_lo_measure_order
[idx
], bbp_atten
* 2);
1527 bwi_rf_lo_measure_11g(mac
, &lo_save
, lo
, devi_ctrl
);
1532 #undef RF_ATTEN_LISTSZ
1533 #undef BBP_ATTEN_MAX
1537 bwi_rf_lo_measure_11g(struct bwi_mac
*mac
, const struct bwi_rf_lo
*src_lo
,
1538 struct bwi_rf_lo
*dst_lo
, uint8_t devi_ctrl
)
1540 #define LO_ADJUST_MIN 1
1541 #define LO_ADJUST_MAX 8
1542 #define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo }
1543 static const struct bwi_rf_lo rf_lo_adjust
[LO_ADJUST_MAX
] = {
1555 struct bwi_rf_lo lo_min
;
1557 int found
, loop_count
, adjust_state
;
1559 bcopy(src_lo
, &lo_min
, sizeof(lo_min
));
1560 RF_LO_WRITE(mac
, &lo_min
);
1561 devi_min
= bwi_rf_lo_devi_measure(mac
, devi_ctrl
);
1563 loop_count
= 12; /* XXX */
1566 struct bwi_rf_lo lo_base
;
1570 if (adjust_state
== 0) {
1572 fin
= LO_ADJUST_MAX
;
1573 } else if (adjust_state
% 2 == 0) {
1574 i
= adjust_state
- 1;
1575 fin
= adjust_state
+ 1;
1577 i
= adjust_state
- 2;
1578 fin
= adjust_state
+ 2;
1581 if (i
< LO_ADJUST_MIN
)
1583 KKASSERT(i
<= LO_ADJUST_MAX
&& i
>= LO_ADJUST_MIN
);
1585 if (fin
> LO_ADJUST_MAX
)
1586 fin
-= LO_ADJUST_MAX
;
1587 KKASSERT(fin
<= LO_ADJUST_MAX
&& fin
>= LO_ADJUST_MIN
);
1589 bcopy(&lo_min
, &lo_base
, sizeof(lo_base
));
1591 struct bwi_rf_lo lo
;
1593 lo
.ctrl_hi
= lo_base
.ctrl_hi
+
1594 rf_lo_adjust
[i
- 1].ctrl_hi
;
1595 lo
.ctrl_lo
= lo_base
.ctrl_lo
+
1596 rf_lo_adjust
[i
- 1].ctrl_lo
;
1598 if (abs(lo
.ctrl_lo
) < 9 && abs(lo
.ctrl_hi
) < 9) {
1601 RF_LO_WRITE(mac
, &lo
);
1602 devi
= bwi_rf_lo_devi_measure(mac
, devi_ctrl
);
1603 if (devi
< devi_min
) {
1607 bcopy(&lo
, &lo_min
, sizeof(lo_min
));
1612 if (i
== LO_ADJUST_MAX
)
1617 } while (loop_count
-- && found
);
1619 bcopy(&lo_min
, dst_lo
, sizeof(*dst_lo
));
1621 #undef LO_ADJUST_MIN
1622 #undef LO_ADJUST_MAX
1626 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac
*mac
)
1628 #define SAVE_RF_MAX 3
1629 #define SAVE_PHY_MAX 8
1631 static const uint16_t save_rf_regs
[SAVE_RF_MAX
] =
1632 { 0x7a, 0x52, 0x43 };
1633 static const uint16_t save_phy_regs
[SAVE_PHY_MAX
] =
1634 { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
1636 struct bwi_softc
*sc
= mac
->mac_sc
;
1637 struct bwi_rf
*rf
= &mac
->mac_rf
;
1638 struct bwi_phy
*phy
= &mac
->mac_phy
;
1639 uint16_t save_rf
[SAVE_RF_MAX
];
1640 uint16_t save_phy
[SAVE_PHY_MAX
];
1641 uint16_t ant_div
, bbp_atten
, chan_ex
;
1646 * Save RF/PHY registers for later restoration
1648 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
1649 save_rf
[i
] = RF_READ(mac
, save_rf_regs
[i
]);
1650 for (i
= 0; i
< SAVE_PHY_MAX
; ++i
)
1651 save_phy
[i
] = PHY_READ(mac
, save_phy_regs
[i
]);
1653 ant_div
= CSR_READ_2(sc
, BWI_RF_ANTDIV
);
1654 bbp_atten
= CSR_READ_2(sc
, BWI_BBP_ATTEN
);
1655 chan_ex
= CSR_READ_2(sc
, BWI_RF_CHAN_EX
);
1660 if (phy
->phy_rev
>= 5)
1661 RF_CLRBITS(mac
, 0x7a, 0xff80);
1663 RF_CLRBITS(mac
, 0x7a, 0xfff0);
1664 PHY_WRITE(mac
, 0x30, 0xff);
1666 CSR_WRITE_2(sc
, BWI_BPHY_CTRL
, 0x7f7f);
1668 PHY_WRITE(mac
, 0x26, 0);
1669 PHY_SETBITS(mac
, 0x15, 0x20);
1670 PHY_WRITE(mac
, 0x2a, 0x8a3);
1671 RF_SETBITS(mac
, 0x7a, 0x80);
1673 nrssi
[0] = (int16_t)PHY_READ(mac
, 0x27);
1678 RF_CLRBITS(mac
, 0x7a, 0xff80);
1679 if (phy
->phy_version
>= 2)
1680 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0x40);
1681 else if (phy
->phy_version
== 0)
1682 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0x122);
1684 CSR_CLRBITS_2(sc
, BWI_RF_CHAN_EX
, 0xdfff);
1686 PHY_WRITE(mac
, 0x20, 0x3f3f);
1687 PHY_WRITE(mac
, 0x15, 0xf330);
1689 RF_WRITE(mac
, 0x5a, 0x60);
1690 RF_CLRBITS(mac
, 0x43, 0xff0f);
1692 PHY_WRITE(mac
, 0x5a, 0x480);
1693 PHY_WRITE(mac
, 0x59, 0x810);
1694 PHY_WRITE(mac
, 0x58, 0xd);
1698 nrssi
[1] = (int16_t)PHY_READ(mac
, 0x27);
1701 * Restore saved RF/PHY registers
1703 PHY_WRITE(mac
, save_phy_regs
[0], save_phy
[0]);
1704 RF_WRITE(mac
, save_rf_regs
[0], save_rf
[0]);
1706 CSR_WRITE_2(sc
, BWI_RF_ANTDIV
, ant_div
);
1708 for (i
= 1; i
< 4; ++i
)
1709 PHY_WRITE(mac
, save_phy_regs
[i
], save_phy
[i
]);
1711 bwi_rf_workaround(mac
, rf
->rf_curchan
);
1713 if (phy
->phy_version
!= 0)
1714 CSR_WRITE_2(sc
, BWI_RF_CHAN_EX
, chan_ex
);
1716 for (; i
< SAVE_PHY_MAX
; ++i
)
1717 PHY_WRITE(mac
, save_phy_regs
[i
], save_phy
[i
]);
1719 for (i
= 1; i
< SAVE_RF_MAX
; ++i
)
1720 RF_WRITE(mac
, save_rf_regs
[i
], save_rf
[i
]);
1723 * Install calculated narrow RSSI values
1725 if (nrssi
[0] == nrssi
[1])
1726 rf
->rf_nrssi_slope
= 0x10000;
1728 rf
->rf_nrssi_slope
= 0x400000 / (nrssi
[0] - nrssi
[1]);
1729 if (nrssi
[0] <= -4) {
1730 rf
->rf_nrssi
[0] = nrssi
[0];
1731 rf
->rf_nrssi
[1] = nrssi
[1];
1739 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac
*mac
)
1741 #define SAVE_RF_MAX 2
1742 #define SAVE_PHY_COMM_MAX 10
1743 #define SAVE_PHY6_MAX 8
1745 static const uint16_t save_rf_regs
[SAVE_RF_MAX
] =
1747 static const uint16_t save_phy_comm_regs
[SAVE_PHY_COMM_MAX
] = {
1748 0x0001, 0x0811, 0x0812, 0x0814,
1749 0x0815, 0x005a, 0x0059, 0x0058,
1752 static const uint16_t save_phy6_regs
[SAVE_PHY6_MAX
] = {
1753 0x002e, 0x002f, 0x080f, 0x0810,
1754 0x0801, 0x0060, 0x0014, 0x0478
1757 struct bwi_phy
*phy
= &mac
->mac_phy
;
1758 uint16_t save_rf
[SAVE_RF_MAX
];
1759 uint16_t save_phy_comm
[SAVE_PHY_COMM_MAX
];
1760 uint16_t save_phy6
[SAVE_PHY6_MAX
];
1761 uint16_t rf7b
= 0xffff;
1763 int i
, phy6_idx
= 0;
1765 for (i
= 0; i
< SAVE_PHY_COMM_MAX
; ++i
)
1766 save_phy_comm
[i
] = PHY_READ(mac
, save_phy_comm_regs
[i
]);
1767 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
1768 save_rf
[i
] = RF_READ(mac
, save_rf_regs
[i
]);
1770 PHY_CLRBITS(mac
, 0x429, 0x8000);
1771 PHY_FILT_SETBITS(mac
, 0x1, 0x3fff, 0x4000);
1772 PHY_SETBITS(mac
, 0x811, 0xc);
1773 PHY_FILT_SETBITS(mac
, 0x812, 0xfff3, 0x4);
1774 PHY_CLRBITS(mac
, 0x802, 0x3);
1776 if (phy
->phy_rev
>= 6) {
1777 for (i
= 0; i
< SAVE_PHY6_MAX
; ++i
)
1778 save_phy6
[i
] = PHY_READ(mac
, save_phy6_regs
[i
]);
1780 PHY_WRITE(mac
, 0x2e, 0);
1781 PHY_WRITE(mac
, 0x2f, 0);
1782 PHY_WRITE(mac
, 0x80f, 0);
1783 PHY_WRITE(mac
, 0x810, 0);
1784 PHY_SETBITS(mac
, 0x478, 0x100);
1785 PHY_SETBITS(mac
, 0x801, 0x40);
1786 PHY_SETBITS(mac
, 0x60, 0x40);
1787 PHY_SETBITS(mac
, 0x14, 0x200);
1790 RF_SETBITS(mac
, 0x7a, 0x70);
1791 RF_SETBITS(mac
, 0x7a, 0x80);
1795 nrssi
= bwi_nrssi_11g(mac
);
1797 for (i
= 7; i
>= 4; --i
) {
1798 RF_WRITE(mac
, 0x7b, i
);
1800 nrssi
= bwi_nrssi_11g(mac
);
1801 if (nrssi
< 31 && rf7b
== 0xffff)
1807 struct bwi_gains gains
;
1809 RF_CLRBITS(mac
, 0x7a, 0xff80);
1811 PHY_SETBITS(mac
, 0x814, 0x1);
1812 PHY_CLRBITS(mac
, 0x815, 0x1);
1813 PHY_SETBITS(mac
, 0x811, 0xc);
1814 PHY_SETBITS(mac
, 0x812, 0xc);
1815 PHY_SETBITS(mac
, 0x811, 0x30);
1816 PHY_SETBITS(mac
, 0x812, 0x30);
1817 PHY_WRITE(mac
, 0x5a, 0x480);
1818 PHY_WRITE(mac
, 0x59, 0x810);
1819 PHY_WRITE(mac
, 0x58, 0xd);
1820 if (phy
->phy_version
== 0)
1821 PHY_WRITE(mac
, 0x3, 0x122);
1823 PHY_SETBITS(mac
, 0xa, 0x2000);
1824 PHY_SETBITS(mac
, 0x814, 0x4);
1825 PHY_CLRBITS(mac
, 0x815, 0x4);
1826 PHY_FILT_SETBITS(mac
, 0x3, 0xff9f, 0x40);
1827 RF_SETBITS(mac
, 0x7a, 0xf);
1829 bzero(&gains
, sizeof(gains
));
1830 gains
.tbl_gain1
= 3;
1831 gains
.tbl_gain2
= 0;
1833 bwi_set_gains(mac
, &gains
);
1835 RF_FILT_SETBITS(mac
, 0x43, 0xf0, 0xf);
1838 nrssi
= bwi_nrssi_11g(mac
);
1840 for (i
= 0; i
< 4; ++i
) {
1841 RF_WRITE(mac
, 0x7b, i
);
1843 nrssi
= bwi_nrssi_11g(mac
);
1844 if (nrssi
> -31 && rf7b
== 0xffff)
1853 RF_WRITE(mac
, 0x7b, rf7b
);
1856 * Restore saved RF/PHY registers
1858 if (phy
->phy_rev
>= 6) {
1859 for (phy6_idx
= 0; phy6_idx
< 4; ++phy6_idx
) {
1860 PHY_WRITE(mac
, save_phy6_regs
[phy6_idx
],
1861 save_phy6
[phy6_idx
]);
1865 /* Saved PHY registers 0, 1, 2 are handled later */
1866 for (i
= 3; i
< SAVE_PHY_COMM_MAX
; ++i
)
1867 PHY_WRITE(mac
, save_phy_comm_regs
[i
], save_phy_comm
[i
]);
1869 for (i
= SAVE_RF_MAX
- 1; i
>= 0; --i
)
1870 RF_WRITE(mac
, save_rf_regs
[i
], save_rf
[i
]);
1872 PHY_SETBITS(mac
, 0x802, 0x3);
1873 PHY_SETBITS(mac
, 0x429, 0x8000);
1875 bwi_set_gains(mac
, NULL
);
1877 if (phy
->phy_rev
>= 6) {
1878 for (; phy6_idx
< SAVE_PHY6_MAX
; ++phy6_idx
) {
1879 PHY_WRITE(mac
, save_phy6_regs
[phy6_idx
],
1880 save_phy6
[phy6_idx
]);
1884 PHY_WRITE(mac
, save_phy_comm_regs
[0], save_phy_comm
[0]);
1885 PHY_WRITE(mac
, save_phy_comm_regs
[2], save_phy_comm
[2]);
1886 PHY_WRITE(mac
, save_phy_comm_regs
[1], save_phy_comm
[1]);
1889 #undef SAVE_PHY_COMM_MAX
1890 #undef SAVE_PHY6_MAX
1894 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac
*mac
)
1896 #define SAVE_RF_MAX 3
1897 #define SAVE_PHY_COMM_MAX 4
1898 #define SAVE_PHY3_MAX 8
1900 static const uint16_t save_rf_regs
[SAVE_RF_MAX
] =
1901 { 0x7a, 0x52, 0x43 };
1902 static const uint16_t save_phy_comm_regs
[SAVE_PHY_COMM_MAX
] =
1903 { 0x15, 0x5a, 0x59, 0x58 };
1904 static const uint16_t save_phy3_regs
[SAVE_PHY3_MAX
] = {
1905 0x002e, 0x002f, 0x080f, 0x0810,
1906 0x0801, 0x0060, 0x0014, 0x0478
1909 struct bwi_softc
*sc
= mac
->mac_sc
;
1910 struct bwi_phy
*phy
= &mac
->mac_phy
;
1911 struct bwi_rf
*rf
= &mac
->mac_rf
;
1912 uint16_t save_rf
[SAVE_RF_MAX
];
1913 uint16_t save_phy_comm
[SAVE_PHY_COMM_MAX
];
1914 uint16_t save_phy3
[SAVE_PHY3_MAX
];
1915 uint16_t ant_div
, bbp_atten
, chan_ex
;
1916 struct bwi_gains gains
;
1918 int i
, phy3_idx
= 0;
1920 if (rf
->rf_rev
>= 9)
1922 else if (rf
->rf_rev
== 8)
1923 bwi_rf_set_nrssi_ofs_11g(mac
);
1925 PHY_CLRBITS(mac
, 0x429, 0x8000);
1926 PHY_CLRBITS(mac
, 0x802, 0x3);
1929 * Save RF/PHY registers for later restoration
1931 ant_div
= CSR_READ_2(sc
, BWI_RF_ANTDIV
);
1932 CSR_SETBITS_2(sc
, BWI_RF_ANTDIV
, 0x8000);
1934 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
1935 save_rf
[i
] = RF_READ(mac
, save_rf_regs
[i
]);
1936 for (i
= 0; i
< SAVE_PHY_COMM_MAX
; ++i
)
1937 save_phy_comm
[i
] = PHY_READ(mac
, save_phy_comm_regs
[i
]);
1939 bbp_atten
= CSR_READ_2(sc
, BWI_BBP_ATTEN
);
1940 chan_ex
= CSR_READ_2(sc
, BWI_RF_CHAN_EX
);
1942 if (phy
->phy_rev
>= 3) {
1943 for (i
= 0; i
< SAVE_PHY3_MAX
; ++i
)
1944 save_phy3
[i
] = PHY_READ(mac
, save_phy3_regs
[i
]);
1946 PHY_WRITE(mac
, 0x2e, 0);
1947 PHY_WRITE(mac
, 0x810, 0);
1949 if (phy
->phy_rev
== 4 || phy
->phy_rev
== 6 ||
1950 phy
->phy_rev
== 7) {
1951 PHY_SETBITS(mac
, 0x478, 0x100);
1952 PHY_SETBITS(mac
, 0x810, 0x40);
1953 } else if (phy
->phy_rev
== 3 || phy
->phy_rev
== 5) {
1954 PHY_CLRBITS(mac
, 0x810, 0x40);
1957 PHY_SETBITS(mac
, 0x60, 0x40);
1958 PHY_SETBITS(mac
, 0x14, 0x200);
1964 RF_SETBITS(mac
, 0x7a, 0x70);
1966 bzero(&gains
, sizeof(gains
));
1967 gains
.tbl_gain1
= 0;
1968 gains
.tbl_gain2
= 8;
1970 bwi_set_gains(mac
, &gains
);
1972 RF_CLRBITS(mac
, 0x7a, 0xff08);
1973 if (phy
->phy_rev
>= 2) {
1974 PHY_FILT_SETBITS(mac
, 0x811, 0xffcf, 0x30);
1975 PHY_FILT_SETBITS(mac
, 0x812, 0xffcf, 0x10);
1978 RF_SETBITS(mac
, 0x7a, 0x80);
1980 nrssi
[0] = bwi_nrssi_11g(mac
);
1985 RF_CLRBITS(mac
, 0x7a, 0xff80);
1986 if (phy
->phy_version
>= 2)
1987 PHY_FILT_SETBITS(mac
, 0x3, 0xff9f, 0x40);
1988 CSR_SETBITS_2(sc
, BWI_RF_CHAN_EX
, 0x2000);
1990 RF_SETBITS(mac
, 0x7a, 0xf);
1991 PHY_WRITE(mac
, 0x15, 0xf330);
1992 if (phy
->phy_rev
>= 2) {
1993 PHY_FILT_SETBITS(mac
, 0x812, 0xffcf, 0x20);
1994 PHY_FILT_SETBITS(mac
, 0x811, 0xffcf, 0x20);
1997 bzero(&gains
, sizeof(gains
));
1998 gains
.tbl_gain1
= 3;
1999 gains
.tbl_gain2
= 0;
2001 bwi_set_gains(mac
, &gains
);
2003 if (rf
->rf_rev
== 8) {
2004 RF_WRITE(mac
, 0x43, 0x1f);
2006 RF_FILT_SETBITS(mac
, 0x52, 0xff0f, 0x60);
2007 RF_FILT_SETBITS(mac
, 0x43, 0xfff0, 0x9);
2009 PHY_WRITE(mac
, 0x5a, 0x480);
2010 PHY_WRITE(mac
, 0x59, 0x810);
2011 PHY_WRITE(mac
, 0x58, 0xd);
2014 nrssi
[1] = bwi_nrssi_11g(mac
);
2017 * Install calculated narrow RSSI values
2019 if (nrssi
[1] == nrssi
[0])
2020 rf
->rf_nrssi_slope
= 0x10000;
2022 rf
->rf_nrssi_slope
= 0x400000 / (nrssi
[0] - nrssi
[1]);
2023 if (nrssi
[0] >= -4) {
2024 rf
->rf_nrssi
[0] = nrssi
[1];
2025 rf
->rf_nrssi
[1] = nrssi
[0];
2029 * Restore saved RF/PHY registers
2031 if (phy
->phy_rev
>= 3) {
2032 for (phy3_idx
= 0; phy3_idx
< 4; ++phy3_idx
) {
2033 PHY_WRITE(mac
, save_phy3_regs
[phy3_idx
],
2034 save_phy3
[phy3_idx
]);
2037 if (phy
->phy_rev
>= 2) {
2038 PHY_CLRBITS(mac
, 0x812, 0x30);
2039 PHY_CLRBITS(mac
, 0x811, 0x30);
2042 for (i
= 0; i
< SAVE_RF_MAX
; ++i
)
2043 RF_WRITE(mac
, save_rf_regs
[i
], save_rf
[i
]);
2045 CSR_WRITE_2(sc
, BWI_RF_ANTDIV
, ant_div
);
2046 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, bbp_atten
);
2047 CSR_WRITE_2(sc
, BWI_RF_CHAN_EX
, chan_ex
);
2049 for (i
= 0; i
< SAVE_PHY_COMM_MAX
; ++i
)
2050 PHY_WRITE(mac
, save_phy_comm_regs
[i
], save_phy_comm
[i
]);
2052 bwi_rf_workaround(mac
, rf
->rf_curchan
);
2053 PHY_SETBITS(mac
, 0x802, 0x3);
2054 bwi_set_gains(mac
, NULL
);
2055 PHY_SETBITS(mac
, 0x429, 0x8000);
2057 if (phy
->phy_rev
>= 3) {
2058 for (; phy3_idx
< SAVE_PHY3_MAX
; ++phy3_idx
) {
2059 PHY_WRITE(mac
, save_phy3_regs
[phy3_idx
],
2060 save_phy3
[phy3_idx
]);
2064 bwi_rf_init_sw_nrssi_table(mac
);
2065 bwi_rf_set_nrssi_thr_11g(mac
);
2068 #undef SAVE_PHY_COMM_MAX
2069 #undef SAVE_PHY3_MAX
2073 bwi_rf_init_sw_nrssi_table(struct bwi_mac
*mac
)
2075 struct bwi_rf
*rf
= &mac
->mac_rf
;
2078 d
= 0x1f - rf
->rf_nrssi
[0];
2079 for (i
= 0; i
< BWI_NRSSI_TBLSZ
; ++i
) {
2082 val
= (((i
- d
) * rf
->rf_nrssi_slope
) / 0x10000) + 0x3a;
2085 else if (val
> 0x3f)
2088 rf
->rf_nrssi_table
[i
] = val
;
2093 bwi_rf_init_hw_nrssi_table(struct bwi_mac
*mac
, uint16_t adjust
)
2097 for (i
= 0; i
< BWI_NRSSI_TBLSZ
; ++i
) {
2100 val
= bwi_nrssi_read(mac
, i
);
2108 bwi_nrssi_write(mac
, i
, val
);
2113 bwi_rf_set_nrssi_thr_11b(struct bwi_mac
*mac
)
2115 struct bwi_rf
*rf
= &mac
->mac_rf
;
2118 if (rf
->rf_type
!= BWI_RF_T_BCM2050
||
2119 (mac
->mac_sc
->sc_card_flags
& BWI_CARD_F_SW_NRSSI
) == 0)
2123 * Calculate nrssi threshold
2125 if (rf
->rf_rev
>= 6) {
2126 thr
= (rf
->rf_nrssi
[1] - rf
->rf_nrssi
[0]) * 32;
2127 thr
+= 20 * (rf
->rf_nrssi
[0] + 1);
2130 thr
= rf
->rf_nrssi
[1] - 5;
2134 else if (thr
> 0x3e)
2137 PHY_READ(mac
, BWI_PHYR_NRSSI_THR_11B
); /* dummy read */
2138 PHY_WRITE(mac
, BWI_PHYR_NRSSI_THR_11B
, (((uint16_t)thr
) << 8) | 0x1c);
2140 if (rf
->rf_rev
>= 6) {
2141 PHY_WRITE(mac
, 0x87, 0xe0d);
2142 PHY_WRITE(mac
, 0x86, 0xc0b);
2143 PHY_WRITE(mac
, 0x85, 0xa09);
2144 PHY_WRITE(mac
, 0x84, 0x808);
2145 PHY_WRITE(mac
, 0x83, 0x808);
2146 PHY_WRITE(mac
, 0x82, 0x604);
2147 PHY_WRITE(mac
, 0x81, 0x302);
2148 PHY_WRITE(mac
, 0x80, 0x100);
2152 static __inline
int32_t
2153 _nrssi_threshold(const struct bwi_rf
*rf
, int32_t val
)
2155 val
*= (rf
->rf_nrssi
[1] - rf
->rf_nrssi
[0]);
2156 val
+= (rf
->rf_nrssi
[0] << 6);
2170 bwi_rf_set_nrssi_thr_11g(struct bwi_mac
*mac
)
2176 * Find the two nrssi thresholds
2178 if ((mac
->mac_phy
.phy_flags
& BWI_PHY_F_LINKED
) == 0 ||
2179 (mac
->mac_sc
->sc_card_flags
& BWI_CARD_F_SW_NRSSI
) == 0) {
2182 nrssi
= bwi_nrssi_read(mac
, 0x20);
2194 /* TODO Interfere mode */
2195 thr1
= _nrssi_threshold(&mac
->mac_rf
, 0x11);
2196 thr2
= _nrssi_threshold(&mac
->mac_rf
, 0xe);
2199 #define NRSSI_THR1_MASK __BITS(5, 0)
2200 #define NRSSI_THR2_MASK __BITS(11, 6)
2202 thr
= __SHIFTIN((uint32_t)thr1
, NRSSI_THR1_MASK
) |
2203 __SHIFTIN((uint32_t)thr2
, NRSSI_THR2_MASK
);
2204 PHY_FILT_SETBITS(mac
, BWI_PHYR_NRSSI_THR_11G
, 0xf000, thr
);
2206 #undef NRSSI_THR1_MASK
2207 #undef NRSSI_THR2_MASK
2211 bwi_rf_clear_tssi(struct bwi_mac
*mac
)
2213 /* XXX use function pointer */
2214 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
) {
2220 val
= __SHIFTIN(BWI_INVALID_TSSI
, BWI_LO_TSSI_MASK
) |
2221 __SHIFTIN(BWI_INVALID_TSSI
, BWI_HI_TSSI_MASK
);
2223 for (i
= 0; i
< 2; ++i
) {
2224 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
,
2225 BWI_COMM_MOBJ_TSSI_DS
+ (i
* 2), val
);
2228 for (i
= 0; i
< 2; ++i
) {
2229 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
,
2230 BWI_COMM_MOBJ_TSSI_OFDM
+ (i
* 2), val
);
2236 bwi_rf_clear_state(struct bwi_rf
*rf
)
2240 rf
->rf_flags
&= ~BWI_RF_CLEAR_FLAGS
;
2241 bzero(rf
->rf_lo
, sizeof(rf
->rf_lo
));
2242 bzero(rf
->rf_lo_used
, sizeof(rf
->rf_lo_used
));
2244 rf
->rf_nrssi_slope
= 0;
2245 rf
->rf_nrssi
[0] = BWI_INVALID_NRSSI
;
2246 rf
->rf_nrssi
[1] = BWI_INVALID_NRSSI
;
2248 for (i
= 0; i
< BWI_NRSSI_TBLSZ
; ++i
)
2249 rf
->rf_nrssi_table
[i
] = i
;
2254 bcopy(rf
->rf_txpower_map0
, rf
->rf_txpower_map
,
2255 sizeof(rf
->rf_txpower_map
));
2256 rf
->rf_idle_tssi
= rf
->rf_idle_tssi0
;
2260 bwi_rf_on_11a(struct bwi_mac
*mac
)
2266 bwi_rf_on_11bg(struct bwi_mac
*mac
)
2268 struct bwi_phy
*phy
= &mac
->mac_phy
;
2270 PHY_WRITE(mac
, 0x15, 0x8000);
2271 PHY_WRITE(mac
, 0x15, 0xcc00);
2272 if (phy
->phy_flags
& BWI_PHY_F_LINKED
)
2273 PHY_WRITE(mac
, 0x15, 0xc0);
2275 PHY_WRITE(mac
, 0x15, 0);
2277 bwi_rf_set_chan(mac
, 6 /* XXX */, 1);
2281 bwi_rf_set_ant_mode(struct bwi_mac
*mac
, int ant_mode
)
2283 struct bwi_softc
*sc
= mac
->mac_sc
;
2284 struct bwi_phy
*phy
= &mac
->mac_phy
;
2287 KKASSERT(ant_mode
== BWI_ANT_MODE_0
||
2288 ant_mode
== BWI_ANT_MODE_1
||
2289 ant_mode
== BWI_ANT_MODE_AUTO
);
2291 HFLAGS_CLRBITS(mac
, BWI_HFLAG_AUTO_ANTDIV
);
2293 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
2294 /* NOTE: v4/v3 conflicts, take v3 */
2295 if (mac
->mac_rev
== 2)
2296 val
= BWI_ANT_MODE_AUTO
;
2300 PHY_FILT_SETBITS(mac
, 0x3e2, 0xfe7f, val
);
2301 } else { /* 11a/g */
2302 /* XXX reg/value naming */
2303 val
= ant_mode
<< 7;
2304 PHY_FILT_SETBITS(mac
, 0x401, 0x7e7f, val
);
2306 if (ant_mode
== BWI_ANT_MODE_AUTO
)
2307 PHY_CLRBITS(mac
, 0x42b, 0x100);
2309 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
2312 if (ant_mode
== BWI_ANT_MODE_AUTO
)
2313 PHY_SETBITS(mac
, 0x48c, 0x2000);
2315 PHY_CLRBITS(mac
, 0x48c, 0x2000);
2317 if (phy
->phy_rev
>= 2) {
2318 PHY_SETBITS(mac
, 0x461, 0x10);
2319 PHY_FILT_SETBITS(mac
, 0x4ad, 0xff00, 0x15);
2320 if (phy
->phy_rev
== 2) {
2321 PHY_WRITE(mac
, 0x427, 0x8);
2323 PHY_FILT_SETBITS(mac
, 0x427,
2327 if (phy
->phy_rev
>= 6)
2328 PHY_WRITE(mac
, 0x49b, 0xdc);
2333 /* XXX v4 set AUTO_ANTDIV unconditionally */
2334 if (ant_mode
== BWI_ANT_MODE_AUTO
)
2335 HFLAGS_SETBITS(mac
, BWI_HFLAG_AUTO_ANTDIV
);
2337 val
= ant_mode
<< 8;
2338 MOBJ_FILT_SETBITS_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_TX_BEACON
,
2340 MOBJ_FILT_SETBITS_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_TX_ACK
,
2342 MOBJ_FILT_SETBITS_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_TX_PROBE_RESP
,
2345 /* XXX what's these */
2346 if (phy
->phy_mode
== IEEE80211_MODE_11B
)
2347 CSR_SETBITS_2(sc
, 0x5e, 0x4);
2349 CSR_WRITE_4(sc
, 0x100, 0x1000000);
2350 if (mac
->mac_rev
< 5)
2351 CSR_WRITE_4(sc
, 0x10c, 0x1000000);
2353 mac
->mac_rf
.rf_ant_mode
= ant_mode
;
2357 bwi_rf_get_latest_tssi(struct bwi_mac
*mac
, int8_t tssi
[], uint16_t ofs
)
2361 for (i
= 0; i
< 4; ) {
2364 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, ofs
+ i
);
2365 tssi
[i
++] = (int8_t)__SHIFTOUT(val
, BWI_LO_TSSI_MASK
);
2366 tssi
[i
++] = (int8_t)__SHIFTOUT(val
, BWI_HI_TSSI_MASK
);
2369 for (i
= 0; i
< 4; ++i
) {
2370 if (tssi
[i
] == BWI_INVALID_TSSI
)
2377 bwi_rf_tssi2dbm(struct bwi_mac
*mac
, int8_t tssi
, int8_t *txpwr
)
2379 struct bwi_rf
*rf
= &mac
->mac_rf
;
2382 pwr_idx
= rf
->rf_idle_tssi
+ (int)tssi
- rf
->rf_base_tssi
;
2384 if (pwr_idx
< 0 || pwr_idx
>= BWI_TSSI_MAX
)
2389 else if (pwr_idx
>= BWI_TSSI_MAX
)
2390 pwr_idx
= BWI_TSSI_MAX
- 1;
2393 *txpwr
= rf
->rf_txpower_map
[pwr_idx
];
2398 bwi_rf_calc_rssi_bcm2050(struct bwi_mac
*mac
, const struct bwi_rxbuf_hdr
*hdr
)
2400 uint16_t flags1
, flags3
;
2403 rssi
= hdr
->rxh_rssi
;
2404 flags1
= le16toh(hdr
->rxh_flags1
);
2405 flags3
= le16toh(hdr
->rxh_flags3
);
2407 #define NEW_BCM2050_RSSI
2408 #ifdef NEW_BCM2050_RSSI
2409 if (flags1
& BWI_RXH_F1_OFDM
) {
2412 if (flags3
& BWI_RXH_F3_BCM2050_RSSI
)
2419 if (mac
->mac_sc
->sc_card_flags
& BWI_CARD_F_SW_NRSSI
) {
2420 struct bwi_rf
*rf
= &mac
->mac_rf
;
2422 if (rssi
>= BWI_NRSSI_TBLSZ
)
2423 rssi
= BWI_NRSSI_TBLSZ
- 1;
2425 rssi
= ((31 - (int)rf
->rf_nrssi_table
[rssi
]) * -131) / 128;
2428 rssi
= ((31 - rssi
) * -149) / 128;
2432 if (mac
->mac_phy
.phy_mode
!= IEEE80211_MODE_11G
)
2435 if (flags3
& BWI_RXH_F3_BCM2050_RSSI
)
2438 lna_gain
= __SHIFTOUT(le16toh(hdr
->rxh_phyinfo
),
2439 BWI_RXH_PHYINFO_LNAGAIN
);
2440 DPRINTF(mac
->mac_sc
, BWI_DBG_RF
| BWI_DBG_RX
,
2441 "lna_gain %d, phyinfo 0x%04x\n",
2442 lna_gain
, le16toh(hdr
->rxh_phyinfo
));
2456 * According to v3 spec, we should do _nothing_ here,
2457 * but it seems that the result RSSI will be too low
2458 * (relative to what ath(4) says). Raise it a little
2464 panic("impossible lna gain %d", lna_gain
);
2466 #else /* !NEW_BCM2050_RSSI */
2467 lna_gain
= 0; /* shut up gcc warning */
2469 if (flags1
& BWI_RXH_F1_OFDM
) {
2472 rssi
= (rssi
* 73) / 64;
2474 if (flags3
& BWI_RXH_F3_BCM2050_RSSI
)
2481 if (mac
->mac_sc
->sc_card_flags
& BWI_CARD_F_SW_NRSSI
) {
2482 struct bwi_rf
*rf
= &mac
->mac_rf
;
2484 if (rssi
>= BWI_NRSSI_TBLSZ
)
2485 rssi
= BWI_NRSSI_TBLSZ
- 1;
2487 rssi
= ((31 - (int)rf
->rf_nrssi_table
[rssi
]) * -131) / 128;
2490 rssi
= ((31 - rssi
) * -149) / 128;
2494 if (mac
->mac_phy
.phy_mode
!= IEEE80211_MODE_11G
)
2497 if (flags3
& BWI_RXH_F3_BCM2050_RSSI
)
2499 #endif /* NEW_BCM2050_RSSI */
2504 bwi_rf_calc_rssi_bcm2053(struct bwi_mac
*mac
, const struct bwi_rxbuf_hdr
*hdr
)
2509 rssi
= (((int)hdr
->rxh_rssi
- 11) * 103) / 64;
2511 flags1
= le16toh(hdr
->rxh_flags1
);
2512 if (flags1
& BWI_RXH_F1_BCM2053_RSSI
)
2520 bwi_rf_calc_rssi_bcm2060(struct bwi_mac
*mac
, const struct bwi_rxbuf_hdr
*hdr
)
2524 rssi
= hdr
->rxh_rssi
;
2531 bwi_rf_lo_measure_11b(struct bwi_mac
*mac
)
2537 for (i
= 0; i
< 10; ++i
) {
2538 PHY_WRITE(mac
, 0x15, 0xafa0);
2540 PHY_WRITE(mac
, 0x15, 0xefa0);
2542 PHY_WRITE(mac
, 0x15, 0xffa0);
2545 val
+= PHY_READ(mac
, 0x2c);
2551 bwi_rf_lo_update_11b(struct bwi_mac
*mac
)
2553 struct bwi_softc
*sc
= mac
->mac_sc
;
2554 struct bwi_rf
*rf
= &mac
->mac_rf
;
2555 struct rf_saveregs regs
;
2556 uint16_t rf_val
, phy_val
, min_val
, val
;
2557 uint16_t rf52
, bphy_ctrl
;
2560 DPRINTF(sc
, BWI_DBG_RF
| BWI_DBG_INIT
, "%s enter\n", __func__
);
2562 bzero(®s
, sizeof(regs
));
2566 * Save RF/PHY registers for later restoration
2568 SAVE_PHY_REG(mac
, ®s
, 15);
2569 rf52
= RF_READ(mac
, 0x52) & 0xfff0;
2570 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
2571 SAVE_PHY_REG(mac
, ®s
, 0a
);
2572 SAVE_PHY_REG(mac
, ®s
, 2a
);
2573 SAVE_PHY_REG(mac
, ®s
, 35);
2574 SAVE_PHY_REG(mac
, ®s
, 03);
2575 SAVE_PHY_REG(mac
, ®s
, 01);
2576 SAVE_PHY_REG(mac
, ®s
, 30);
2578 SAVE_RF_REG(mac
, ®s
, 43);
2579 SAVE_RF_REG(mac
, ®s
, 7a
);
2581 bphy_ctrl
= CSR_READ_2(sc
, BWI_BPHY_CTRL
);
2583 SAVE_RF_REG(mac
, ®s
, 52);
2586 PHY_WRITE(mac
, 0x30, 0xff);
2587 CSR_WRITE_2(sc
, BWI_PHY_CTRL
, 0x3f3f);
2588 PHY_WRITE(mac
, 0x35, regs
.phy_35
& 0xff7f);
2589 RF_WRITE(mac
, 0x7a, regs
.rf_7a
& 0xfff0);
2592 PHY_WRITE(mac
, 0x15, 0xb000);
2594 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
2595 PHY_WRITE(mac
, 0x2b, 0x203);
2596 PHY_WRITE(mac
, 0x2a, 0x8a3);
2598 PHY_WRITE(mac
, 0x2b, 0x1402);
2605 min_val
= UINT16_MAX
;
2607 for (i
= 0; i
< 4; ++i
) {
2608 RF_WRITE(mac
, 0x52, rf52
| i
);
2609 bwi_rf_lo_measure_11b(mac
); /* Ignore return value */
2611 for (i
= 0; i
< 10; ++i
) {
2612 RF_WRITE(mac
, 0x52, rf52
| i
);
2614 val
= bwi_rf_lo_measure_11b(mac
) / 10;
2615 if (val
< min_val
) {
2620 RF_WRITE(mac
, 0x52, rf52
| rf_val
);
2626 min_val
= UINT16_MAX
;
2628 for (i
= -4; i
< 5; i
+= 2) {
2631 for (j
= -4; j
< 5; j
+= 2) {
2634 phy2f
= (0x100 * i
) + j
;
2637 PHY_WRITE(mac
, 0x2f, phy2f
);
2639 val
= bwi_rf_lo_measure_11b(mac
) / 10;
2640 if (val
< min_val
) {
2646 PHY_WRITE(mac
, 0x2f, phy_val
+ 0x101);
2649 * Restore saved RF/PHY registers
2651 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
2652 RESTORE_PHY_REG(mac
, ®s
, 0a
);
2653 RESTORE_PHY_REG(mac
, ®s
, 2a
);
2654 RESTORE_PHY_REG(mac
, ®s
, 35);
2655 RESTORE_PHY_REG(mac
, ®s
, 03);
2656 RESTORE_PHY_REG(mac
, ®s
, 01);
2657 RESTORE_PHY_REG(mac
, ®s
, 30);
2659 RESTORE_RF_REG(mac
, ®s
, 43);
2660 RESTORE_RF_REG(mac
, ®s
, 7a
);
2662 RF_FILT_SETBITS(mac
, 0x52, 0xf, regs
.rf_52
);
2664 CSR_WRITE_2(sc
, BWI_BPHY_CTRL
, bphy_ctrl
);
2666 RESTORE_PHY_REG(mac
, ®s
, 15);
2668 bwi_rf_workaround(mac
, rf
->rf_curchan
);