2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
37 * The Broadcom Wireless LAN controller driver.
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/module.h>
45 #include <sys/endian.h>
46 #include <sys/errno.h>
47 #include <sys/firmware.h>
49 #include <sys/mutex.h>
50 #include <machine/bus.h>
51 #include <machine/resource.h>
54 #include <sys/socket.h>
55 #include <sys/sockio.h>
57 #include <net/ethernet.h>
59 #include <net/if_var.h>
60 #include <net/if_arp.h>
61 #include <net/if_dl.h>
62 #include <net/if_llc.h>
63 #include <net/if_media.h>
64 #include <net/if_types.h>
66 #include <dev/pci/pcivar.h>
67 #include <dev/pci/pcireg.h>
68 #include <dev/siba/siba_ids.h>
69 #include <dev/siba/sibareg.h>
70 #include <dev/siba/sibavar.h>
72 #include <net80211/ieee80211_var.h>
73 #include <net80211/ieee80211_radiotap.h>
74 #include <net80211/ieee80211_regdomain.h>
75 #include <net80211/ieee80211_phy.h>
76 #include <net80211/ieee80211_ratectl.h>
78 #include <dev/bwn/if_bwnreg.h>
79 #include <dev/bwn/if_bwnvar.h>
81 #include <dev/bwn/if_bwn_debug.h>
82 #include <dev/bwn/if_bwn_misc.h>
83 #include <dev/bwn/if_bwn_phy_g.h>
85 static void bwn_phy_g_init_sub(struct bwn_mac *);
86 static uint8_t bwn_has_hwpctl(struct bwn_mac *);
87 static void bwn_phy_init_b5(struct bwn_mac *);
88 static void bwn_phy_init_b6(struct bwn_mac *);
89 static void bwn_phy_init_a(struct bwn_mac *);
90 static void bwn_loopback_calcgain(struct bwn_mac *);
91 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
92 static void bwn_lo_g_init(struct bwn_mac *);
93 static void bwn_lo_g_adjust(struct bwn_mac *);
94 static void bwn_lo_get_powervector(struct bwn_mac *);
95 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
96 const struct bwn_bbatt *, const struct bwn_rfatt *);
97 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
98 static void bwn_phy_hwpctl_init(struct bwn_mac *);
99 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
100 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
101 const struct bwn_bbatt *, const struct bwn_rfatt *,
103 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
104 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
105 static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
106 static void bwn_wa_init(struct bwn_mac *);
107 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
109 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
111 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
113 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
114 static void bwn_nrssi_offset(struct bwn_mac *);
115 static void bwn_nrssi_threshold(struct bwn_mac *);
116 static void bwn_nrssi_slope_11g(struct bwn_mac *);
117 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
119 static void bwn_set_original_gains(struct bwn_mac *);
120 static void bwn_hwpctl_early_init(struct bwn_mac *);
121 static void bwn_hwpctl_init_gphy(struct bwn_mac *);
122 static uint16_t bwn_phy_g_chan2freq(uint8_t);
123 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
127 static uint16_t bwn_phy_g_txctl(struct bwn_mac *mac);
128 static int bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset);
129 static void bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp);
130 static void bwn_phy_lock(struct bwn_mac *mac);
131 static void bwn_phy_unlock(struct bwn_mac *mac);
132 static void bwn_rf_lock(struct bwn_mac *mac);
133 static void bwn_rf_unlock(struct bwn_mac *mac);
135 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
136 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
137 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
138 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
139 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
140 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
143 bwn_has_hwpctl(struct bwn_mac *mac)
146 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
148 return (mac->mac_phy.use_hwpctl(mac));
152 bwn_phy_g_attach(struct bwn_mac *mac)
154 struct bwn_softc *sc = mac->mac_sc;
155 struct bwn_phy *phy = &mac->mac_phy;
156 struct bwn_phy_g *pg = &phy->phy_g;
158 int16_t pab0, pab1, pab2;
159 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
162 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
163 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
164 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
165 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
167 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
168 device_printf(sc->sc_dev, "not supported anymore\n");
171 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
173 pg->pg_idletssi = 52;
174 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
178 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
179 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
180 if (pg->pg_tssi2dbm == NULL) {
181 device_printf(sc->sc_dev, "failed to allocate buffer\n");
184 for (i = 0; i < 64; i++) {
185 int32_t m1, m2, f, q, delta;
188 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
189 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
194 device_printf(sc->sc_dev,
195 "failed to generate tssi2dBm\n");
196 free(pg->pg_tssi2dbm, M_DEVBUF);
199 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
204 } while (delta >= 2);
206 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
210 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
215 bwn_phy_g_detach(struct bwn_mac *mac)
217 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
219 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
220 free(pg->pg_tssi2dbm, M_DEVBUF);
221 pg->pg_tssi2dbm = NULL;
227 bwn_phy_g_init_pre(struct bwn_mac *mac)
229 struct bwn_phy *phy = &mac->mac_phy;
230 struct bwn_phy_g *pg = &phy->phy_g;
235 tssi2dbm = pg->pg_tssi2dbm;
236 idletssi = pg->pg_idletssi;
238 memset(pg, 0, sizeof(*pg));
240 pg->pg_tssi2dbm = tssi2dbm;
241 pg->pg_idletssi = idletssi;
243 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
245 for (i = 0; i < N(pg->pg_nrssi); i++)
246 pg->pg_nrssi[i] = -1000;
247 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
248 pg->pg_nrssi_lt[i] = i;
249 pg->pg_lofcal = 0xffff;
250 pg->pg_initval = 0xffff;
251 pg->pg_immode = BWN_IMMODE_NONE;
252 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
253 pg->pg_avgtssi = 0xff;
255 pg->pg_loctl.tx_bias = 0xff;
256 TAILQ_INIT(&pg->pg_loctl.calib_list);
260 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
262 struct bwn_phy *phy = &mac->mac_phy;
263 struct bwn_phy_g *pg = &phy->phy_g;
264 struct bwn_softc *sc = mac->mac_sc;
265 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
266 static const struct bwn_rfatt rfatt0[] = {
267 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
268 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
271 static const struct bwn_rfatt rfatt1[] = {
272 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
275 static const struct bwn_rfatt rfatt2[] = {
276 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
279 static const struct bwn_bbatt bbatt_0[] = {
280 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
283 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
285 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
286 pg->pg_bbatt.att = 0;
288 pg->pg_bbatt.att = 2;
290 /* prepare Radio Attenuation */
291 pg->pg_rfatt.padmix = 0;
293 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
294 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
295 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
296 pg->pg_rfatt.att = 2;
298 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
299 pg->pg_rfatt.att = 3;
304 if (phy->type == BWN_PHYTYPE_A) {
305 pg->pg_rfatt.att = 0x60;
309 switch (phy->rf_ver) {
311 switch (phy->rf_rev) {
313 pg->pg_rfatt.att = 5;
316 if (phy->type == BWN_PHYTYPE_G) {
317 if (siba_get_pci_subvendor(sc->sc_dev) ==
318 SIBA_BOARDVENDOR_BCM &&
319 siba_get_pci_subdevice(sc->sc_dev) ==
320 SIBA_BOARD_BCM4309G &&
321 siba_get_pci_revid(sc->sc_dev) >= 30)
322 pg->pg_rfatt.att = 3;
323 else if (siba_get_pci_subvendor(sc->sc_dev) ==
324 SIBA_BOARDVENDOR_BCM &&
325 siba_get_pci_subdevice(sc->sc_dev) ==
327 pg->pg_rfatt.att = 3;
329 pg->pg_rfatt.att = 1;
331 if (siba_get_pci_subvendor(sc->sc_dev) ==
332 SIBA_BOARDVENDOR_BCM &&
333 siba_get_pci_subdevice(sc->sc_dev) ==
334 SIBA_BOARD_BCM4309G &&
335 siba_get_pci_revid(sc->sc_dev) >= 30)
336 pg->pg_rfatt.att = 7;
338 pg->pg_rfatt.att = 6;
342 if (phy->type == BWN_PHYTYPE_G) {
343 if (siba_get_pci_subvendor(sc->sc_dev) ==
344 SIBA_BOARDVENDOR_BCM &&
345 siba_get_pci_subdevice(sc->sc_dev) ==
346 SIBA_BOARD_BCM4309G &&
347 siba_get_pci_revid(sc->sc_dev) >= 30)
348 pg->pg_rfatt.att = 3;
349 else if (siba_get_pci_subvendor(sc->sc_dev) ==
350 SIBA_BOARDVENDOR_BCM &&
351 siba_get_pci_subdevice(sc->sc_dev) ==
353 pg->pg_rfatt.att = 5;
354 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
355 pg->pg_rfatt.att = 4;
357 pg->pg_rfatt.att = 3;
359 pg->pg_rfatt.att = 6;
362 pg->pg_rfatt.att = 5;
366 pg->pg_rfatt.att = 1;
370 pg->pg_rfatt.att = 5;
373 pg->pg_rfatt.att = 0xa;
374 pg->pg_rfatt.padmix = 1;
378 pg->pg_rfatt.att = 5;
383 switch (phy->rf_rev) {
385 pg->pg_rfatt.att = 6;
390 pg->pg_rfatt.att = 5;
392 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
394 if (!bwn_has_hwpctl(mac)) {
395 lo->rfatt.array = rfatt0;
396 lo->rfatt.len = N(rfatt0);
401 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
402 lo->rfatt.array = rfatt1;
403 lo->rfatt.len = N(rfatt1);
408 lo->rfatt.array = rfatt2;
409 lo->rfatt.len = N(rfatt2);
413 lo->bbatt.array = bbatt_0;
414 lo->bbatt.len = N(bbatt_0);
418 BWN_READ_4(mac, BWN_MACCTL);
421 bwn_reset_core(mac, 0);
422 bwn_phy_g_init_sub(mac);
424 bwn_reset_core(mac, 1);
430 bwn_phy_g_txctl(struct bwn_mac *mac)
432 struct bwn_phy *phy = &mac->mac_phy;
434 if (phy->rf_ver != 0x2050)
436 if (phy->rf_rev == 1)
437 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
439 return (BWN_TXCTL_PA2DB);
440 if (phy->rf_rev == 8)
441 return (BWN_TXCTL_TXMIX);
446 bwn_phy_g_init(struct bwn_mac *mac)
449 bwn_phy_g_init_sub(mac);
454 bwn_phy_g_exit(struct bwn_mac *mac)
456 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
457 struct bwn_lo_calib *cal, *tmp;
461 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
462 TAILQ_REMOVE(&lo->calib_list, cal, list);
468 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
471 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
472 return (BWN_READ_2(mac, BWN_PHYDATA));
476 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
479 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
480 BWN_WRITE_2(mac, BWN_PHYDATA, value);
484 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
487 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
488 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
489 return (BWN_READ_2(mac, BWN_RFDATALO));
493 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
496 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
497 BWN_WRITE_2(mac, BWN_RFCTL, reg);
498 BWN_WRITE_2(mac, BWN_RFDATALO, value);
502 bwn_phy_g_hwpctl(struct bwn_mac *mac)
505 return (mac->mac_phy.rev >= 6);
509 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
511 struct bwn_phy *phy = &mac->mac_phy;
512 struct bwn_phy_g *pg = &phy->phy_g;
513 unsigned int channel;
514 uint16_t rfover, rfoverval;
520 BWN_PHY_WRITE(mac, 0x15, 0x8000);
521 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
522 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
523 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
524 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
525 pg->pg_radioctx_over);
526 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
527 pg->pg_radioctx_overval);
528 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
531 bwn_phy_g_switch_chan(mac, 6, 1);
532 bwn_phy_g_switch_chan(mac, channel, 0);
536 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
537 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
538 pg->pg_radioctx_over = rfover;
539 pg->pg_radioctx_overval = rfoverval;
540 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
541 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
542 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
546 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
549 if ((newchan < 1) || (newchan > 14))
551 bwn_phy_g_switch_chan(mac, newchan, 0);
557 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
564 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
566 struct bwn_phy *phy = &mac->mac_phy;
571 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
574 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
575 bwn_hf_write(mac, hf);
577 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
578 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
579 ((autodiv ? BWN_ANTAUTO1 : antenna)
580 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
583 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
584 if (antenna == BWN_ANTAUTO1)
585 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
587 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
588 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
590 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
592 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
594 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
595 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
597 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
598 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
599 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
600 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
603 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
605 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
606 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
610 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
612 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
613 bwn_hf_write(mac, hf);
617 bwn_phy_g_im(struct bwn_mac *mac, int mode)
619 struct bwn_phy *phy = &mac->mac_phy;
620 struct bwn_phy_g *pg = &phy->phy_g;
622 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
623 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
625 if (phy->rev == 0 || !phy->gmode)
628 pg->pg_aci_wlan_automatic = 0;
633 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
635 struct bwn_phy *phy = &mac->mac_phy;
636 struct bwn_phy_g *pg = &phy->phy_g;
637 struct bwn_softc *sc = mac->mac_sc;
644 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
646 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
647 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
648 if (cck < 0 && ofdm < 0) {
649 if (ignore_tssi == 0)
650 return (BWN_TXPWR_RES_DONE);
654 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
655 if (pg->pg_avgtssi != 0xff)
656 tssi = (tssi + pg->pg_avgtssi) / 2;
657 pg->pg_avgtssi = tssi;
658 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
660 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
661 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
664 device_printf(sc->sc_dev, "invalid max TX-power value\n");
666 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
669 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
670 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
671 tssi, 0x00), 0x3f)]);
673 return (BWN_TXPWR_RES_DONE);
675 rfatt = -((power + 7) / 8);
676 bbatt = (-(power / 2)) - (4 * rfatt);
677 if ((rfatt == 0) && (bbatt == 0))
678 return (BWN_TXPWR_RES_DONE);
679 pg->pg_bbatt_delta = bbatt;
680 pg->pg_rfatt_delta = rfatt;
681 return (BWN_TXPWR_RES_NEED_ADJUST);
685 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
687 struct bwn_phy *phy = &mac->mac_phy;
688 struct bwn_phy_g *pg = &phy->phy_g;
689 struct bwn_softc *sc = mac->mac_sc;
693 bwn_mac_suspend(mac);
695 BWN_ASSERT_LOCKED(sc);
697 bbatt = pg->pg_bbatt.att;
698 bbatt += pg->pg_bbatt_delta;
699 rfatt = pg->pg_rfatt.att;
700 rfatt += pg->pg_rfatt_delta;
702 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
703 txctl = pg->pg_txctl;
704 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
707 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
710 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
712 bbatt += 4 * (rfatt - 2);
715 } else if (rfatt > 4 && txctl) {
726 pg->pg_txctl = txctl;
727 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
728 pg->pg_rfatt.att = rfatt;
729 pg->pg_bbatt.att = bbatt;
731 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
735 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
744 bwn_phy_g_task_15s(struct bwn_mac *mac)
746 struct bwn_phy *phy = &mac->mac_phy;
747 struct bwn_phy_g *pg = &phy->phy_g;
748 struct bwn_softc *sc = mac->mac_sc;
749 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
750 unsigned long expire, now;
751 struct bwn_lo_calib *cal, *tmp;
754 bwn_mac_suspend(mac);
760 if (bwn_has_hwpctl(mac)) {
761 expire = now - BWN_LO_PWRVEC_EXPIRE;
762 if (ieee80211_time_before(lo->pwr_vec_read_time, expire)) {
763 bwn_lo_get_powervector(mac);
764 bwn_phy_g_dc_lookup_init(mac, 0);
769 expire = now - BWN_LO_CALIB_EXPIRE;
770 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
771 if (!ieee80211_time_before(cal->calib_time, expire))
773 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
774 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
775 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
779 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
780 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
781 cal->ctl.i, cal->ctl.q);
783 TAILQ_REMOVE(&lo->calib_list, cal, list);
786 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
787 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
790 device_printf(sc->sc_dev,
791 "failed to recalibrate LO\n");
794 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
795 bwn_lo_write(mac, &cal->ctl);
803 bwn_phy_g_task_60s(struct bwn_mac *mac)
805 struct bwn_phy *phy = &mac->mac_phy;
806 struct bwn_softc *sc = mac->mac_sc;
807 uint8_t old = phy->chan;
809 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
812 bwn_mac_suspend(mac);
813 bwn_nrssi_slope_11g(mac);
814 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
815 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
816 bwn_switch_channel(mac, old);
822 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
825 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
829 bwn_phy_g_init_sub(struct bwn_mac *mac)
831 struct bwn_phy *phy = &mac->mac_phy;
832 struct bwn_phy_g *pg = &phy->phy_g;
833 struct bwn_softc *sc = mac->mac_sc;
837 bwn_phy_init_b5(mac);
839 bwn_phy_init_b6(mac);
841 if (phy->rev >= 2 || phy->gmode)
845 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
846 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
849 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
850 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
853 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
854 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
856 if (phy->gmode || phy->rev >= 2) {
857 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
858 tmp &= BWN_PHYVER_VERSION;
859 if (tmp == 3 || tmp == 5) {
860 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
861 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
864 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
868 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
869 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
870 if (phy->rf_rev == 8) {
871 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
872 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
874 if (BWN_HAS_LOOPBACK(phy))
875 bwn_loopback_calcgain(mac);
877 if (phy->rf_rev != 8) {
878 if (pg->pg_initval == 0xffff)
879 pg->pg_initval = bwn_rf_init_bcm2050(mac);
881 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
884 if (BWN_HAS_TXMAG(phy)) {
885 BWN_RF_WRITE(mac, 0x52,
886 (BWN_RF_READ(mac, 0x52) & 0xff00)
887 | pg->pg_loctl.tx_bias |
888 pg->pg_loctl.tx_magn);
890 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
893 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
894 (pg->pg_loctl.tx_bias << 12));
896 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
897 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
899 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
901 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
903 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
904 if (phy->gmode || phy->rev >= 2) {
905 bwn_lo_g_adjust(mac);
906 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
909 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
910 for (i = 0; i < 64; i++) {
911 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
912 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
913 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
916 bwn_nrssi_threshold(mac);
917 } else if (phy->gmode || phy->rev >= 2) {
918 if (pg->pg_nrssi[0] == -1000) {
919 KASSERT(pg->pg_nrssi[1] == -1000,
920 ("%s:%d: fail", __func__, __LINE__));
921 bwn_nrssi_slope_11g(mac);
923 bwn_nrssi_threshold(mac);
925 if (phy->rf_rev == 8)
926 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
927 bwn_phy_hwpctl_init(mac);
928 if ((siba_get_chipid(sc->sc_dev) == 0x4306
929 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
930 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
931 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
936 bwn_phy_init_b5(struct bwn_mac *mac)
938 struct bwn_phy *phy = &mac->mac_phy;
939 struct bwn_phy_g *pg = &phy->phy_g;
940 struct bwn_softc *sc = mac->mac_sc;
941 uint16_t offset, value;
944 if (phy->analog == 1)
945 BWN_RF_SET(mac, 0x007a, 0x0050);
946 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
947 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
949 for (offset = 0x00a8; offset < 0x00c7; offset++) {
950 BWN_PHY_WRITE(mac, offset, value);
954 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
955 if (phy->rf_ver == 0x2050)
956 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
958 if (phy->gmode || phy->rev >= 2) {
959 if (phy->rf_ver == 0x2050) {
960 BWN_RF_SET(mac, 0x007a, 0x0020);
961 BWN_RF_SET(mac, 0x0051, 0x0004);
963 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
965 BWN_PHY_SET(mac, 0x0802, 0x0100);
966 BWN_PHY_SET(mac, 0x042b, 0x2000);
968 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
970 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
971 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
972 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
975 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
976 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
978 if (phy->analog == 1) {
979 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
980 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
981 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
982 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
983 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
985 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
986 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
987 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
989 if (phy->analog == 1)
990 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
992 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
994 if (phy->analog == 0)
995 BWN_WRITE_2(mac, 0x03e4, 0x3000);
997 old_channel = phy->chan;
998 bwn_phy_g_switch_chan(mac, 7, 0);
1000 if (phy->rf_ver != 0x2050) {
1001 BWN_RF_WRITE(mac, 0x0075, 0x0080);
1002 BWN_RF_WRITE(mac, 0x0079, 0x0081);
1005 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1006 BWN_RF_WRITE(mac, 0x0050, 0x0023);
1008 if (phy->rf_ver == 0x2050) {
1009 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1010 BWN_RF_WRITE(mac, 0x005a, 0x0070);
1013 BWN_RF_WRITE(mac, 0x005b, 0x007b);
1014 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
1015 BWN_RF_SET(mac, 0x007a, 0x0007);
1017 bwn_phy_g_switch_chan(mac, old_channel, 0);
1018 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
1019 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
1020 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
1022 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
1025 if (phy->rf_ver == 0x2050)
1026 BWN_RF_WRITE(mac, 0x005d, 0x000d);
1028 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
1032 bwn_loopback_calcgain(struct bwn_mac *mac)
1034 struct bwn_phy *phy = &mac->mac_phy;
1035 struct bwn_phy_g *pg = &phy->phy_g;
1036 struct bwn_softc *sc = mac->mac_sc;
1037 uint16_t backup_phy[16] = { 0 };
1038 uint16_t backup_radio[3];
1039 uint16_t backup_bband;
1040 uint16_t i, j, loop_i_max;
1042 uint16_t loop1_outer_done, loop1_inner_done;
1044 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
1045 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
1046 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
1047 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
1048 if (phy->rev != 1) {
1049 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
1050 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
1052 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
1053 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
1054 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
1055 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
1056 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
1057 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
1058 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
1059 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
1060 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
1061 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1062 backup_bband = pg->pg_bbatt.att;
1063 backup_radio[0] = BWN_RF_READ(mac, 0x52);
1064 backup_radio[1] = BWN_RF_READ(mac, 0x43);
1065 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
1067 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
1068 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
1069 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
1070 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
1071 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
1072 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
1073 if (phy->rev != 1) {
1074 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
1075 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
1076 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
1077 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
1079 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
1080 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
1081 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
1082 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
1084 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
1085 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1086 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1088 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
1089 if (phy->rev != 1) {
1090 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
1091 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
1093 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
1095 if (phy->rf_rev == 8)
1096 BWN_RF_WRITE(mac, 0x43, 0x000f);
1098 BWN_RF_WRITE(mac, 0x52, 0);
1099 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
1101 bwn_phy_g_set_bbatt(mac, 11);
1104 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
1106 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
1107 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
1109 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
1110 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
1112 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
1113 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
1115 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
1116 if (phy->rev >= 7) {
1117 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
1118 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
1121 BWN_RF_MASK(mac, 0x7a, 0x00f7);
1124 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
1125 for (i = 0; i < loop_i_max; i++) {
1126 for (j = 0; j < 16; j++) {
1127 BWN_RF_WRITE(mac, 0x43, i);
1128 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
1130 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
1131 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
1133 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
1138 loop1_outer_done = i;
1139 loop1_inner_done = j;
1141 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
1143 for (j = j - 8; j < 16; j++) {
1144 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
1145 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
1146 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
1149 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
1156 if (phy->rev != 1) {
1157 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
1158 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
1160 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
1161 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
1162 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
1163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
1164 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
1165 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
1166 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
1167 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
1168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
1170 bwn_phy_g_set_bbatt(mac, backup_bband);
1172 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
1173 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
1174 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
1176 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
1178 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
1179 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
1180 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
1181 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
1183 pg->pg_max_lb_gain =
1184 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
1185 pg->pg_trsw_rx_gain = trsw_rx * 2;
1189 bwn_rf_init_bcm2050(struct bwn_mac *mac)
1191 struct bwn_phy *phy = &mac->mac_phy;
1192 uint32_t tmp1 = 0, tmp2 = 0;
1193 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
1194 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
1195 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
1196 static const uint8_t rcc_table[] = {
1197 0x02, 0x03, 0x01, 0x0f,
1198 0x06, 0x07, 0x05, 0x0f,
1199 0x0a, 0x0b, 0x09, 0x0f,
1200 0x0e, 0x0f, 0x0d, 0x0f,
1203 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
1204 rfoverval = rfover = cck3 = 0;
1205 radio0 = BWN_RF_READ(mac, 0x43);
1206 radio1 = BWN_RF_READ(mac, 0x51);
1207 radio2 = BWN_RF_READ(mac, 0x52);
1208 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
1209 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
1210 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
1211 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
1213 if (phy->type == BWN_PHYTYPE_B) {
1214 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
1215 reg0 = BWN_READ_2(mac, 0x3ec);
1217 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
1218 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
1219 } else if (phy->gmode || phy->rev >= 2) {
1220 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
1221 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
1222 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
1223 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
1224 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
1225 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
1227 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
1228 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
1229 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
1230 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
1231 if (BWN_HAS_LOOPBACK(phy)) {
1232 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
1233 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
1235 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
1237 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
1238 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
1241 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1242 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1244 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
1245 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
1247 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
1249 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
1250 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
1251 reg1 = BWN_READ_2(mac, 0x3e6);
1252 reg2 = BWN_READ_2(mac, 0x3f4);
1254 if (phy->analog == 0)
1255 BWN_WRITE_2(mac, 0x03e6, 0x0122);
1257 if (phy->analog >= 2)
1258 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
1259 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
1260 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
1263 reg = BWN_RF_READ(mac, 0x60);
1264 index = (reg & 0x001e) >> 1;
1265 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
1267 if (phy->type == BWN_PHYTYPE_B)
1268 BWN_RF_WRITE(mac, 0x78, 0x26);
1269 if (phy->gmode || phy->rev >= 2) {
1270 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1271 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1274 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
1275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
1276 if (phy->gmode || phy->rev >= 2) {
1277 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1278 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1281 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
1282 BWN_RF_SET(mac, 0x51, 0x0004);
1283 if (phy->rf_rev == 8)
1284 BWN_RF_WRITE(mac, 0x43, 0x1f);
1286 BWN_RF_WRITE(mac, 0x52, 0);
1287 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
1289 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1291 for (i = 0; i < 16; i++) {
1292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
1293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1294 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1295 if (phy->gmode || phy->rev >= 2) {
1296 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1297 bwn_rf_2050_rfoverval(mac,
1298 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1300 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1302 if (phy->gmode || phy->rev >= 2) {
1303 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1304 bwn_rf_2050_rfoverval(mac,
1305 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1307 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
1309 if (phy->gmode || phy->rev >= 2) {
1310 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1311 bwn_rf_2050_rfoverval(mac,
1312 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
1314 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
1316 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1317 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1318 if (phy->gmode || phy->rev >= 2) {
1319 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1320 bwn_rf_2050_rfoverval(mac,
1321 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1323 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1327 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1331 for (i = 0; i < 16; i++) {
1332 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
1333 BWN_RF_WRITE(mac, 0x78, radio78);
1335 for (j = 0; j < 16; j++) {
1336 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
1337 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1338 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1339 if (phy->gmode || phy->rev >= 2) {
1340 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1341 bwn_rf_2050_rfoverval(mac,
1342 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1344 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1346 if (phy->gmode || phy->rev >= 2) {
1347 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1348 bwn_rf_2050_rfoverval(mac,
1349 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1351 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
1353 if (phy->gmode || phy->rev >= 2) {
1354 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1355 bwn_rf_2050_rfoverval(mac,
1356 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
1358 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
1360 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1361 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1362 if (phy->gmode || phy->rev >= 2) {
1363 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1364 bwn_rf_2050_rfoverval(mac,
1365 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1367 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1375 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
1376 BWN_RF_WRITE(mac, 0x51, radio1);
1377 BWN_RF_WRITE(mac, 0x52, radio2);
1378 BWN_RF_WRITE(mac, 0x43, radio0);
1379 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
1380 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
1381 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
1382 BWN_WRITE_2(mac, 0x3e6, reg1);
1383 if (phy->analog != 0)
1384 BWN_WRITE_2(mac, 0x3f4, reg2);
1385 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
1386 bwn_spu_workaround(mac, phy->chan);
1387 if (phy->type == BWN_PHYTYPE_B) {
1388 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
1389 BWN_WRITE_2(mac, 0x3ec, reg0);
1390 } else if (phy->gmode) {
1391 BWN_WRITE_2(mac, BWN_PHY_RADIO,
1392 BWN_READ_2(mac, BWN_PHY_RADIO)
1394 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
1395 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
1396 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
1397 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
1399 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
1400 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
1401 if (BWN_HAS_LOOPBACK(phy)) {
1402 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
1403 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
1407 return ((i > 15) ? radio78 : rcc);
1411 bwn_phy_init_b6(struct bwn_mac *mac)
1413 struct bwn_phy *phy = &mac->mac_phy;
1414 struct bwn_phy_g *pg = &phy->phy_g;
1415 struct bwn_softc *sc = mac->mac_sc;
1416 uint16_t offset, val;
1417 uint8_t old_channel;
1419 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
1420 ("%s:%d: fail", __func__, __LINE__));
1422 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
1423 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
1424 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
1425 BWN_RF_WRITE(mac, 0x51, 0x37);
1426 BWN_RF_WRITE(mac, 0x52, 0x70);
1427 BWN_RF_WRITE(mac, 0x53, 0xb3);
1428 BWN_RF_WRITE(mac, 0x54, 0x9b);
1429 BWN_RF_WRITE(mac, 0x5a, 0x88);
1430 BWN_RF_WRITE(mac, 0x5b, 0x88);
1431 BWN_RF_WRITE(mac, 0x5d, 0x88);
1432 BWN_RF_WRITE(mac, 0x5e, 0x88);
1433 BWN_RF_WRITE(mac, 0x7d, 0x88);
1435 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
1437 if (phy->rf_rev == 8) {
1438 BWN_RF_WRITE(mac, 0x51, 0);
1439 BWN_RF_WRITE(mac, 0x52, 0x40);
1440 BWN_RF_WRITE(mac, 0x53, 0xb7);
1441 BWN_RF_WRITE(mac, 0x54, 0x98);
1442 BWN_RF_WRITE(mac, 0x5a, 0x88);
1443 BWN_RF_WRITE(mac, 0x5b, 0x6b);
1444 BWN_RF_WRITE(mac, 0x5c, 0x0f);
1445 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
1446 BWN_RF_WRITE(mac, 0x5d, 0xfa);
1447 BWN_RF_WRITE(mac, 0x5e, 0xd8);
1449 BWN_RF_WRITE(mac, 0x5d, 0xf5);
1450 BWN_RF_WRITE(mac, 0x5e, 0xb8);
1452 BWN_RF_WRITE(mac, 0x0073, 0x0003);
1453 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
1454 BWN_RF_WRITE(mac, 0x007c, 0x0001);
1455 BWN_RF_WRITE(mac, 0x007e, 0x0008);
1457 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
1458 BWN_PHY_WRITE(mac, offset, val);
1461 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
1462 BWN_PHY_WRITE(mac, offset, val);
1465 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
1466 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
1469 if (phy->type == BWN_PHYTYPE_G) {
1470 BWN_RF_SET(mac, 0x007a, 0x0020);
1471 BWN_RF_SET(mac, 0x0051, 0x0004);
1472 BWN_PHY_SET(mac, 0x0802, 0x0100);
1473 BWN_PHY_SET(mac, 0x042b, 0x2000);
1474 BWN_PHY_WRITE(mac, 0x5b, 0);
1475 BWN_PHY_WRITE(mac, 0x5c, 0);
1478 old_channel = phy->chan;
1479 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
1481 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1482 BWN_RF_WRITE(mac, 0x0050, 0x0023);
1484 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
1485 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
1486 BWN_RF_WRITE(mac, 0x50, 0x20);
1488 if (phy->rf_rev <= 2) {
1489 BWN_RF_WRITE(mac, 0x7c, 0x20);
1490 BWN_RF_WRITE(mac, 0x5a, 0x70);
1491 BWN_RF_WRITE(mac, 0x5b, 0x7b);
1492 BWN_RF_WRITE(mac, 0x5c, 0xb0);
1494 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
1496 bwn_phy_g_switch_chan(mac, old_channel, 0);
1498 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
1499 if (phy->rf_rev >= 6)
1500 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
1502 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
1503 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
1504 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
1506 if (phy->rf_rev <= 5)
1507 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
1508 if (phy->rf_rev <= 2)
1509 BWN_RF_WRITE(mac, 0x005d, 0x000d);
1511 if (phy->analog == 4) {
1512 BWN_WRITE_2(mac, 0x3e4, 9);
1513 BWN_PHY_MASK(mac, 0x61, 0x0fff);
1515 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
1516 if (phy->type == BWN_PHYTYPE_B)
1517 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1518 else if (phy->type == BWN_PHYTYPE_G)
1519 BWN_WRITE_2(mac, 0x03e6, 0x0);
1523 bwn_phy_init_a(struct bwn_mac *mac)
1525 struct bwn_phy *phy = &mac->mac_phy;
1526 struct bwn_softc *sc = mac->mac_sc;
1528 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
1529 ("%s:%d: fail", __func__, __LINE__));
1531 if (phy->rev >= 6) {
1532 if (phy->type == BWN_PHYTYPE_A)
1533 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
1534 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
1535 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
1537 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
1542 if (phy->type == BWN_PHYTYPE_G &&
1543 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
1544 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
1548 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
1552 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
1553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
1557 bwn_wa_agc(struct bwn_mac *mac)
1559 struct bwn_phy *phy = &mac->mac_phy;
1561 if (phy->rev == 1) {
1562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
1563 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
1564 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
1565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
1566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
1567 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
1568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
1569 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
1570 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
1572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
1573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
1574 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
1575 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
1578 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
1580 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
1581 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
1582 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
1583 BWN_RF_SET(mac, 0x7a, 0x0008);
1584 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
1585 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
1586 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
1587 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
1589 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
1590 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
1591 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
1592 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
1593 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
1594 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
1595 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
1596 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
1597 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
1598 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
1599 if (phy->rev == 1) {
1600 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
1601 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
1603 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
1604 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
1605 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
1606 if (phy->rev >= 6) {
1607 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
1608 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
1609 (uint16_t)~0xf000, 0x3000);
1612 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
1613 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
1614 if (phy->rev == 1) {
1615 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
1616 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
1617 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
1618 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
1619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
1620 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
1621 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
1622 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
1624 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
1625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
1626 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
1627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
1629 if (phy->rev >= 6) {
1630 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
1631 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
1633 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
1637 bwn_wa_grev1(struct bwn_mac *mac)
1639 struct bwn_phy *phy = &mac->mac_phy;
1641 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
1642 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
1643 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
1645 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1647 /* init CRSTHRES and ANTDWELL */
1648 if (phy->rev == 1) {
1649 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
1650 } else if (phy->rev == 2) {
1651 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
1652 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
1653 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1655 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
1656 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
1657 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
1658 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1660 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
1661 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
1662 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
1664 /* XXX support PHY-A??? */
1665 for (i = 0; i < N(bwn_tab_finefreqg); i++)
1666 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
1667 bwn_tab_finefreqg[i]);
1669 /* XXX support PHY-A??? */
1671 for (i = 0; i < N(bwn_tab_noise_g1); i++)
1672 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1673 bwn_tab_noise_g1[i]);
1675 for (i = 0; i < N(bwn_tab_noise_g2); i++)
1676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1677 bwn_tab_noise_g2[i]);
1680 for (i = 0; i < N(bwn_tab_rotor); i++)
1681 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
1684 /* XXX support PHY-A??? */
1685 if (phy->rev >= 6) {
1686 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
1688 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
1690 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
1692 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
1694 for (i = 0; i < N(bwn_tab_retard); i++)
1695 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
1698 if (phy->rev == 1) {
1699 for (i = 0; i < 16; i++)
1700 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
1703 for (i = 0; i < 32; i++)
1704 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
1711 bwn_wa_grev26789(struct bwn_mac *mac)
1713 struct bwn_phy *phy = &mac->mac_phy;
1715 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
1718 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1720 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
1722 /* init CRSTHRES and ANTDWELL */
1724 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
1725 else if (phy->rev == 2) {
1726 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
1727 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
1728 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1730 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
1731 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
1732 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
1733 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1736 for (i = 0; i < 64; i++)
1737 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
1739 /* XXX support PHY-A??? */
1741 for (i = 0; i < N(bwn_tab_noise_g1); i++)
1742 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1743 bwn_tab_noise_g1[i]);
1745 for (i = 0; i < N(bwn_tab_noise_g2); i++)
1746 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1747 bwn_tab_noise_g2[i]);
1749 /* XXX support PHY-A??? */
1750 if (phy->rev >= 6) {
1751 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
1753 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
1755 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
1757 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
1759 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
1760 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
1761 bwn_tab_sigmasqr2[i]);
1763 if (phy->rev == 1) {
1764 for (i = 0; i < 16; i++)
1765 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
1768 for (i = 0; i < 32; i++)
1769 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
1774 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
1776 if (phy->type == BWN_PHYTYPE_A)
1777 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
1779 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
1781 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
1782 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
1783 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
1786 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
1787 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
1791 bwn_wa_init(struct bwn_mac *mac)
1793 struct bwn_phy *phy = &mac->mac_phy;
1794 struct bwn_softc *sc = mac->mac_sc;
1796 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1807 bwn_wa_grev26789(mac);
1810 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1813 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
1814 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
1815 siba_get_pci_revid(sc->sc_dev) != 0x17) {
1817 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
1819 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
1822 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
1823 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
1824 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
1827 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
1828 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1830 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1832 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1834 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1836 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1838 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1843 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
1844 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
1845 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
1848 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
1849 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
1853 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1856 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
1859 addr = table + offset;
1860 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
1861 (addr - 1 != pg->pg_ofdmtab_addr)) {
1862 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
1863 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
1865 pg->pg_ofdmtab_addr = addr;
1866 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
1870 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1873 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
1876 addr = table + offset;
1877 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
1878 (addr - 1 != pg->pg_ofdmtab_addr)) {
1879 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
1880 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
1882 pg->pg_ofdmtab_addr = addr;
1884 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
1885 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
1889 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1893 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
1894 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
1898 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
1902 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
1903 ("%s:%d: fail", __func__, __LINE__));
1905 value = (uint8_t) (ctl->q);
1906 value |= ((uint8_t) (ctl->i)) << 8;
1907 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
1911 bwn_lo_calcfeed(struct bwn_mac *mac,
1912 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
1914 struct bwn_phy *phy = &mac->mac_phy;
1915 struct bwn_softc *sc = mac->mac_sc;
1917 uint16_t feedthrough;
1920 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
1921 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
1923 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
1924 ("%s:%d: fail", __func__, __LINE__));
1925 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
1926 ("%s:%d: fail", __func__, __LINE__));
1928 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
1930 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
1931 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
1933 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
1935 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
1936 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1938 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
1939 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1941 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
1942 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1944 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
1946 pga |= BWN_PHY_PGACTL_UNKNOWN;
1947 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1949 pga |= BWN_PHY_PGACTL_LOWBANDW;
1950 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1952 pga |= BWN_PHY_PGACTL_LPF;
1953 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1956 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1958 return (feedthrough);
1962 bwn_lo_txctl_regtable(struct bwn_mac *mac,
1963 uint16_t *value, uint16_t *pad_mix_gain)
1965 struct bwn_phy *phy = &mac->mac_phy;
1966 uint16_t reg, v, padmix;
1968 if (phy->type == BWN_PHYTYPE_B) {
1970 if (phy->rf_rev <= 5) {
1978 if (phy->rev >= 2 && phy->rf_rev == 8) {
1991 *pad_mix_gain = padmix;
1997 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
1999 struct bwn_phy *phy = &mac->mac_phy;
2000 struct bwn_phy_g *pg = &phy->phy_g;
2001 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2003 uint16_t trsw_rx, pga;
2004 uint16_t rf_pctl_reg;
2006 static const uint8_t tx_bias_values[] = {
2007 0x09, 0x08, 0x0a, 0x01, 0x00,
2008 0x02, 0x05, 0x04, 0x06,
2010 static const uint8_t tx_magn_values[] = {
2014 if (!BWN_HAS_LOOPBACK(phy)) {
2022 lb_gain = pg->pg_max_lb_gain / 2;
2025 pga = abs(10 - lb_gain) / 6;
2026 pga = MIN(MAX(pga, 0), 15);
2033 if ((phy->rev >= 2) &&
2034 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
2037 if ((10 - lb_gain) < cmp_val)
2038 tmp = (10 - lb_gain);
2046 rf_pctl_reg = cmp_val;
2051 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
2052 bwn_phy_g_set_bbatt(mac, 2);
2054 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
2056 BWN_RF_MASK(mac, reg, mask);
2058 if (BWN_HAS_TXMAG(phy)) {
2061 int min_feedth = 0xffff;
2062 uint8_t tx_magn, tx_bias;
2064 for (i = 0; i < N(tx_magn_values); i++) {
2065 tx_magn = tx_magn_values[i];
2066 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
2067 for (j = 0; j < N(tx_bias_values); j++) {
2068 tx_bias = tx_bias_values[j];
2069 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
2070 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
2072 if (feedthrough < min_feedth) {
2073 lo->tx_bias = tx_bias;
2074 lo->tx_magn = tx_magn;
2075 min_feedth = feedthrough;
2077 if (lo->tx_bias == 0)
2080 BWN_RF_WRITE(mac, 0x52,
2081 (BWN_RF_READ(mac, 0x52)
2082 & 0xff00) | lo->tx_bias | lo->
2088 BWN_RF_MASK(mac, 0x52, 0xfff0);
2091 BWN_GETTIME(lo->txctl_measured_time);
2095 bwn_lo_get_powervector(struct bwn_mac *mac)
2097 struct bwn_phy *phy = &mac->mac_phy;
2098 struct bwn_phy_g *pg = &phy->phy_g;
2099 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2102 uint64_t power_vector = 0;
2104 for (i = 0; i < 8; i += 2) {
2105 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
2106 power_vector |= (tmp << (i * 8));
2107 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
2110 lo->power_vector = power_vector;
2112 BWN_GETTIME(lo->pwr_vec_read_time);
2116 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
2119 struct bwn_phy *phy = &mac->mac_phy;
2120 struct bwn_phy_g *pg = &phy->phy_g;
2123 if (max_rx_gain < 0)
2126 if (BWN_HAS_LOOPBACK(phy)) {
2131 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
2132 if (max_rx_gain >= trsw_rx_gain) {
2133 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
2137 trsw_rx_gain = max_rx_gain;
2138 if (trsw_rx_gain < 9) {
2139 pg->pg_lna_lod_gain = 0;
2141 pg->pg_lna_lod_gain = 1;
2144 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
2145 pg->pg_pga_gain = trsw_rx_gain / 3;
2146 if (pg->pg_pga_gain >= 5) {
2147 pg->pg_pga_gain -= 5;
2148 pg->pg_lna_gain = 2;
2150 pg->pg_lna_gain = 0;
2152 pg->pg_lna_gain = 0;
2153 pg->pg_trsw_rx_gain = 0x20;
2154 if (max_rx_gain >= 0x14) {
2155 pg->pg_lna_lod_gain = 1;
2156 pg->pg_pga_gain = 2;
2157 } else if (max_rx_gain >= 0x12) {
2158 pg->pg_lna_lod_gain = 1;
2159 pg->pg_pga_gain = 1;
2160 } else if (max_rx_gain >= 0xf) {
2161 pg->pg_lna_lod_gain = 1;
2162 pg->pg_pga_gain = 0;
2164 pg->pg_lna_lod_gain = 0;
2165 pg->pg_pga_gain = 0;
2169 tmp = BWN_RF_READ(mac, 0x7a);
2170 if (pg->pg_lna_lod_gain == 0)
2174 BWN_RF_WRITE(mac, 0x7a, tmp);
2178 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
2180 struct bwn_phy *phy = &mac->mac_phy;
2181 struct bwn_phy_g *pg = &phy->phy_g;
2182 struct bwn_softc *sc = mac->mac_sc;
2183 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2187 if (bwn_has_hwpctl(mac)) {
2188 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
2189 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
2190 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
2191 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
2192 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
2194 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
2195 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
2196 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
2197 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
2199 if (phy->type == BWN_PHYTYPE_B &&
2200 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
2201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
2202 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
2204 if (phy->rev >= 2) {
2205 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
2206 sav->phy_analogoverval =
2207 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
2208 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2209 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2210 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
2211 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
2212 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
2214 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
2215 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
2216 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
2217 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
2218 if (phy->type == BWN_PHYTYPE_G) {
2219 if ((phy->rev >= 7) &&
2220 (siba_sprom_get_bf_lo(sc->sc_dev) &
2222 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
2224 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
2227 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
2229 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
2231 sav->reg0 = BWN_READ_2(mac, 0x3f4);
2232 sav->reg1 = BWN_READ_2(mac, 0x3e2);
2233 sav->rf0 = BWN_RF_READ(mac, 0x43);
2234 sav->rf1 = BWN_RF_READ(mac, 0x7a);
2235 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
2236 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
2237 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
2238 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
2240 if (!BWN_HAS_TXMAG(phy)) {
2241 sav->rf2 = BWN_RF_READ(mac, 0x52);
2244 if (phy->type == BWN_PHYTYPE_B) {
2245 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
2246 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
2247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
2248 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
2250 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
2253 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
2257 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
2258 BWN_PHY_WRITE(mac, tmp, 0x007f);
2260 tmp = sav->phy_syncctl;
2261 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
2263 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
2265 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
2266 if (phy->type == BWN_PHYTYPE_G ||
2267 (phy->type == BWN_PHYTYPE_B &&
2268 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
2269 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
2271 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
2273 bwn_dummy_transmission(mac, 0, 1);
2274 bwn_phy_g_switch_chan(mac, 6, 0);
2275 BWN_RF_READ(mac, 0x51);
2276 if (phy->type == BWN_PHYTYPE_G)
2277 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
2280 if (ieee80211_time_before(lo->txctl_measured_time,
2281 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
2282 bwn_lo_measure_txctl_values(mac);
2284 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
2285 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
2287 if (phy->type == BWN_PHYTYPE_B)
2288 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
2290 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
2295 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
2297 struct bwn_phy *phy = &mac->mac_phy;
2298 struct bwn_phy_g *pg = &phy->phy_g;
2301 if (phy->rev >= 2) {
2302 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
2303 tmp = (pg->pg_pga_gain << 8);
2304 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
2306 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
2308 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
2310 tmp = (pg->pg_pga_gain | 0xefa0);
2311 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
2313 if (phy->type == BWN_PHYTYPE_G) {
2315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
2317 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
2319 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
2321 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
2323 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
2324 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
2325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
2326 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
2327 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
2328 BWN_RF_WRITE(mac, 0x43, sav->rf0);
2329 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
2330 if (!BWN_HAS_TXMAG(phy)) {
2332 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
2334 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
2335 if (phy->type == BWN_PHYTYPE_B &&
2336 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
2337 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
2338 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
2340 if (phy->rev >= 2) {
2341 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
2342 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
2343 sav->phy_analogoverval);
2344 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
2345 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
2346 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
2347 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
2348 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
2350 if (bwn_has_hwpctl(mac)) {
2351 tmp = (sav->phy_lomask & 0xbfff);
2352 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
2353 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
2354 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
2355 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
2356 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
2358 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
2362 bwn_lo_probe_loctl(struct bwn_mac *mac,
2363 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
2365 struct bwn_phy *phy = &mac->mac_phy;
2366 struct bwn_phy_g *pg = &phy->phy_g;
2367 struct bwn_loctl orig, test;
2368 struct bwn_loctl prev = { -100, -100 };
2369 static const struct bwn_loctl modifiers[] = {
2370 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
2371 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
2373 int begin, end, lower = 0, i;
2376 if (d->curstate == 0) {
2379 } else if (d->curstate % 2 == 0) {
2380 begin = d->curstate - 1;
2381 end = d->curstate + 1;
2383 begin = d->curstate - 2;
2384 end = d->curstate + 2;
2391 memcpy(&orig, probe, sizeof(struct bwn_loctl));
2395 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
2396 memcpy(&test, &orig, sizeof(struct bwn_loctl));
2397 test.i += modifiers[i - 1].i * d->multipler;
2398 test.q += modifiers[i - 1].q * d->multipler;
2399 if ((test.i != prev.i || test.q != prev.q) &&
2400 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
2401 bwn_lo_write(mac, &test);
2402 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2403 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2404 if (feedth < d->feedth) {
2405 memcpy(probe, &test,
2406 sizeof(struct bwn_loctl));
2409 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
2413 memcpy(&prev, &test, sizeof(prev));
2427 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
2429 struct bwn_phy *phy = &mac->mac_phy;
2430 struct bwn_phy_g *pg = &phy->phy_g;
2431 struct bwn_lo_g_sm d;
2432 struct bwn_loctl probe;
2433 int lower, repeat, cnt = 0;
2438 if (BWN_HAS_LOOPBACK(phy))
2441 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
2442 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
2445 bwn_lo_write(mac, &d.loctl);
2446 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2447 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2448 if (feedth < 0x258) {
2449 if (feedth >= 0x12c)
2453 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2454 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2459 KASSERT(d.curstate >= 0 && d.curstate <= 8,
2460 ("%s:%d: fail", __func__, __LINE__));
2461 memcpy(&probe, &d.loctl,
2462 sizeof(struct bwn_loctl));
2463 lower = bwn_lo_probe_loctl(mac, &probe, &d);
2466 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
2468 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
2470 } while (d.nmeasure < 24);
2471 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
2473 if (BWN_HAS_LOOPBACK(phy)) {
2474 if (d.feedth > 0x1194)
2476 else if (d.feedth < 0x5dc)
2479 if (d.feedth <= 0x5dc) {
2484 } else if (cnt == 2)
2487 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
2488 } while (++cnt < repeat);
2491 static struct bwn_lo_calib *
2492 bwn_lo_calibset(struct bwn_mac *mac,
2493 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
2495 struct bwn_phy *phy = &mac->mac_phy;
2496 struct bwn_phy_g *pg = &phy->phy_g;
2497 struct bwn_loctl loctl = { 0, 0 };
2498 struct bwn_lo_calib *cal;
2499 struct bwn_lo_g_value sval = { 0 };
2501 uint16_t pad, reg, value;
2503 sval.old_channel = phy->chan;
2504 bwn_mac_suspend(mac);
2505 bwn_lo_save(mac, &sval);
2507 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
2508 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
2509 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
2511 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
2514 if (BWN_HAS_LOOPBACK(phy))
2515 rxgain += pg->pg_max_lb_gain;
2516 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
2517 bwn_phy_g_set_bbatt(mac, bbatt->att);
2518 bwn_lo_probe_sm(mac, &loctl, &rxgain);
2520 bwn_lo_restore(mac, &sval);
2521 bwn_mac_enable(mac);
2523 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
2525 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
2528 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
2529 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
2530 memcpy(&cal->ctl, &loctl, sizeof(loctl));
2532 BWN_GETTIME(cal->calib_time);
2537 static struct bwn_lo_calib *
2538 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
2539 const struct bwn_rfatt *rfatt)
2541 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2542 struct bwn_lo_calib *c;
2544 TAILQ_FOREACH(c, &lo->calib_list, list) {
2545 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
2547 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
2552 c = bwn_lo_calibset(mac, bbatt, rfatt);
2555 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
2561 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
2563 struct bwn_phy *phy = &mac->mac_phy;
2564 struct bwn_phy_g *pg = &phy->phy_g;
2565 struct bwn_softc *sc = mac->mac_sc;
2566 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2567 const struct bwn_rfatt *rfatt;
2568 const struct bwn_bbatt *bbatt;
2571 int rf_offset, bb_offset;
2572 uint8_t changed = 0;
2574 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
2575 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
2576 ("%s:%d: fail", __func__, __LINE__));
2578 pvector = lo->power_vector;
2579 if (!update && !pvector)
2582 bwn_mac_suspend(mac);
2584 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
2585 struct bwn_lo_calib *cal;
2589 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
2591 bb_offset = i / lo->rfatt.len;
2592 rf_offset = i % lo->rfatt.len;
2593 bbatt = &(lo->bbatt.array[bb_offset]);
2594 rfatt = &(lo->rfatt.array[rf_offset]);
2596 cal = bwn_lo_calibset(mac, bbatt, rfatt);
2598 device_printf(sc->sc_dev, "LO: Could not "
2599 "calibrate DC table entry\n");
2602 val = (uint8_t)(cal->ctl.q);
2603 val |= ((uint8_t)(cal->ctl.i)) << 4;
2604 free(cal, M_DEVBUF);
2608 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
2609 | ((val & 0x00ff) << 8);
2611 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
2616 for (i = 0; i < BWN_DC_LT_SIZE; i++)
2617 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
2619 bwn_mac_enable(mac);
2623 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
2628 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
2633 bwn_lo_g_adjust(struct bwn_mac *mac)
2635 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2636 struct bwn_lo_calib *cal;
2637 struct bwn_rfatt rf;
2639 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
2640 bwn_lo_fixup_rfatt(&rf);
2642 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
2645 bwn_lo_write(mac, &cal->ctl);
2649 bwn_lo_g_init(struct bwn_mac *mac)
2652 if (!bwn_has_hwpctl(mac))
2655 bwn_lo_get_powervector(mac);
2656 bwn_phy_g_dc_lookup_init(mac, 1);
2660 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
2663 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
2664 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
2668 bwn_nrssi_threshold(struct bwn_mac *mac)
2670 struct bwn_phy *phy = &mac->mac_phy;
2671 struct bwn_phy_g *pg = &phy->phy_g;
2672 struct bwn_softc *sc = mac->mac_sc;
2677 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2679 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
2680 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
2688 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
2689 a += (pg->pg_nrssi[0] << 6);
2690 a += (a < 32) ? 31 : 32;
2692 a = MIN(MAX(a, -31), 31);
2694 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
2695 b += (pg->pg_nrssi[0] << 6);
2701 b = MIN(MAX(b, -31), 31);
2703 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
2704 tmpu16 |= ((uint32_t)b & 0x0000003f);
2705 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
2706 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
2710 tmp16 = bwn_nrssi_read(mac, 0x20);
2713 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
2717 bwn_nrssi_slope_11g(struct bwn_mac *mac)
2719 #define SAVE_RF_MAX 3
2720 #define SAVE_PHY_COMM_MAX 4
2721 #define SAVE_PHY3_MAX 8
2722 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
2723 { 0x7a, 0x52, 0x43 };
2724 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
2725 { 0x15, 0x5a, 0x59, 0x58 };
2726 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
2727 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
2728 0x0801, 0x0060, 0x0014, 0x0478
2730 struct bwn_phy *phy = &mac->mac_phy;
2731 struct bwn_phy_g *pg = &phy->phy_g;
2732 int32_t i, tmp32, phy3_idx = 0;
2733 uint16_t delta, tmp;
2734 uint16_t save_rf[SAVE_RF_MAX];
2735 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
2736 uint16_t save_phy3[SAVE_PHY3_MAX];
2737 uint16_t ant_div, phy0, chan_ex;
2738 int16_t nrssi0, nrssi1;
2740 KASSERT(phy->type == BWN_PHYTYPE_G,
2741 ("%s:%d: fail", __func__, __LINE__));
2743 if (phy->rf_rev >= 9)
2745 if (phy->rf_rev == 8)
2746 bwn_nrssi_offset(mac);
2748 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
2749 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
2752 * Save RF/PHY registers for later restoration
2754 ant_div = BWN_READ_2(mac, 0x03e2);
2755 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
2756 for (i = 0; i < SAVE_RF_MAX; ++i)
2757 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
2758 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2759 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
2761 phy0 = BWN_READ_2(mac, BWN_PHY0);
2762 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
2763 if (phy->rev >= 3) {
2764 for (i = 0; i < SAVE_PHY3_MAX; ++i)
2765 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
2766 BWN_PHY_WRITE(mac, 0x002e, 0);
2767 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
2772 BWN_PHY_SET(mac, 0x0478, 0x0100);
2773 BWN_PHY_SET(mac, 0x0801, 0x0040);
2777 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
2780 BWN_PHY_SET(mac, 0x0060, 0x0040);
2781 BWN_PHY_SET(mac, 0x0014, 0x0200);
2786 BWN_RF_SET(mac, 0x007a, 0x0070);
2787 bwn_set_all_gains(mac, 0, 8, 0);
2788 BWN_RF_MASK(mac, 0x007a, 0x00f7);
2789 if (phy->rev >= 2) {
2790 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
2791 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
2793 BWN_RF_SET(mac, 0x007a, 0x0080);
2796 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2797 if (nrssi0 >= 0x0020)
2803 BWN_RF_MASK(mac, 0x007a, 0x007f);
2805 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
2807 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
2808 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
2809 BWN_RF_SET(mac, 0x007a, 0x000f);
2810 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
2811 if (phy->rev >= 2) {
2812 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
2813 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
2816 bwn_set_all_gains(mac, 3, 0, 1);
2817 if (phy->rf_rev == 8) {
2818 BWN_RF_WRITE(mac, 0x0043, 0x001f);
2820 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
2821 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
2822 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
2823 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
2825 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
2826 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
2827 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
2829 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2832 * Install calculated narrow RSSI values
2834 if (nrssi1 >= 0x0020)
2836 if (nrssi0 == nrssi1)
2837 pg->pg_nrssi_slope = 0x00010000;
2839 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
2841 pg->pg_nrssi[0] = nrssi1;
2842 pg->pg_nrssi[1] = nrssi0;
2846 * Restore saved RF/PHY registers
2848 if (phy->rev >= 3) {
2849 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
2850 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2851 save_phy3[phy3_idx]);
2854 if (phy->rev >= 2) {
2855 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
2856 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
2859 for (i = 0; i < SAVE_RF_MAX; ++i)
2860 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
2862 BWN_WRITE_2(mac, 0x03e2, ant_div);
2863 BWN_WRITE_2(mac, 0x03e6, phy0);
2864 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
2866 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2867 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
2869 bwn_spu_workaround(mac, phy->chan);
2870 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
2871 bwn_set_original_gains(mac);
2872 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
2873 if (phy->rev >= 3) {
2874 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
2875 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2876 save_phy3[phy3_idx]);
2880 delta = 0x1f - pg->pg_nrssi[0];
2881 for (i = 0; i < 64; i++) {
2882 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
2883 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
2884 pg->pg_nrssi_lt[i] = tmp32;
2887 bwn_nrssi_threshold(mac);
2889 #undef SAVE_PHY_COMM_MAX
2890 #undef SAVE_PHY3_MAX
2894 bwn_nrssi_offset(struct bwn_mac *mac)
2896 #define SAVE_RF_MAX 2
2897 #define SAVE_PHY_COMM_MAX 10
2898 #define SAVE_PHY6_MAX 8
2899 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
2901 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
2902 0x0001, 0x0811, 0x0812, 0x0814,
2903 0x0815, 0x005a, 0x0059, 0x0058,
2906 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
2907 0x002e, 0x002f, 0x080f, 0x0810,
2908 0x0801, 0x0060, 0x0014, 0x0478
2910 struct bwn_phy *phy = &mac->mac_phy;
2911 int i, phy6_idx = 0;
2912 uint16_t save_rf[SAVE_RF_MAX];
2913 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
2914 uint16_t save_phy6[SAVE_PHY6_MAX];
2916 uint16_t saved = 0xffff;
2918 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2919 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
2920 for (i = 0; i < SAVE_RF_MAX; ++i)
2921 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
2923 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
2924 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
2925 BWN_PHY_SET(mac, 0x0811, 0x000c);
2926 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
2927 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
2928 if (phy->rev >= 6) {
2929 for (i = 0; i < SAVE_PHY6_MAX; ++i)
2930 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
2932 BWN_PHY_WRITE(mac, 0x002e, 0);
2933 BWN_PHY_WRITE(mac, 0x002f, 0);
2934 BWN_PHY_WRITE(mac, 0x080f, 0);
2935 BWN_PHY_WRITE(mac, 0x0810, 0);
2936 BWN_PHY_SET(mac, 0x0478, 0x0100);
2937 BWN_PHY_SET(mac, 0x0801, 0x0040);
2938 BWN_PHY_SET(mac, 0x0060, 0x0040);
2939 BWN_PHY_SET(mac, 0x0014, 0x0200);
2941 BWN_RF_SET(mac, 0x007a, 0x0070);
2942 BWN_RF_SET(mac, 0x007a, 0x0080);
2945 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2949 for (i = 7; i >= 4; i--) {
2950 BWN_RF_WRITE(mac, 0x007b, i);
2952 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
2956 if (nrssi < 31 && saved == 0xffff)
2959 if (saved == 0xffff)
2962 BWN_RF_MASK(mac, 0x007a, 0x007f);
2963 if (phy->rev != 1) {
2964 BWN_PHY_SET(mac, 0x0814, 0x0001);
2965 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
2967 BWN_PHY_SET(mac, 0x0811, 0x000c);
2968 BWN_PHY_SET(mac, 0x0812, 0x000c);
2969 BWN_PHY_SET(mac, 0x0811, 0x0030);
2970 BWN_PHY_SET(mac, 0x0812, 0x0030);
2971 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
2972 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
2973 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
2975 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
2977 BWN_PHY_SET(mac, 0x000a, 0x2000);
2978 if (phy->rev != 1) {
2979 BWN_PHY_SET(mac, 0x0814, 0x0004);
2980 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
2982 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
2983 BWN_RF_SET(mac, 0x007a, 0x000f);
2984 bwn_set_all_gains(mac, 3, 0, 1);
2985 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
2987 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2991 for (i = 0; i < 4; i++) {
2992 BWN_RF_WRITE(mac, 0x007b, i);
2994 nrssi = (int16_t)((BWN_PHY_READ(mac,
2995 0x047f) >> 8) & 0x003f);
2998 if (nrssi > -31 && saved == 0xffff)
3001 if (saved == 0xffff)
3006 BWN_RF_WRITE(mac, 0x007b, saved);
3009 * Restore saved RF/PHY registers
3011 if (phy->rev >= 6) {
3012 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
3013 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
3014 save_phy6[phy6_idx]);
3017 if (phy->rev != 1) {
3018 for (i = 3; i < 5; i++)
3019 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
3022 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
3023 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
3025 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
3026 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
3028 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
3029 BWN_PHY_SET(mac, 0x0429, 0x8000);
3030 bwn_set_original_gains(mac);
3031 if (phy->rev >= 6) {
3032 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
3033 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
3034 save_phy6[phy6_idx]);
3038 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
3039 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
3040 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
3044 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
3047 struct bwn_phy *phy = &mac->mac_phy;
3049 uint16_t start = 0x08, end = 0x18;
3053 if (phy->rev <= 1) {
3058 table = BWN_OFDMTAB_GAINX;
3060 table = BWN_OFDMTAB_GAINX_R1;
3061 for (i = 0; i < 4; i++)
3062 bwn_ofdmtab_write_2(mac, table, i, first);
3064 for (i = start; i < end; i++)
3065 bwn_ofdmtab_write_2(mac, table, i, second);
3068 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
3069 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
3070 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
3071 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
3073 bwn_dummy_transmission(mac, 0, 1);
3077 bwn_set_original_gains(struct bwn_mac *mac)
3079 struct bwn_phy *phy = &mac->mac_phy;
3082 uint16_t start = 0x0008, end = 0x0018;
3084 if (phy->rev <= 1) {
3089 table = BWN_OFDMTAB_GAINX;
3091 table = BWN_OFDMTAB_GAINX_R1;
3092 for (i = 0; i < 4; i++) {
3094 tmp |= (i & 0x0001) << 1;
3095 tmp |= (i & 0x0002) >> 1;
3097 bwn_ofdmtab_write_2(mac, table, i, tmp);
3100 for (i = start; i < end; i++)
3101 bwn_ofdmtab_write_2(mac, table, i, i - start);
3103 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
3104 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
3105 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
3106 bwn_dummy_transmission(mac, 0, 1);
3110 bwn_phy_hwpctl_init(struct bwn_mac *mac)
3112 struct bwn_phy *phy = &mac->mac_phy;
3113 struct bwn_phy_g *pg = &phy->phy_g;
3114 struct bwn_rfatt old_rfatt, rfatt;
3115 struct bwn_bbatt old_bbatt, bbatt;
3116 struct bwn_softc *sc = mac->mac_sc;
3117 uint8_t old_txctl = 0;
3119 KASSERT(phy->type == BWN_PHYTYPE_G,
3120 ("%s:%d: fail", __func__, __LINE__));
3122 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
3123 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
3126 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
3128 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
3132 bwn_hwpctl_early_init(mac);
3133 if (pg->pg_curtssi == 0) {
3134 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
3135 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
3137 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
3138 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
3139 old_txctl = pg->pg_txctl;
3142 if (phy->rf_rev == 8) {
3149 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
3151 bwn_dummy_transmission(mac, 0, 1);
3152 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
3153 if (phy->rf_ver == 0x2050 && phy->analog == 0)
3154 BWN_RF_MASK(mac, 0x0076, 0xff7b);
3156 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
3157 &old_rfatt, old_txctl);
3159 bwn_hwpctl_init_gphy(mac);
3162 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
3163 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
3164 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
3165 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
3169 bwn_hwpctl_early_init(struct bwn_mac *mac)
3171 struct bwn_phy *phy = &mac->mac_phy;
3173 if (!bwn_has_hwpctl(mac)) {
3174 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
3178 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
3179 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
3180 BWN_PHY_SET(mac, 0x047c, 0x0002);
3181 BWN_PHY_SET(mac, 0x047a, 0xf000);
3182 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
3183 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
3184 BWN_PHY_SET(mac, 0x005d, 0x8000);
3185 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
3186 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
3187 BWN_PHY_SET(mac, 0x0036, 0x0400);
3189 BWN_PHY_SET(mac, 0x0036, 0x0200);
3190 BWN_PHY_SET(mac, 0x0036, 0x0400);
3191 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
3192 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
3193 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
3194 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
3195 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
3200 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
3202 struct bwn_phy *phy = &mac->mac_phy;
3203 struct bwn_phy_g *pg = &phy->phy_g;
3204 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
3206 uint16_t nr_written = 0, tmp, value;
3209 if (!bwn_has_hwpctl(mac)) {
3210 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
3214 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
3215 (pg->pg_idletssi - pg->pg_curtssi));
3216 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
3217 (pg->pg_idletssi - pg->pg_curtssi));
3219 for (i = 0; i < 32; i++)
3220 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
3221 for (i = 32; i < 64; i++)
3222 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
3223 for (i = 0; i < 64; i += 2) {
3224 value = (uint16_t) pg->pg_tssi2dbm[i];
3225 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
3226 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
3229 for (rf = 0; rf < lo->rfatt.len; rf++) {
3230 for (bb = 0; bb < lo->bbatt.len; bb++) {
3231 if (nr_written >= 0x40)
3233 tmp = lo->bbatt.array[bb].att;
3235 if (phy->rf_rev == 8)
3239 tmp |= lo->rfatt.array[rf].att;
3240 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
3245 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
3246 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
3248 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
3249 BWN_PHY_SET(mac, 0x0478, 0x0800);
3250 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
3251 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
3253 bwn_phy_g_dc_lookup_init(mac, 1);
3254 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
3258 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
3260 struct bwn_softc *sc = mac->mac_sc;
3263 bwn_spu_workaround(mac, channel);
3265 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
3267 if (channel == 14) {
3268 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
3270 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
3273 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
3274 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
3275 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
3279 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
3280 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
3284 bwn_phy_g_chan2freq(uint8_t channel)
3286 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
3288 KASSERT(channel >= 1 && channel <= 14,
3289 ("%s:%d: fail", __func__, __LINE__));
3291 return (bwn_phy_g_rf_channels[channel - 1]);
3295 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
3296 const struct bwn_rfatt *rfatt, uint8_t txctl)
3298 struct bwn_phy *phy = &mac->mac_phy;
3299 struct bwn_phy_g *pg = &phy->phy_g;
3300 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
3302 uint16_t tx_bias, tx_magn;
3306 tx_bias = lo->tx_bias;
3307 tx_magn = lo->tx_magn;
3308 if (tx_bias == 0xff)
3311 pg->pg_txctl = txctl;
3312 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
3313 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
3314 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
3315 bwn_phy_g_set_bbatt(mac, bb);
3316 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
3317 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
3318 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
3320 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
3321 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
3323 if (BWN_HAS_TXMAG(phy))
3324 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
3326 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
3327 bwn_lo_g_adjust(mac);
3331 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
3334 struct bwn_phy *phy = &mac->mac_phy;
3336 if (phy->analog == 0) {
3337 BWN_WRITE_2(mac, BWN_PHY0,
3338 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
3341 if (phy->analog > 1) {
3342 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
3345 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
3349 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
3351 struct bwn_phy *phy = &mac->mac_phy;
3352 struct bwn_phy_g *pg = &phy->phy_g;
3353 struct bwn_softc *sc = mac->mac_sc;
3358 if (phy->gmode == 0)
3361 if (BWN_HAS_LOOPBACK(phy)) {
3362 max_lb_gain = pg->pg_max_lb_gain;
3363 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
3364 if (max_lb_gain >= 0x46) {
3366 max_lb_gain -= 0x46;
3367 } else if (max_lb_gain >= 0x3a) {
3369 max_lb_gain -= 0x3a;
3370 } else if (max_lb_gain >= 0x2e) {
3372 max_lb_gain -= 0x2e;
3375 max_lb_gain -= 0x10;
3378 for (i = 0; i < 16; i++) {
3379 max_lb_gain -= (i * 6);
3380 if (max_lb_gain < 6)
3384 if ((phy->rev < 7) ||
3385 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
3386 if (reg == BWN_PHY_RFOVER) {
3388 } else if (reg == BWN_PHY_RFOVERVAL) {
3391 case BWN_LPD(0, 1, 1):
3393 case BWN_LPD(0, 0, 1):
3394 case BWN_LPD(1, 0, 1):
3395 return (0x0092 | extlna);
3396 case BWN_LPD(1, 0, 0):
3397 return (0x0093 | extlna);
3400 ("%s:%d: fail", __func__, __LINE__));
3402 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3404 if (reg == BWN_PHY_RFOVER)
3406 if (reg == BWN_PHY_RFOVERVAL) {
3411 case BWN_LPD(0, 1, 1):
3413 case BWN_LPD(0, 0, 1):
3414 return (0x8092 | extlna);
3415 case BWN_LPD(1, 0, 1):
3416 return (0x2092 | extlna);
3417 case BWN_LPD(1, 0, 0):
3418 return (0x2093 | extlna);
3421 ("%s:%d: fail", __func__, __LINE__));
3423 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3428 if ((phy->rev < 7) ||
3429 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
3430 if (reg == BWN_PHY_RFOVER) {
3432 } else if (reg == BWN_PHY_RFOVERVAL) {
3434 case BWN_LPD(0, 1, 1):
3436 case BWN_LPD(0, 0, 1):
3438 case BWN_LPD(1, 0, 1):
3440 case BWN_LPD(1, 0, 0):
3444 ("%s:%d: fail", __func__, __LINE__));
3446 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3448 if (reg == BWN_PHY_RFOVER) {
3450 } else if (reg == BWN_PHY_RFOVERVAL) {
3452 case BWN_LPD(0, 1, 1):
3454 case BWN_LPD(0, 0, 1):
3456 case BWN_LPD(1, 0, 1):
3458 case BWN_LPD(1, 0, 0):
3462 ("%s:%d: fail", __func__, __LINE__));
3464 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3470 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
3473 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
3475 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
3476 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
3478 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
3482 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
3484 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
3485 unsigned int a, b, c, d;
3489 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
3491 b = (tmp >> 8) & 0xff;
3492 c = (tmp >> 16) & 0xff;
3493 d = (tmp >> 24) & 0xff;
3494 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
3495 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
3497 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
3498 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
3499 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
3502 a = (a + 32) & 0x3f;
3503 b = (b + 32) & 0x3f;
3504 c = (c + 32) & 0x3f;
3505 d = (d + 32) & 0x3f;
3508 avg = (a + b + c + d + 2) / 4;
3510 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
3511 & BWN_HF_4DB_CCK_POWERBOOST)
3512 avg = (avg >= 13) ? (avg - 13) : 0;
3518 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
3520 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
3521 int rfatt = *rfattp;
3522 int bbatt = *bbattp;
3525 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
3527 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
3529 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
3531 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
3533 if (bbatt > lo->bbatt.max) {
3538 if (bbatt < lo->bbatt.min) {
3543 if (rfatt > lo->rfatt.max) {
3548 if (rfatt < lo->rfatt.min) {
3556 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
3557 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
3561 bwn_phy_lock(struct bwn_mac *mac)
3563 struct bwn_softc *sc = mac->mac_sc;
3564 struct ieee80211com *ic = &sc->sc_ic;
3566 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
3567 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
3569 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
3570 bwn_psctl(mac, BWN_PS_AWAKE);
3574 bwn_phy_unlock(struct bwn_mac *mac)
3576 struct bwn_softc *sc = mac->mac_sc;
3577 struct ieee80211com *ic = &sc->sc_ic;
3579 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
3580 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
3582 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
3587 bwn_rf_lock(struct bwn_mac *mac)
3590 BWN_WRITE_4(mac, BWN_MACCTL,
3591 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
3592 BWN_READ_4(mac, BWN_MACCTL);
3597 bwn_rf_unlock(struct bwn_mac *mac)
3600 BWN_READ_2(mac, BWN_PHYVER);
3601 BWN_WRITE_4(mac, BWN_MACCTL,
3602 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);