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>
69 #include <net80211/ieee80211_var.h>
70 #include <net80211/ieee80211_radiotap.h>
71 #include <net80211/ieee80211_regdomain.h>
72 #include <net80211/ieee80211_phy.h>
73 #include <net80211/ieee80211_ratectl.h>
75 #include <dev/bwn/if_bwn_siba.h>
77 #include <dev/bwn/if_bwnreg.h>
78 #include <dev/bwn/if_bwnvar.h>
80 #include <dev/bwn/if_bwn_debug.h>
81 #include <dev/bwn/if_bwn_misc.h>
82 #include <dev/bwn/if_bwn_phy_g.h>
84 static void bwn_phy_g_init_sub(struct bwn_mac *);
85 static uint8_t bwn_has_hwpctl(struct bwn_mac *);
86 static void bwn_phy_init_b5(struct bwn_mac *);
87 static void bwn_phy_init_b6(struct bwn_mac *);
88 static void bwn_phy_init_a(struct bwn_mac *);
89 static void bwn_loopback_calcgain(struct bwn_mac *);
90 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
91 static void bwn_lo_g_init(struct bwn_mac *);
92 static void bwn_lo_g_adjust(struct bwn_mac *);
93 static void bwn_lo_get_powervector(struct bwn_mac *);
94 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
95 const struct bwn_bbatt *, const struct bwn_rfatt *);
96 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
97 static void bwn_phy_hwpctl_init(struct bwn_mac *);
98 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
99 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
100 const struct bwn_bbatt *, const struct bwn_rfatt *,
102 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
103 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
104 static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
105 static void bwn_wa_init(struct bwn_mac *);
106 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
108 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
110 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
112 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
113 static void bwn_nrssi_offset(struct bwn_mac *);
114 static void bwn_nrssi_threshold(struct bwn_mac *);
115 static void bwn_nrssi_slope_11g(struct bwn_mac *);
116 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
118 static void bwn_set_original_gains(struct bwn_mac *);
119 static void bwn_hwpctl_early_init(struct bwn_mac *);
120 static void bwn_hwpctl_init_gphy(struct bwn_mac *);
121 static uint16_t bwn_phy_g_chan2freq(uint8_t);
122 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
126 static uint16_t bwn_phy_g_txctl(struct bwn_mac *mac);
127 static int bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset);
128 static void bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp);
129 static void bwn_phy_lock(struct bwn_mac *mac);
130 static void bwn_phy_unlock(struct bwn_mac *mac);
131 static void bwn_rf_lock(struct bwn_mac *mac);
132 static void bwn_rf_unlock(struct bwn_mac *mac);
134 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
135 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
136 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
137 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
138 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
139 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
142 bwn_has_hwpctl(struct bwn_mac *mac)
145 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
147 return (mac->mac_phy.use_hwpctl(mac));
151 bwn_phy_g_attach(struct bwn_mac *mac)
153 struct bwn_softc *sc = mac->mac_sc;
154 struct bwn_phy *phy = &mac->mac_phy;
155 struct bwn_phy_g *pg = &phy->phy_g;
157 int16_t pab0, pab1, pab2;
158 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
161 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
162 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
163 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
164 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
166 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
167 device_printf(sc->sc_dev, "not supported anymore\n");
170 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
172 pg->pg_idletssi = 52;
173 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
177 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
178 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
179 if (pg->pg_tssi2dbm == NULL) {
180 device_printf(sc->sc_dev, "failed to allocate buffer\n");
183 for (i = 0; i < 64; i++) {
184 int32_t m1, m2, f, q, delta;
187 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
188 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
193 device_printf(sc->sc_dev,
194 "failed to generate tssi2dBm\n");
195 free(pg->pg_tssi2dbm, M_DEVBUF);
198 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
203 } while (delta >= 2);
205 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
209 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
214 bwn_phy_g_detach(struct bwn_mac *mac)
216 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
218 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
219 free(pg->pg_tssi2dbm, M_DEVBUF);
220 pg->pg_tssi2dbm = NULL;
226 bwn_phy_g_init_pre(struct bwn_mac *mac)
228 struct bwn_phy *phy = &mac->mac_phy;
229 struct bwn_phy_g *pg = &phy->phy_g;
234 tssi2dbm = pg->pg_tssi2dbm;
235 idletssi = pg->pg_idletssi;
237 memset(pg, 0, sizeof(*pg));
239 pg->pg_tssi2dbm = tssi2dbm;
240 pg->pg_idletssi = idletssi;
242 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
244 for (i = 0; i < N(pg->pg_nrssi); i++)
245 pg->pg_nrssi[i] = -1000;
246 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
247 pg->pg_nrssi_lt[i] = i;
248 pg->pg_lofcal = 0xffff;
249 pg->pg_initval = 0xffff;
250 pg->pg_immode = BWN_IMMODE_NONE;
251 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
252 pg->pg_avgtssi = 0xff;
254 pg->pg_loctl.tx_bias = 0xff;
255 TAILQ_INIT(&pg->pg_loctl.calib_list);
259 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
261 struct bwn_phy *phy = &mac->mac_phy;
262 struct bwn_phy_g *pg = &phy->phy_g;
263 struct bwn_softc *sc = mac->mac_sc;
264 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
265 static const struct bwn_rfatt rfatt0[] = {
266 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
267 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
270 static const struct bwn_rfatt rfatt1[] = {
271 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
274 static const struct bwn_rfatt rfatt2[] = {
275 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
278 static const struct bwn_bbatt bbatt_0[] = {
279 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
282 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
284 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
285 pg->pg_bbatt.att = 0;
287 pg->pg_bbatt.att = 2;
289 /* prepare Radio Attenuation */
290 pg->pg_rfatt.padmix = 0;
292 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
293 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
294 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
295 pg->pg_rfatt.att = 2;
297 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
298 pg->pg_rfatt.att = 3;
303 if (phy->type == BWN_PHYTYPE_A) {
304 pg->pg_rfatt.att = 0x60;
308 switch (phy->rf_ver) {
310 switch (phy->rf_rev) {
312 pg->pg_rfatt.att = 5;
315 if (phy->type == BWN_PHYTYPE_G) {
316 if (siba_get_pci_subvendor(sc->sc_dev) ==
317 SIBA_BOARDVENDOR_BCM &&
318 siba_get_pci_subdevice(sc->sc_dev) ==
319 SIBA_BOARD_BCM4309G &&
320 siba_get_pci_revid(sc->sc_dev) >= 30)
321 pg->pg_rfatt.att = 3;
322 else if (siba_get_pci_subvendor(sc->sc_dev) ==
323 SIBA_BOARDVENDOR_BCM &&
324 siba_get_pci_subdevice(sc->sc_dev) ==
326 pg->pg_rfatt.att = 3;
328 pg->pg_rfatt.att = 1;
330 if (siba_get_pci_subvendor(sc->sc_dev) ==
331 SIBA_BOARDVENDOR_BCM &&
332 siba_get_pci_subdevice(sc->sc_dev) ==
333 SIBA_BOARD_BCM4309G &&
334 siba_get_pci_revid(sc->sc_dev) >= 30)
335 pg->pg_rfatt.att = 7;
337 pg->pg_rfatt.att = 6;
341 if (phy->type == BWN_PHYTYPE_G) {
342 if (siba_get_pci_subvendor(sc->sc_dev) ==
343 SIBA_BOARDVENDOR_BCM &&
344 siba_get_pci_subdevice(sc->sc_dev) ==
345 SIBA_BOARD_BCM4309G &&
346 siba_get_pci_revid(sc->sc_dev) >= 30)
347 pg->pg_rfatt.att = 3;
348 else if (siba_get_pci_subvendor(sc->sc_dev) ==
349 SIBA_BOARDVENDOR_BCM &&
350 siba_get_pci_subdevice(sc->sc_dev) ==
352 pg->pg_rfatt.att = 5;
353 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
354 pg->pg_rfatt.att = 4;
356 pg->pg_rfatt.att = 3;
358 pg->pg_rfatt.att = 6;
361 pg->pg_rfatt.att = 5;
365 pg->pg_rfatt.att = 1;
369 pg->pg_rfatt.att = 5;
372 pg->pg_rfatt.att = 0xa;
373 pg->pg_rfatt.padmix = 1;
377 pg->pg_rfatt.att = 5;
382 switch (phy->rf_rev) {
384 pg->pg_rfatt.att = 6;
389 pg->pg_rfatt.att = 5;
391 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
393 if (!bwn_has_hwpctl(mac)) {
394 lo->rfatt.array = rfatt0;
395 lo->rfatt.len = N(rfatt0);
400 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
401 lo->rfatt.array = rfatt1;
402 lo->rfatt.len = N(rfatt1);
407 lo->rfatt.array = rfatt2;
408 lo->rfatt.len = N(rfatt2);
412 lo->bbatt.array = bbatt_0;
413 lo->bbatt.len = N(bbatt_0);
417 BWN_READ_4(mac, BWN_MACCTL);
420 bwn_reset_core(mac, 0);
421 bwn_phy_g_init_sub(mac);
423 bwn_reset_core(mac, 1);
429 bwn_phy_g_txctl(struct bwn_mac *mac)
431 struct bwn_phy *phy = &mac->mac_phy;
433 if (phy->rf_ver != 0x2050)
435 if (phy->rf_rev == 1)
436 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
438 return (BWN_TXCTL_PA2DB);
439 if (phy->rf_rev == 8)
440 return (BWN_TXCTL_TXMIX);
445 bwn_phy_g_init(struct bwn_mac *mac)
448 bwn_phy_g_init_sub(mac);
453 bwn_phy_g_exit(struct bwn_mac *mac)
455 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
456 struct bwn_lo_calib *cal, *tmp;
460 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
461 TAILQ_REMOVE(&lo->calib_list, cal, list);
467 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
470 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
471 return (BWN_READ_2(mac, BWN_PHYDATA));
475 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
478 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
479 BWN_WRITE_2(mac, BWN_PHYDATA, value);
483 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
486 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
487 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
488 return (BWN_READ_2(mac, BWN_RFDATALO));
492 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
495 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
496 BWN_WRITE_2(mac, BWN_RFCTL, reg);
497 BWN_WRITE_2(mac, BWN_RFDATALO, value);
501 bwn_phy_g_hwpctl(struct bwn_mac *mac)
504 return (mac->mac_phy.rev >= 6);
508 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
510 struct bwn_phy *phy = &mac->mac_phy;
511 struct bwn_phy_g *pg = &phy->phy_g;
512 unsigned int channel;
513 uint16_t rfover, rfoverval;
519 BWN_PHY_WRITE(mac, 0x15, 0x8000);
520 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
521 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
522 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
523 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
524 pg->pg_radioctx_over);
525 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
526 pg->pg_radioctx_overval);
527 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
530 bwn_phy_g_switch_chan(mac, 6, 1);
531 bwn_phy_g_switch_chan(mac, channel, 0);
535 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
536 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
537 pg->pg_radioctx_over = rfover;
538 pg->pg_radioctx_overval = rfoverval;
539 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
540 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
541 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
545 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
548 if ((newchan < 1) || (newchan > 14))
550 bwn_phy_g_switch_chan(mac, newchan, 0);
556 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
563 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
565 struct bwn_phy *phy = &mac->mac_phy;
570 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
573 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
574 bwn_hf_write(mac, hf);
576 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
577 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
578 ((autodiv ? BWN_ANTAUTO1 : antenna)
579 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
582 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
583 if (antenna == BWN_ANTAUTO1)
584 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
586 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
587 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
589 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
591 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
593 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
594 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
596 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
597 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
598 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
599 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
602 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
604 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
605 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
609 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
611 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
612 bwn_hf_write(mac, hf);
616 bwn_phy_g_im(struct bwn_mac *mac, int mode)
618 struct bwn_phy *phy = &mac->mac_phy;
619 struct bwn_phy_g *pg = &phy->phy_g;
621 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
622 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
624 if (phy->rev == 0 || !phy->gmode)
627 pg->pg_aci_wlan_automatic = 0;
632 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
634 struct bwn_phy *phy = &mac->mac_phy;
635 struct bwn_phy_g *pg = &phy->phy_g;
636 struct bwn_softc *sc = mac->mac_sc;
643 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
645 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
646 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
647 if (cck < 0 && ofdm < 0) {
648 if (ignore_tssi == 0)
649 return (BWN_TXPWR_RES_DONE);
653 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
654 if (pg->pg_avgtssi != 0xff)
655 tssi = (tssi + pg->pg_avgtssi) / 2;
656 pg->pg_avgtssi = tssi;
657 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
659 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
660 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
663 device_printf(sc->sc_dev, "invalid max TX-power value\n");
665 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
668 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
669 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
670 tssi, 0x00), 0x3f)]);
672 return (BWN_TXPWR_RES_DONE);
674 rfatt = -((power + 7) / 8);
675 bbatt = (-(power / 2)) - (4 * rfatt);
676 if ((rfatt == 0) && (bbatt == 0))
677 return (BWN_TXPWR_RES_DONE);
678 pg->pg_bbatt_delta = bbatt;
679 pg->pg_rfatt_delta = rfatt;
680 return (BWN_TXPWR_RES_NEED_ADJUST);
684 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
686 struct bwn_phy *phy = &mac->mac_phy;
687 struct bwn_phy_g *pg = &phy->phy_g;
688 struct bwn_softc *sc = mac->mac_sc;
692 bwn_mac_suspend(mac);
694 BWN_ASSERT_LOCKED(sc);
696 bbatt = pg->pg_bbatt.att;
697 bbatt += pg->pg_bbatt_delta;
698 rfatt = pg->pg_rfatt.att;
699 rfatt += pg->pg_rfatt_delta;
701 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
702 txctl = pg->pg_txctl;
703 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
706 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
709 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
711 bbatt += 4 * (rfatt - 2);
714 } else if (rfatt > 4 && txctl) {
725 pg->pg_txctl = txctl;
726 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
727 pg->pg_rfatt.att = rfatt;
728 pg->pg_bbatt.att = bbatt;
730 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
734 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
743 bwn_phy_g_task_15s(struct bwn_mac *mac)
745 struct bwn_phy *phy = &mac->mac_phy;
746 struct bwn_phy_g *pg = &phy->phy_g;
747 struct bwn_softc *sc = mac->mac_sc;
748 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
749 unsigned long expire, now;
750 struct bwn_lo_calib *cal, *tmp;
753 bwn_mac_suspend(mac);
759 if (bwn_has_hwpctl(mac)) {
760 expire = now - BWN_LO_PWRVEC_EXPIRE;
761 if (ieee80211_time_before(lo->pwr_vec_read_time, expire)) {
762 bwn_lo_get_powervector(mac);
763 bwn_phy_g_dc_lookup_init(mac, 0);
768 expire = now - BWN_LO_CALIB_EXPIRE;
769 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
770 if (!ieee80211_time_before(cal->calib_time, expire))
772 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
773 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
774 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
778 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
779 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
780 cal->ctl.i, cal->ctl.q);
782 TAILQ_REMOVE(&lo->calib_list, cal, list);
785 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
786 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
789 device_printf(sc->sc_dev,
790 "failed to recalibrate LO\n");
793 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
794 bwn_lo_write(mac, &cal->ctl);
802 bwn_phy_g_task_60s(struct bwn_mac *mac)
804 struct bwn_phy *phy = &mac->mac_phy;
805 struct bwn_softc *sc = mac->mac_sc;
806 uint8_t old = phy->chan;
808 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
811 bwn_mac_suspend(mac);
812 bwn_nrssi_slope_11g(mac);
813 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
814 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
815 bwn_switch_channel(mac, old);
821 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
824 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
828 bwn_phy_g_init_sub(struct bwn_mac *mac)
830 struct bwn_phy *phy = &mac->mac_phy;
831 struct bwn_phy_g *pg = &phy->phy_g;
832 struct bwn_softc *sc = mac->mac_sc;
836 bwn_phy_init_b5(mac);
838 bwn_phy_init_b6(mac);
840 if (phy->rev >= 2 || phy->gmode)
844 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
845 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
848 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
849 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
852 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
853 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
855 if (phy->gmode || phy->rev >= 2) {
856 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
857 tmp &= BWN_PHYVER_VERSION;
858 if (tmp == 3 || tmp == 5) {
859 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
860 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
863 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
867 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
868 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
869 if (phy->rf_rev == 8) {
870 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
871 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
873 if (BWN_HAS_LOOPBACK(phy))
874 bwn_loopback_calcgain(mac);
876 if (phy->rf_rev != 8) {
877 if (pg->pg_initval == 0xffff)
878 pg->pg_initval = bwn_rf_init_bcm2050(mac);
880 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
883 if (BWN_HAS_TXMAG(phy)) {
884 BWN_RF_WRITE(mac, 0x52,
885 (BWN_RF_READ(mac, 0x52) & 0xff00)
886 | pg->pg_loctl.tx_bias |
887 pg->pg_loctl.tx_magn);
889 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
892 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
893 (pg->pg_loctl.tx_bias << 12));
895 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
896 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
898 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
900 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
902 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
903 if (phy->gmode || phy->rev >= 2) {
904 bwn_lo_g_adjust(mac);
905 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
908 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
909 for (i = 0; i < 64; i++) {
910 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
911 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
912 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
915 bwn_nrssi_threshold(mac);
916 } else if (phy->gmode || phy->rev >= 2) {
917 if (pg->pg_nrssi[0] == -1000) {
918 KASSERT(pg->pg_nrssi[1] == -1000,
919 ("%s:%d: fail", __func__, __LINE__));
920 bwn_nrssi_slope_11g(mac);
922 bwn_nrssi_threshold(mac);
924 if (phy->rf_rev == 8)
925 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
926 bwn_phy_hwpctl_init(mac);
927 if ((siba_get_chipid(sc->sc_dev) == 0x4306
928 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
929 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
930 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
935 bwn_phy_init_b5(struct bwn_mac *mac)
937 struct bwn_phy *phy = &mac->mac_phy;
938 struct bwn_phy_g *pg = &phy->phy_g;
939 struct bwn_softc *sc = mac->mac_sc;
940 uint16_t offset, value;
943 if (phy->analog == 1)
944 BWN_RF_SET(mac, 0x007a, 0x0050);
945 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
946 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
948 for (offset = 0x00a8; offset < 0x00c7; offset++) {
949 BWN_PHY_WRITE(mac, offset, value);
953 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
954 if (phy->rf_ver == 0x2050)
955 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
957 if (phy->gmode || phy->rev >= 2) {
958 if (phy->rf_ver == 0x2050) {
959 BWN_RF_SET(mac, 0x007a, 0x0020);
960 BWN_RF_SET(mac, 0x0051, 0x0004);
962 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
964 BWN_PHY_SET(mac, 0x0802, 0x0100);
965 BWN_PHY_SET(mac, 0x042b, 0x2000);
967 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
969 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
970 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
971 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
974 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
975 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
977 if (phy->analog == 1) {
978 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
979 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
980 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
981 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
982 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
984 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
985 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
986 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
988 if (phy->analog == 1)
989 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
991 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
993 if (phy->analog == 0)
994 BWN_WRITE_2(mac, 0x03e4, 0x3000);
996 old_channel = phy->chan;
997 bwn_phy_g_switch_chan(mac, 7, 0);
999 if (phy->rf_ver != 0x2050) {
1000 BWN_RF_WRITE(mac, 0x0075, 0x0080);
1001 BWN_RF_WRITE(mac, 0x0079, 0x0081);
1004 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1005 BWN_RF_WRITE(mac, 0x0050, 0x0023);
1007 if (phy->rf_ver == 0x2050) {
1008 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1009 BWN_RF_WRITE(mac, 0x005a, 0x0070);
1012 BWN_RF_WRITE(mac, 0x005b, 0x007b);
1013 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
1014 BWN_RF_SET(mac, 0x007a, 0x0007);
1016 bwn_phy_g_switch_chan(mac, old_channel, 0);
1017 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
1018 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
1019 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
1021 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
1024 if (phy->rf_ver == 0x2050)
1025 BWN_RF_WRITE(mac, 0x005d, 0x000d);
1027 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
1031 bwn_loopback_calcgain(struct bwn_mac *mac)
1033 struct bwn_phy *phy = &mac->mac_phy;
1034 struct bwn_phy_g *pg = &phy->phy_g;
1035 struct bwn_softc *sc = mac->mac_sc;
1036 uint16_t backup_phy[16] = { 0 };
1037 uint16_t backup_radio[3];
1038 uint16_t backup_bband;
1039 uint16_t i, j, loop_i_max;
1041 uint16_t loop1_outer_done, loop1_inner_done;
1043 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
1044 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
1045 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
1046 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
1047 if (phy->rev != 1) {
1048 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
1049 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
1051 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
1052 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
1053 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
1054 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
1055 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
1056 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
1057 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
1058 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
1059 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
1060 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1061 backup_bband = pg->pg_bbatt.att;
1062 backup_radio[0] = BWN_RF_READ(mac, 0x52);
1063 backup_radio[1] = BWN_RF_READ(mac, 0x43);
1064 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
1066 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
1067 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
1068 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
1069 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
1070 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
1071 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
1072 if (phy->rev != 1) {
1073 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
1074 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
1075 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
1076 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
1078 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
1079 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
1080 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
1081 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
1083 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
1084 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1085 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1087 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
1088 if (phy->rev != 1) {
1089 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
1090 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
1092 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
1094 if (phy->rf_rev == 8)
1095 BWN_RF_WRITE(mac, 0x43, 0x000f);
1097 BWN_RF_WRITE(mac, 0x52, 0);
1098 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
1100 bwn_phy_g_set_bbatt(mac, 11);
1103 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
1105 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
1106 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
1108 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
1109 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
1111 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
1112 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
1114 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
1115 if (phy->rev >= 7) {
1116 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
1117 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
1120 BWN_RF_MASK(mac, 0x7a, 0x00f7);
1123 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
1124 for (i = 0; i < loop_i_max; i++) {
1125 for (j = 0; j < 16; j++) {
1126 BWN_RF_WRITE(mac, 0x43, i);
1127 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
1129 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
1130 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
1132 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
1137 loop1_outer_done = i;
1138 loop1_inner_done = j;
1140 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
1142 for (j = j - 8; j < 16; j++) {
1143 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
1144 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
1145 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
1148 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
1155 if (phy->rev != 1) {
1156 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
1157 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
1159 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
1160 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
1161 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
1162 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
1163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
1164 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
1165 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
1166 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
1167 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
1169 bwn_phy_g_set_bbatt(mac, backup_bband);
1171 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
1172 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
1173 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
1175 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
1177 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
1178 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
1179 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
1180 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
1182 pg->pg_max_lb_gain =
1183 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
1184 pg->pg_trsw_rx_gain = trsw_rx * 2;
1188 bwn_rf_init_bcm2050(struct bwn_mac *mac)
1190 struct bwn_phy *phy = &mac->mac_phy;
1191 uint32_t tmp1 = 0, tmp2 = 0;
1192 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
1193 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
1194 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
1195 static const uint8_t rcc_table[] = {
1196 0x02, 0x03, 0x01, 0x0f,
1197 0x06, 0x07, 0x05, 0x0f,
1198 0x0a, 0x0b, 0x09, 0x0f,
1199 0x0e, 0x0f, 0x0d, 0x0f,
1202 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
1203 rfoverval = rfover = cck3 = 0;
1204 radio0 = BWN_RF_READ(mac, 0x43);
1205 radio1 = BWN_RF_READ(mac, 0x51);
1206 radio2 = BWN_RF_READ(mac, 0x52);
1207 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
1208 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
1209 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
1210 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
1212 if (phy->type == BWN_PHYTYPE_B) {
1213 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
1214 reg0 = BWN_READ_2(mac, 0x3ec);
1216 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
1217 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
1218 } else if (phy->gmode || phy->rev >= 2) {
1219 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
1220 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
1221 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
1222 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
1223 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
1224 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
1226 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
1227 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
1228 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
1229 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
1230 if (BWN_HAS_LOOPBACK(phy)) {
1231 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
1232 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
1234 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
1236 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
1237 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
1240 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1241 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1243 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
1244 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
1246 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
1248 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
1249 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
1250 reg1 = BWN_READ_2(mac, 0x3e6);
1251 reg2 = BWN_READ_2(mac, 0x3f4);
1253 if (phy->analog == 0)
1254 BWN_WRITE_2(mac, 0x03e6, 0x0122);
1256 if (phy->analog >= 2)
1257 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
1258 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
1259 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
1262 reg = BWN_RF_READ(mac, 0x60);
1263 index = (reg & 0x001e) >> 1;
1264 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
1266 if (phy->type == BWN_PHYTYPE_B)
1267 BWN_RF_WRITE(mac, 0x78, 0x26);
1268 if (phy->gmode || phy->rev >= 2) {
1269 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1270 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1273 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
1274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
1275 if (phy->gmode || phy->rev >= 2) {
1276 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1277 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
1280 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
1281 BWN_RF_SET(mac, 0x51, 0x0004);
1282 if (phy->rf_rev == 8)
1283 BWN_RF_WRITE(mac, 0x43, 0x1f);
1285 BWN_RF_WRITE(mac, 0x52, 0);
1286 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
1288 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1290 for (i = 0; i < 16; i++) {
1291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
1292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1294 if (phy->gmode || phy->rev >= 2) {
1295 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1296 bwn_rf_2050_rfoverval(mac,
1297 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1299 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1301 if (phy->gmode || phy->rev >= 2) {
1302 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1303 bwn_rf_2050_rfoverval(mac,
1304 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1306 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
1308 if (phy->gmode || phy->rev >= 2) {
1309 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1310 bwn_rf_2050_rfoverval(mac,
1311 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
1313 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
1315 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1317 if (phy->gmode || phy->rev >= 2) {
1318 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1319 bwn_rf_2050_rfoverval(mac,
1320 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1322 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1326 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1330 for (i = 0; i < 16; i++) {
1331 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
1332 BWN_RF_WRITE(mac, 0x78, radio78);
1334 for (j = 0; j < 16; j++) {
1335 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
1336 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
1337 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
1338 if (phy->gmode || phy->rev >= 2) {
1339 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1340 bwn_rf_2050_rfoverval(mac,
1341 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1343 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1345 if (phy->gmode || phy->rev >= 2) {
1346 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1347 bwn_rf_2050_rfoverval(mac,
1348 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1350 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
1352 if (phy->gmode || phy->rev >= 2) {
1353 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1354 bwn_rf_2050_rfoverval(mac,
1355 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
1357 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
1359 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1360 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
1361 if (phy->gmode || phy->rev >= 2) {
1362 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
1363 bwn_rf_2050_rfoverval(mac,
1364 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
1366 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
1374 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
1375 BWN_RF_WRITE(mac, 0x51, radio1);
1376 BWN_RF_WRITE(mac, 0x52, radio2);
1377 BWN_RF_WRITE(mac, 0x43, radio0);
1378 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
1379 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
1380 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
1381 BWN_WRITE_2(mac, 0x3e6, reg1);
1382 if (phy->analog != 0)
1383 BWN_WRITE_2(mac, 0x3f4, reg2);
1384 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
1385 bwn_spu_workaround(mac, phy->chan);
1386 if (phy->type == BWN_PHYTYPE_B) {
1387 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
1388 BWN_WRITE_2(mac, 0x3ec, reg0);
1389 } else if (phy->gmode) {
1390 BWN_WRITE_2(mac, BWN_PHY_RADIO,
1391 BWN_READ_2(mac, BWN_PHY_RADIO)
1393 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
1394 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
1395 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
1396 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
1398 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
1399 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
1400 if (BWN_HAS_LOOPBACK(phy)) {
1401 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
1402 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
1406 return ((i > 15) ? radio78 : rcc);
1410 bwn_phy_init_b6(struct bwn_mac *mac)
1412 struct bwn_phy *phy = &mac->mac_phy;
1413 struct bwn_phy_g *pg = &phy->phy_g;
1414 struct bwn_softc *sc = mac->mac_sc;
1415 uint16_t offset, val;
1416 uint8_t old_channel;
1418 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
1419 ("%s:%d: fail", __func__, __LINE__));
1421 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
1422 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
1423 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
1424 BWN_RF_WRITE(mac, 0x51, 0x37);
1425 BWN_RF_WRITE(mac, 0x52, 0x70);
1426 BWN_RF_WRITE(mac, 0x53, 0xb3);
1427 BWN_RF_WRITE(mac, 0x54, 0x9b);
1428 BWN_RF_WRITE(mac, 0x5a, 0x88);
1429 BWN_RF_WRITE(mac, 0x5b, 0x88);
1430 BWN_RF_WRITE(mac, 0x5d, 0x88);
1431 BWN_RF_WRITE(mac, 0x5e, 0x88);
1432 BWN_RF_WRITE(mac, 0x7d, 0x88);
1434 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
1436 if (phy->rf_rev == 8) {
1437 BWN_RF_WRITE(mac, 0x51, 0);
1438 BWN_RF_WRITE(mac, 0x52, 0x40);
1439 BWN_RF_WRITE(mac, 0x53, 0xb7);
1440 BWN_RF_WRITE(mac, 0x54, 0x98);
1441 BWN_RF_WRITE(mac, 0x5a, 0x88);
1442 BWN_RF_WRITE(mac, 0x5b, 0x6b);
1443 BWN_RF_WRITE(mac, 0x5c, 0x0f);
1444 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
1445 BWN_RF_WRITE(mac, 0x5d, 0xfa);
1446 BWN_RF_WRITE(mac, 0x5e, 0xd8);
1448 BWN_RF_WRITE(mac, 0x5d, 0xf5);
1449 BWN_RF_WRITE(mac, 0x5e, 0xb8);
1451 BWN_RF_WRITE(mac, 0x0073, 0x0003);
1452 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
1453 BWN_RF_WRITE(mac, 0x007c, 0x0001);
1454 BWN_RF_WRITE(mac, 0x007e, 0x0008);
1456 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
1457 BWN_PHY_WRITE(mac, offset, val);
1460 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
1461 BWN_PHY_WRITE(mac, offset, val);
1464 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
1465 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
1468 if (phy->type == BWN_PHYTYPE_G) {
1469 BWN_RF_SET(mac, 0x007a, 0x0020);
1470 BWN_RF_SET(mac, 0x0051, 0x0004);
1471 BWN_PHY_SET(mac, 0x0802, 0x0100);
1472 BWN_PHY_SET(mac, 0x042b, 0x2000);
1473 BWN_PHY_WRITE(mac, 0x5b, 0);
1474 BWN_PHY_WRITE(mac, 0x5c, 0);
1477 old_channel = phy->chan;
1478 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
1480 BWN_RF_WRITE(mac, 0x0050, 0x0020);
1481 BWN_RF_WRITE(mac, 0x0050, 0x0023);
1483 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
1484 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
1485 BWN_RF_WRITE(mac, 0x50, 0x20);
1487 if (phy->rf_rev <= 2) {
1488 BWN_RF_WRITE(mac, 0x7c, 0x20);
1489 BWN_RF_WRITE(mac, 0x5a, 0x70);
1490 BWN_RF_WRITE(mac, 0x5b, 0x7b);
1491 BWN_RF_WRITE(mac, 0x5c, 0xb0);
1493 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
1495 bwn_phy_g_switch_chan(mac, old_channel, 0);
1497 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
1498 if (phy->rf_rev >= 6)
1499 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
1501 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
1502 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
1503 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
1505 if (phy->rf_rev <= 5)
1506 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
1507 if (phy->rf_rev <= 2)
1508 BWN_RF_WRITE(mac, 0x005d, 0x000d);
1510 if (phy->analog == 4) {
1511 BWN_WRITE_2(mac, 0x3e4, 9);
1512 BWN_PHY_MASK(mac, 0x61, 0x0fff);
1514 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
1515 if (phy->type == BWN_PHYTYPE_B)
1516 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1517 else if (phy->type == BWN_PHYTYPE_G)
1518 BWN_WRITE_2(mac, 0x03e6, 0x0);
1522 bwn_phy_init_a(struct bwn_mac *mac)
1524 struct bwn_phy *phy = &mac->mac_phy;
1525 struct bwn_softc *sc = mac->mac_sc;
1527 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
1528 ("%s:%d: fail", __func__, __LINE__));
1530 if (phy->rev >= 6) {
1531 if (phy->type == BWN_PHYTYPE_A)
1532 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
1533 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
1534 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
1536 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
1541 if (phy->type == BWN_PHYTYPE_G &&
1542 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
1543 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
1547 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
1551 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
1552 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
1556 bwn_wa_agc(struct bwn_mac *mac)
1558 struct bwn_phy *phy = &mac->mac_phy;
1560 if (phy->rev == 1) {
1561 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
1562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
1563 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
1564 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
1565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
1566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
1567 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
1568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
1569 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
1571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
1572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
1573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
1574 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
1577 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
1579 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
1580 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
1581 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
1582 BWN_RF_SET(mac, 0x7a, 0x0008);
1583 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
1584 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
1585 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
1586 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
1588 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
1589 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
1590 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
1591 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
1592 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
1593 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
1594 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
1595 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
1596 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
1597 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
1598 if (phy->rev == 1) {
1599 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
1600 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
1602 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
1603 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
1604 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
1605 if (phy->rev >= 6) {
1606 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
1607 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
1608 (uint16_t)~0xf000, 0x3000);
1611 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
1612 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
1613 if (phy->rev == 1) {
1614 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
1615 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
1616 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
1617 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
1618 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
1619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
1620 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
1621 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
1623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
1624 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
1625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
1626 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
1628 if (phy->rev >= 6) {
1629 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
1630 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
1632 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
1636 bwn_wa_grev1(struct bwn_mac *mac)
1638 struct bwn_phy *phy = &mac->mac_phy;
1640 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
1641 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
1642 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
1644 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1646 /* init CRSTHRES and ANTDWELL */
1647 if (phy->rev == 1) {
1648 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
1649 } else if (phy->rev == 2) {
1650 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
1651 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
1652 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1654 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
1655 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
1656 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
1657 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1659 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
1660 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
1661 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
1663 /* XXX support PHY-A??? */
1664 for (i = 0; i < N(bwn_tab_finefreqg); i++)
1665 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
1666 bwn_tab_finefreqg[i]);
1668 /* XXX support PHY-A??? */
1670 for (i = 0; i < N(bwn_tab_noise_g1); i++)
1671 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1672 bwn_tab_noise_g1[i]);
1674 for (i = 0; i < N(bwn_tab_noise_g2); i++)
1675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1676 bwn_tab_noise_g2[i]);
1679 for (i = 0; i < N(bwn_tab_rotor); i++)
1680 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
1683 /* XXX support PHY-A??? */
1684 if (phy->rev >= 6) {
1685 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
1687 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
1689 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
1691 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
1693 for (i = 0; i < N(bwn_tab_retard); i++)
1694 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
1697 if (phy->rev == 1) {
1698 for (i = 0; i < 16; i++)
1699 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
1702 for (i = 0; i < 32; i++)
1703 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
1710 bwn_wa_grev26789(struct bwn_mac *mac)
1712 struct bwn_phy *phy = &mac->mac_phy;
1714 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
1717 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1719 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
1721 /* init CRSTHRES and ANTDWELL */
1723 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
1724 else if (phy->rev == 2) {
1725 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
1726 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
1727 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1729 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
1730 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
1731 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
1732 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
1735 for (i = 0; i < 64; i++)
1736 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
1738 /* XXX support PHY-A??? */
1740 for (i = 0; i < N(bwn_tab_noise_g1); i++)
1741 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1742 bwn_tab_noise_g1[i]);
1744 for (i = 0; i < N(bwn_tab_noise_g2); i++)
1745 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
1746 bwn_tab_noise_g2[i]);
1748 /* XXX support PHY-A??? */
1749 if (phy->rev >= 6) {
1750 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
1752 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
1754 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
1756 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
1758 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
1759 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
1760 bwn_tab_sigmasqr2[i]);
1762 if (phy->rev == 1) {
1763 for (i = 0; i < 16; i++)
1764 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
1767 for (i = 0; i < 32; i++)
1768 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
1773 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
1775 if (phy->type == BWN_PHYTYPE_A)
1776 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
1778 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
1780 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
1781 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
1782 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
1785 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
1786 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
1790 bwn_wa_init(struct bwn_mac *mac)
1792 struct bwn_phy *phy = &mac->mac_phy;
1793 struct bwn_softc *sc = mac->mac_sc;
1795 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1806 bwn_wa_grev26789(mac);
1809 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1812 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
1813 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
1814 siba_get_pci_revid(sc->sc_dev) != 0x17) {
1816 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
1818 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
1821 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
1822 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
1823 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
1826 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
1827 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1829 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1831 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1833 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1835 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1837 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
1842 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
1843 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
1844 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
1847 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
1848 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
1852 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1855 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
1858 addr = table + offset;
1859 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
1860 (addr - 1 != pg->pg_ofdmtab_addr)) {
1861 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
1862 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
1864 pg->pg_ofdmtab_addr = addr;
1865 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
1869 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1872 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
1875 addr = table + offset;
1876 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
1877 (addr - 1 != pg->pg_ofdmtab_addr)) {
1878 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
1879 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
1881 pg->pg_ofdmtab_addr = addr;
1883 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
1884 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
1888 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
1892 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
1893 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
1897 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
1901 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
1902 ("%s:%d: fail", __func__, __LINE__));
1904 value = (uint8_t) (ctl->q);
1905 value |= ((uint8_t) (ctl->i)) << 8;
1906 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
1910 bwn_lo_calcfeed(struct bwn_mac *mac,
1911 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
1913 struct bwn_phy *phy = &mac->mac_phy;
1914 struct bwn_softc *sc = mac->mac_sc;
1916 uint16_t feedthrough;
1919 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
1920 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
1922 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
1923 ("%s:%d: fail", __func__, __LINE__));
1924 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
1925 ("%s:%d: fail", __func__, __LINE__));
1927 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
1929 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
1930 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
1932 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
1934 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
1935 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1937 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
1938 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1940 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
1941 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
1943 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
1945 pga |= BWN_PHY_PGACTL_UNKNOWN;
1946 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1948 pga |= BWN_PHY_PGACTL_LOWBANDW;
1949 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1951 pga |= BWN_PHY_PGACTL_LPF;
1952 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
1955 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
1957 return (feedthrough);
1961 bwn_lo_txctl_regtable(struct bwn_mac *mac,
1962 uint16_t *value, uint16_t *pad_mix_gain)
1964 struct bwn_phy *phy = &mac->mac_phy;
1965 uint16_t reg, v, padmix;
1967 if (phy->type == BWN_PHYTYPE_B) {
1969 if (phy->rf_rev <= 5) {
1977 if (phy->rev >= 2 && phy->rf_rev == 8) {
1990 *pad_mix_gain = padmix;
1996 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
1998 struct bwn_phy *phy = &mac->mac_phy;
1999 struct bwn_phy_g *pg = &phy->phy_g;
2000 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2002 uint16_t trsw_rx, pga;
2003 uint16_t rf_pctl_reg;
2005 static const uint8_t tx_bias_values[] = {
2006 0x09, 0x08, 0x0a, 0x01, 0x00,
2007 0x02, 0x05, 0x04, 0x06,
2009 static const uint8_t tx_magn_values[] = {
2013 if (!BWN_HAS_LOOPBACK(phy)) {
2021 lb_gain = pg->pg_max_lb_gain / 2;
2024 pga = abs(10 - lb_gain) / 6;
2025 pga = MIN(MAX(pga, 0), 15);
2032 if ((phy->rev >= 2) &&
2033 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
2036 if ((10 - lb_gain) < cmp_val)
2037 tmp = (10 - lb_gain);
2045 rf_pctl_reg = cmp_val;
2050 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
2051 bwn_phy_g_set_bbatt(mac, 2);
2053 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
2055 BWN_RF_MASK(mac, reg, mask);
2057 if (BWN_HAS_TXMAG(phy)) {
2060 int min_feedth = 0xffff;
2061 uint8_t tx_magn, tx_bias;
2063 for (i = 0; i < N(tx_magn_values); i++) {
2064 tx_magn = tx_magn_values[i];
2065 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
2066 for (j = 0; j < N(tx_bias_values); j++) {
2067 tx_bias = tx_bias_values[j];
2068 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
2069 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
2071 if (feedthrough < min_feedth) {
2072 lo->tx_bias = tx_bias;
2073 lo->tx_magn = tx_magn;
2074 min_feedth = feedthrough;
2076 if (lo->tx_bias == 0)
2079 BWN_RF_WRITE(mac, 0x52,
2080 (BWN_RF_READ(mac, 0x52)
2081 & 0xff00) | lo->tx_bias | lo->
2087 BWN_RF_MASK(mac, 0x52, 0xfff0);
2090 BWN_GETTIME(lo->txctl_measured_time);
2094 bwn_lo_get_powervector(struct bwn_mac *mac)
2096 struct bwn_phy *phy = &mac->mac_phy;
2097 struct bwn_phy_g *pg = &phy->phy_g;
2098 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2101 uint64_t power_vector = 0;
2103 for (i = 0; i < 8; i += 2) {
2104 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
2105 power_vector |= (tmp << (i * 8));
2106 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
2109 lo->power_vector = power_vector;
2111 BWN_GETTIME(lo->pwr_vec_read_time);
2115 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
2118 struct bwn_phy *phy = &mac->mac_phy;
2119 struct bwn_phy_g *pg = &phy->phy_g;
2122 if (max_rx_gain < 0)
2125 if (BWN_HAS_LOOPBACK(phy)) {
2130 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
2131 if (max_rx_gain >= trsw_rx_gain) {
2132 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
2136 trsw_rx_gain = max_rx_gain;
2137 if (trsw_rx_gain < 9) {
2138 pg->pg_lna_lod_gain = 0;
2140 pg->pg_lna_lod_gain = 1;
2143 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
2144 pg->pg_pga_gain = trsw_rx_gain / 3;
2145 if (pg->pg_pga_gain >= 5) {
2146 pg->pg_pga_gain -= 5;
2147 pg->pg_lna_gain = 2;
2149 pg->pg_lna_gain = 0;
2151 pg->pg_lna_gain = 0;
2152 pg->pg_trsw_rx_gain = 0x20;
2153 if (max_rx_gain >= 0x14) {
2154 pg->pg_lna_lod_gain = 1;
2155 pg->pg_pga_gain = 2;
2156 } else if (max_rx_gain >= 0x12) {
2157 pg->pg_lna_lod_gain = 1;
2158 pg->pg_pga_gain = 1;
2159 } else if (max_rx_gain >= 0xf) {
2160 pg->pg_lna_lod_gain = 1;
2161 pg->pg_pga_gain = 0;
2163 pg->pg_lna_lod_gain = 0;
2164 pg->pg_pga_gain = 0;
2168 tmp = BWN_RF_READ(mac, 0x7a);
2169 if (pg->pg_lna_lod_gain == 0)
2173 BWN_RF_WRITE(mac, 0x7a, tmp);
2177 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
2179 struct bwn_phy *phy = &mac->mac_phy;
2180 struct bwn_phy_g *pg = &phy->phy_g;
2181 struct bwn_softc *sc = mac->mac_sc;
2182 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2186 if (bwn_has_hwpctl(mac)) {
2187 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
2188 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
2189 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
2190 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
2191 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
2193 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
2194 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
2195 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
2196 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
2198 if (phy->type == BWN_PHYTYPE_B &&
2199 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
2200 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
2201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
2203 if (phy->rev >= 2) {
2204 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
2205 sav->phy_analogoverval =
2206 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
2207 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2208 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2209 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
2210 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
2211 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
2213 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
2214 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
2215 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
2216 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
2217 if (phy->type == BWN_PHYTYPE_G) {
2218 if ((phy->rev >= 7) &&
2219 (siba_sprom_get_bf_lo(sc->sc_dev) &
2221 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
2223 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
2226 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
2228 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
2230 sav->reg0 = BWN_READ_2(mac, 0x3f4);
2231 sav->reg1 = BWN_READ_2(mac, 0x3e2);
2232 sav->rf0 = BWN_RF_READ(mac, 0x43);
2233 sav->rf1 = BWN_RF_READ(mac, 0x7a);
2234 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
2235 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
2236 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
2237 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
2239 if (!BWN_HAS_TXMAG(phy)) {
2240 sav->rf2 = BWN_RF_READ(mac, 0x52);
2243 if (phy->type == BWN_PHYTYPE_B) {
2244 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
2245 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
2246 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
2247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
2249 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
2252 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
2256 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
2257 BWN_PHY_WRITE(mac, tmp, 0x007f);
2259 tmp = sav->phy_syncctl;
2260 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
2262 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
2264 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
2265 if (phy->type == BWN_PHYTYPE_G ||
2266 (phy->type == BWN_PHYTYPE_B &&
2267 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
2268 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
2270 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
2272 bwn_dummy_transmission(mac, 0, 1);
2273 bwn_phy_g_switch_chan(mac, 6, 0);
2274 BWN_RF_READ(mac, 0x51);
2275 if (phy->type == BWN_PHYTYPE_G)
2276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
2279 if (ieee80211_time_before(lo->txctl_measured_time,
2280 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
2281 bwn_lo_measure_txctl_values(mac);
2283 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
2284 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
2286 if (phy->type == BWN_PHYTYPE_B)
2287 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
2289 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
2294 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
2296 struct bwn_phy *phy = &mac->mac_phy;
2297 struct bwn_phy_g *pg = &phy->phy_g;
2300 if (phy->rev >= 2) {
2301 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
2302 tmp = (pg->pg_pga_gain << 8);
2303 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
2305 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
2307 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
2309 tmp = (pg->pg_pga_gain | 0xefa0);
2310 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
2312 if (phy->type == BWN_PHYTYPE_G) {
2314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
2316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
2318 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
2320 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
2322 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
2323 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
2324 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
2325 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
2326 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
2327 BWN_RF_WRITE(mac, 0x43, sav->rf0);
2328 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
2329 if (!BWN_HAS_TXMAG(phy)) {
2331 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
2333 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
2334 if (phy->type == BWN_PHYTYPE_B &&
2335 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
2336 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
2337 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
2339 if (phy->rev >= 2) {
2340 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
2341 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
2342 sav->phy_analogoverval);
2343 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
2344 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
2345 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
2346 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
2347 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
2349 if (bwn_has_hwpctl(mac)) {
2350 tmp = (sav->phy_lomask & 0xbfff);
2351 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
2352 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
2353 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
2354 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
2355 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
2357 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
2361 bwn_lo_probe_loctl(struct bwn_mac *mac,
2362 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
2364 struct bwn_phy *phy = &mac->mac_phy;
2365 struct bwn_phy_g *pg = &phy->phy_g;
2366 struct bwn_loctl orig, test;
2367 struct bwn_loctl prev = { -100, -100 };
2368 static const struct bwn_loctl modifiers[] = {
2369 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
2370 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
2372 int begin, end, lower = 0, i;
2375 if (d->curstate == 0) {
2378 } else if (d->curstate % 2 == 0) {
2379 begin = d->curstate - 1;
2380 end = d->curstate + 1;
2382 begin = d->curstate - 2;
2383 end = d->curstate + 2;
2390 memcpy(&orig, probe, sizeof(struct bwn_loctl));
2394 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
2395 memcpy(&test, &orig, sizeof(struct bwn_loctl));
2396 test.i += modifiers[i - 1].i * d->multipler;
2397 test.q += modifiers[i - 1].q * d->multipler;
2398 if ((test.i != prev.i || test.q != prev.q) &&
2399 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
2400 bwn_lo_write(mac, &test);
2401 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2402 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2403 if (feedth < d->feedth) {
2404 memcpy(probe, &test,
2405 sizeof(struct bwn_loctl));
2408 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
2412 memcpy(&prev, &test, sizeof(prev));
2426 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
2428 struct bwn_phy *phy = &mac->mac_phy;
2429 struct bwn_phy_g *pg = &phy->phy_g;
2430 struct bwn_lo_g_sm d;
2431 struct bwn_loctl probe;
2432 int lower, repeat, cnt = 0;
2437 if (BWN_HAS_LOOPBACK(phy))
2440 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
2441 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
2444 bwn_lo_write(mac, &d.loctl);
2445 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2446 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2447 if (feedth < 0x258) {
2448 if (feedth >= 0x12c)
2452 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
2453 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
2458 KASSERT(d.curstate >= 0 && d.curstate <= 8,
2459 ("%s:%d: fail", __func__, __LINE__));
2460 memcpy(&probe, &d.loctl,
2461 sizeof(struct bwn_loctl));
2462 lower = bwn_lo_probe_loctl(mac, &probe, &d);
2465 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
2467 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
2469 } while (d.nmeasure < 24);
2470 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
2472 if (BWN_HAS_LOOPBACK(phy)) {
2473 if (d.feedth > 0x1194)
2475 else if (d.feedth < 0x5dc)
2478 if (d.feedth <= 0x5dc) {
2483 } else if (cnt == 2)
2486 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
2487 } while (++cnt < repeat);
2490 static struct bwn_lo_calib *
2491 bwn_lo_calibset(struct bwn_mac *mac,
2492 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
2494 struct bwn_phy *phy = &mac->mac_phy;
2495 struct bwn_phy_g *pg = &phy->phy_g;
2496 struct bwn_loctl loctl = { 0, 0 };
2497 struct bwn_lo_calib *cal;
2498 struct bwn_lo_g_value sval = { 0 };
2500 uint16_t pad, reg, value;
2502 sval.old_channel = phy->chan;
2503 bwn_mac_suspend(mac);
2504 bwn_lo_save(mac, &sval);
2506 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
2507 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
2508 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
2510 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
2513 if (BWN_HAS_LOOPBACK(phy))
2514 rxgain += pg->pg_max_lb_gain;
2515 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
2516 bwn_phy_g_set_bbatt(mac, bbatt->att);
2517 bwn_lo_probe_sm(mac, &loctl, &rxgain);
2519 bwn_lo_restore(mac, &sval);
2520 bwn_mac_enable(mac);
2522 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
2524 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
2527 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
2528 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
2529 memcpy(&cal->ctl, &loctl, sizeof(loctl));
2531 BWN_GETTIME(cal->calib_time);
2536 static struct bwn_lo_calib *
2537 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
2538 const struct bwn_rfatt *rfatt)
2540 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2541 struct bwn_lo_calib *c;
2543 TAILQ_FOREACH(c, &lo->calib_list, list) {
2544 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
2546 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
2551 c = bwn_lo_calibset(mac, bbatt, rfatt);
2554 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
2560 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
2562 struct bwn_phy *phy = &mac->mac_phy;
2563 struct bwn_phy_g *pg = &phy->phy_g;
2564 struct bwn_softc *sc = mac->mac_sc;
2565 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2566 const struct bwn_rfatt *rfatt;
2567 const struct bwn_bbatt *bbatt;
2570 int rf_offset, bb_offset;
2571 uint8_t changed = 0;
2573 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
2574 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
2575 ("%s:%d: fail", __func__, __LINE__));
2577 pvector = lo->power_vector;
2578 if (!update && !pvector)
2581 bwn_mac_suspend(mac);
2583 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
2584 struct bwn_lo_calib *cal;
2588 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
2590 bb_offset = i / lo->rfatt.len;
2591 rf_offset = i % lo->rfatt.len;
2592 bbatt = &(lo->bbatt.array[bb_offset]);
2593 rfatt = &(lo->rfatt.array[rf_offset]);
2595 cal = bwn_lo_calibset(mac, bbatt, rfatt);
2597 device_printf(sc->sc_dev, "LO: Could not "
2598 "calibrate DC table entry\n");
2601 val = (uint8_t)(cal->ctl.q);
2602 val |= ((uint8_t)(cal->ctl.i)) << 4;
2603 free(cal, M_DEVBUF);
2607 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
2608 | ((val & 0x00ff) << 8);
2610 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
2615 for (i = 0; i < BWN_DC_LT_SIZE; i++)
2616 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
2618 bwn_mac_enable(mac);
2622 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
2627 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
2632 bwn_lo_g_adjust(struct bwn_mac *mac)
2634 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2635 struct bwn_lo_calib *cal;
2636 struct bwn_rfatt rf;
2638 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
2639 bwn_lo_fixup_rfatt(&rf);
2641 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
2644 bwn_lo_write(mac, &cal->ctl);
2648 bwn_lo_g_init(struct bwn_mac *mac)
2651 if (!bwn_has_hwpctl(mac))
2654 bwn_lo_get_powervector(mac);
2655 bwn_phy_g_dc_lookup_init(mac, 1);
2659 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
2662 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
2663 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
2667 bwn_nrssi_threshold(struct bwn_mac *mac)
2669 struct bwn_phy *phy = &mac->mac_phy;
2670 struct bwn_phy_g *pg = &phy->phy_g;
2671 struct bwn_softc *sc = mac->mac_sc;
2676 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2678 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
2679 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
2687 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
2688 a += (pg->pg_nrssi[0] << 6);
2689 a += (a < 32) ? 31 : 32;
2691 a = MIN(MAX(a, -31), 31);
2693 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
2694 b += (pg->pg_nrssi[0] << 6);
2700 b = MIN(MAX(b, -31), 31);
2702 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
2703 tmpu16 |= ((uint32_t)b & 0x0000003f);
2704 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
2705 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
2709 tmp16 = bwn_nrssi_read(mac, 0x20);
2712 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
2716 bwn_nrssi_slope_11g(struct bwn_mac *mac)
2718 #define SAVE_RF_MAX 3
2719 #define SAVE_PHY_COMM_MAX 4
2720 #define SAVE_PHY3_MAX 8
2721 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
2722 { 0x7a, 0x52, 0x43 };
2723 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
2724 { 0x15, 0x5a, 0x59, 0x58 };
2725 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
2726 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
2727 0x0801, 0x0060, 0x0014, 0x0478
2729 struct bwn_phy *phy = &mac->mac_phy;
2730 struct bwn_phy_g *pg = &phy->phy_g;
2731 int32_t i, tmp32, phy3_idx = 0;
2732 uint16_t delta, tmp;
2733 uint16_t save_rf[SAVE_RF_MAX];
2734 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
2735 uint16_t save_phy3[SAVE_PHY3_MAX];
2736 uint16_t ant_div, phy0, chan_ex;
2737 int16_t nrssi0, nrssi1;
2739 KASSERT(phy->type == BWN_PHYTYPE_G,
2740 ("%s:%d: fail", __func__, __LINE__));
2742 if (phy->rf_rev >= 9)
2744 if (phy->rf_rev == 8)
2745 bwn_nrssi_offset(mac);
2747 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
2748 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
2751 * Save RF/PHY registers for later restoration
2753 ant_div = BWN_READ_2(mac, 0x03e2);
2754 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
2755 for (i = 0; i < SAVE_RF_MAX; ++i)
2756 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
2757 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2758 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
2760 phy0 = BWN_READ_2(mac, BWN_PHY0);
2761 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
2762 if (phy->rev >= 3) {
2763 for (i = 0; i < SAVE_PHY3_MAX; ++i)
2764 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
2765 BWN_PHY_WRITE(mac, 0x002e, 0);
2766 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
2771 BWN_PHY_SET(mac, 0x0478, 0x0100);
2772 BWN_PHY_SET(mac, 0x0801, 0x0040);
2776 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
2779 BWN_PHY_SET(mac, 0x0060, 0x0040);
2780 BWN_PHY_SET(mac, 0x0014, 0x0200);
2785 BWN_RF_SET(mac, 0x007a, 0x0070);
2786 bwn_set_all_gains(mac, 0, 8, 0);
2787 BWN_RF_MASK(mac, 0x007a, 0x00f7);
2788 if (phy->rev >= 2) {
2789 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
2790 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
2792 BWN_RF_SET(mac, 0x007a, 0x0080);
2795 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2796 if (nrssi0 >= 0x0020)
2802 BWN_RF_MASK(mac, 0x007a, 0x007f);
2804 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
2806 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
2807 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
2808 BWN_RF_SET(mac, 0x007a, 0x000f);
2809 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
2810 if (phy->rev >= 2) {
2811 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
2812 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
2815 bwn_set_all_gains(mac, 3, 0, 1);
2816 if (phy->rf_rev == 8) {
2817 BWN_RF_WRITE(mac, 0x0043, 0x001f);
2819 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
2820 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
2821 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
2822 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
2824 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
2825 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
2826 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
2828 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2831 * Install calculated narrow RSSI values
2833 if (nrssi1 >= 0x0020)
2835 if (nrssi0 == nrssi1)
2836 pg->pg_nrssi_slope = 0x00010000;
2838 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
2840 pg->pg_nrssi[0] = nrssi1;
2841 pg->pg_nrssi[1] = nrssi0;
2845 * Restore saved RF/PHY registers
2847 if (phy->rev >= 3) {
2848 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
2849 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2850 save_phy3[phy3_idx]);
2853 if (phy->rev >= 2) {
2854 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
2855 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
2858 for (i = 0; i < SAVE_RF_MAX; ++i)
2859 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
2861 BWN_WRITE_2(mac, 0x03e2, ant_div);
2862 BWN_WRITE_2(mac, 0x03e6, phy0);
2863 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
2865 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2866 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
2868 bwn_spu_workaround(mac, phy->chan);
2869 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
2870 bwn_set_original_gains(mac);
2871 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
2872 if (phy->rev >= 3) {
2873 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
2874 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2875 save_phy3[phy3_idx]);
2879 delta = 0x1f - pg->pg_nrssi[0];
2880 for (i = 0; i < 64; i++) {
2881 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
2882 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
2883 pg->pg_nrssi_lt[i] = tmp32;
2886 bwn_nrssi_threshold(mac);
2888 #undef SAVE_PHY_COMM_MAX
2889 #undef SAVE_PHY3_MAX
2893 bwn_nrssi_offset(struct bwn_mac *mac)
2895 #define SAVE_RF_MAX 2
2896 #define SAVE_PHY_COMM_MAX 10
2897 #define SAVE_PHY6_MAX 8
2898 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
2900 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
2901 0x0001, 0x0811, 0x0812, 0x0814,
2902 0x0815, 0x005a, 0x0059, 0x0058,
2905 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
2906 0x002e, 0x002f, 0x080f, 0x0810,
2907 0x0801, 0x0060, 0x0014, 0x0478
2909 struct bwn_phy *phy = &mac->mac_phy;
2910 int i, phy6_idx = 0;
2911 uint16_t save_rf[SAVE_RF_MAX];
2912 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
2913 uint16_t save_phy6[SAVE_PHY6_MAX];
2915 uint16_t saved = 0xffff;
2917 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2918 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
2919 for (i = 0; i < SAVE_RF_MAX; ++i)
2920 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
2922 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
2923 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
2924 BWN_PHY_SET(mac, 0x0811, 0x000c);
2925 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
2926 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
2927 if (phy->rev >= 6) {
2928 for (i = 0; i < SAVE_PHY6_MAX; ++i)
2929 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
2931 BWN_PHY_WRITE(mac, 0x002e, 0);
2932 BWN_PHY_WRITE(mac, 0x002f, 0);
2933 BWN_PHY_WRITE(mac, 0x080f, 0);
2934 BWN_PHY_WRITE(mac, 0x0810, 0);
2935 BWN_PHY_SET(mac, 0x0478, 0x0100);
2936 BWN_PHY_SET(mac, 0x0801, 0x0040);
2937 BWN_PHY_SET(mac, 0x0060, 0x0040);
2938 BWN_PHY_SET(mac, 0x0014, 0x0200);
2940 BWN_RF_SET(mac, 0x007a, 0x0070);
2941 BWN_RF_SET(mac, 0x007a, 0x0080);
2944 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2948 for (i = 7; i >= 4; i--) {
2949 BWN_RF_WRITE(mac, 0x007b, i);
2951 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
2955 if (nrssi < 31 && saved == 0xffff)
2958 if (saved == 0xffff)
2961 BWN_RF_MASK(mac, 0x007a, 0x007f);
2962 if (phy->rev != 1) {
2963 BWN_PHY_SET(mac, 0x0814, 0x0001);
2964 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
2966 BWN_PHY_SET(mac, 0x0811, 0x000c);
2967 BWN_PHY_SET(mac, 0x0812, 0x000c);
2968 BWN_PHY_SET(mac, 0x0811, 0x0030);
2969 BWN_PHY_SET(mac, 0x0812, 0x0030);
2970 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
2971 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
2972 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
2974 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
2976 BWN_PHY_SET(mac, 0x000a, 0x2000);
2977 if (phy->rev != 1) {
2978 BWN_PHY_SET(mac, 0x0814, 0x0004);
2979 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
2981 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
2982 BWN_RF_SET(mac, 0x007a, 0x000f);
2983 bwn_set_all_gains(mac, 3, 0, 1);
2984 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
2986 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
2990 for (i = 0; i < 4; i++) {
2991 BWN_RF_WRITE(mac, 0x007b, i);
2993 nrssi = (int16_t)((BWN_PHY_READ(mac,
2994 0x047f) >> 8) & 0x003f);
2997 if (nrssi > -31 && saved == 0xffff)
3000 if (saved == 0xffff)
3005 BWN_RF_WRITE(mac, 0x007b, saved);
3008 * Restore saved RF/PHY registers
3010 if (phy->rev >= 6) {
3011 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
3012 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
3013 save_phy6[phy6_idx]);
3016 if (phy->rev != 1) {
3017 for (i = 3; i < 5; i++)
3018 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
3021 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
3022 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
3024 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
3025 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
3027 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
3028 BWN_PHY_SET(mac, 0x0429, 0x8000);
3029 bwn_set_original_gains(mac);
3030 if (phy->rev >= 6) {
3031 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
3032 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
3033 save_phy6[phy6_idx]);
3037 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
3038 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
3039 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
3043 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
3046 struct bwn_phy *phy = &mac->mac_phy;
3048 uint16_t start = 0x08, end = 0x18;
3052 if (phy->rev <= 1) {
3057 table = BWN_OFDMTAB_GAINX;
3059 table = BWN_OFDMTAB_GAINX_R1;
3060 for (i = 0; i < 4; i++)
3061 bwn_ofdmtab_write_2(mac, table, i, first);
3063 for (i = start; i < end; i++)
3064 bwn_ofdmtab_write_2(mac, table, i, second);
3067 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
3068 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
3069 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
3070 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
3072 bwn_dummy_transmission(mac, 0, 1);
3076 bwn_set_original_gains(struct bwn_mac *mac)
3078 struct bwn_phy *phy = &mac->mac_phy;
3081 uint16_t start = 0x0008, end = 0x0018;
3083 if (phy->rev <= 1) {
3088 table = BWN_OFDMTAB_GAINX;
3090 table = BWN_OFDMTAB_GAINX_R1;
3091 for (i = 0; i < 4; i++) {
3093 tmp |= (i & 0x0001) << 1;
3094 tmp |= (i & 0x0002) >> 1;
3096 bwn_ofdmtab_write_2(mac, table, i, tmp);
3099 for (i = start; i < end; i++)
3100 bwn_ofdmtab_write_2(mac, table, i, i - start);
3102 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
3103 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
3104 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
3105 bwn_dummy_transmission(mac, 0, 1);
3109 bwn_phy_hwpctl_init(struct bwn_mac *mac)
3111 struct bwn_phy *phy = &mac->mac_phy;
3112 struct bwn_phy_g *pg = &phy->phy_g;
3113 struct bwn_rfatt old_rfatt, rfatt;
3114 struct bwn_bbatt old_bbatt, bbatt;
3115 struct bwn_softc *sc = mac->mac_sc;
3116 uint8_t old_txctl = 0;
3118 KASSERT(phy->type == BWN_PHYTYPE_G,
3119 ("%s:%d: fail", __func__, __LINE__));
3121 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
3122 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
3125 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
3127 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
3131 bwn_hwpctl_early_init(mac);
3132 if (pg->pg_curtssi == 0) {
3133 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
3134 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
3136 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
3137 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
3138 old_txctl = pg->pg_txctl;
3141 if (phy->rf_rev == 8) {
3148 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
3150 bwn_dummy_transmission(mac, 0, 1);
3151 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
3152 if (phy->rf_ver == 0x2050 && phy->analog == 0)
3153 BWN_RF_MASK(mac, 0x0076, 0xff7b);
3155 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
3156 &old_rfatt, old_txctl);
3158 bwn_hwpctl_init_gphy(mac);
3161 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
3162 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
3163 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
3164 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
3168 bwn_hwpctl_early_init(struct bwn_mac *mac)
3170 struct bwn_phy *phy = &mac->mac_phy;
3172 if (!bwn_has_hwpctl(mac)) {
3173 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
3177 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
3178 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
3179 BWN_PHY_SET(mac, 0x047c, 0x0002);
3180 BWN_PHY_SET(mac, 0x047a, 0xf000);
3181 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
3182 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
3183 BWN_PHY_SET(mac, 0x005d, 0x8000);
3184 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
3185 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
3186 BWN_PHY_SET(mac, 0x0036, 0x0400);
3188 BWN_PHY_SET(mac, 0x0036, 0x0200);
3189 BWN_PHY_SET(mac, 0x0036, 0x0400);
3190 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
3191 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
3192 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
3193 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
3194 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
3199 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
3201 struct bwn_phy *phy = &mac->mac_phy;
3202 struct bwn_phy_g *pg = &phy->phy_g;
3203 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
3205 uint16_t nr_written = 0, tmp, value;
3208 if (!bwn_has_hwpctl(mac)) {
3209 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
3213 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
3214 (pg->pg_idletssi - pg->pg_curtssi));
3215 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
3216 (pg->pg_idletssi - pg->pg_curtssi));
3218 for (i = 0; i < 32; i++)
3219 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
3220 for (i = 32; i < 64; i++)
3221 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
3222 for (i = 0; i < 64; i += 2) {
3223 value = (uint16_t) pg->pg_tssi2dbm[i];
3224 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
3225 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
3228 for (rf = 0; rf < lo->rfatt.len; rf++) {
3229 for (bb = 0; bb < lo->bbatt.len; bb++) {
3230 if (nr_written >= 0x40)
3232 tmp = lo->bbatt.array[bb].att;
3234 if (phy->rf_rev == 8)
3238 tmp |= lo->rfatt.array[rf].att;
3239 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
3244 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
3245 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
3247 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
3248 BWN_PHY_SET(mac, 0x0478, 0x0800);
3249 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
3250 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
3252 bwn_phy_g_dc_lookup_init(mac, 1);
3253 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
3257 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
3259 struct bwn_softc *sc = mac->mac_sc;
3262 bwn_spu_workaround(mac, channel);
3264 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
3266 if (channel == 14) {
3267 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
3269 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
3272 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
3273 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
3274 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
3278 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
3279 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
3283 bwn_phy_g_chan2freq(uint8_t channel)
3285 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
3287 KASSERT(channel >= 1 && channel <= 14,
3288 ("%s:%d: fail", __func__, __LINE__));
3290 return (bwn_phy_g_rf_channels[channel - 1]);
3294 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
3295 const struct bwn_rfatt *rfatt, uint8_t txctl)
3297 struct bwn_phy *phy = &mac->mac_phy;
3298 struct bwn_phy_g *pg = &phy->phy_g;
3299 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
3301 uint16_t tx_bias, tx_magn;
3305 tx_bias = lo->tx_bias;
3306 tx_magn = lo->tx_magn;
3307 if (tx_bias == 0xff)
3310 pg->pg_txctl = txctl;
3311 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
3312 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
3313 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
3314 bwn_phy_g_set_bbatt(mac, bb);
3315 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
3316 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
3317 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
3319 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
3320 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
3322 if (BWN_HAS_TXMAG(phy))
3323 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
3325 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
3326 bwn_lo_g_adjust(mac);
3330 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
3333 struct bwn_phy *phy = &mac->mac_phy;
3335 if (phy->analog == 0) {
3336 BWN_WRITE_2(mac, BWN_PHY0,
3337 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
3340 if (phy->analog > 1) {
3341 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
3344 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
3348 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
3350 struct bwn_phy *phy = &mac->mac_phy;
3351 struct bwn_phy_g *pg = &phy->phy_g;
3352 struct bwn_softc *sc = mac->mac_sc;
3357 if (phy->gmode == 0)
3360 if (BWN_HAS_LOOPBACK(phy)) {
3361 max_lb_gain = pg->pg_max_lb_gain;
3362 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
3363 if (max_lb_gain >= 0x46) {
3365 max_lb_gain -= 0x46;
3366 } else if (max_lb_gain >= 0x3a) {
3368 max_lb_gain -= 0x3a;
3369 } else if (max_lb_gain >= 0x2e) {
3371 max_lb_gain -= 0x2e;
3374 max_lb_gain -= 0x10;
3377 for (i = 0; i < 16; i++) {
3378 max_lb_gain -= (i * 6);
3379 if (max_lb_gain < 6)
3383 if ((phy->rev < 7) ||
3384 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
3385 if (reg == BWN_PHY_RFOVER) {
3387 } else if (reg == BWN_PHY_RFOVERVAL) {
3390 case BWN_LPD(0, 1, 1):
3392 case BWN_LPD(0, 0, 1):
3393 case BWN_LPD(1, 0, 1):
3394 return (0x0092 | extlna);
3395 case BWN_LPD(1, 0, 0):
3396 return (0x0093 | extlna);
3399 ("%s:%d: fail", __func__, __LINE__));
3401 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3403 if (reg == BWN_PHY_RFOVER)
3405 if (reg == BWN_PHY_RFOVERVAL) {
3410 case BWN_LPD(0, 1, 1):
3412 case BWN_LPD(0, 0, 1):
3413 return (0x8092 | extlna);
3414 case BWN_LPD(1, 0, 1):
3415 return (0x2092 | extlna);
3416 case BWN_LPD(1, 0, 0):
3417 return (0x2093 | extlna);
3420 ("%s:%d: fail", __func__, __LINE__));
3422 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3427 if ((phy->rev < 7) ||
3428 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
3429 if (reg == BWN_PHY_RFOVER) {
3431 } else if (reg == BWN_PHY_RFOVERVAL) {
3433 case BWN_LPD(0, 1, 1):
3435 case BWN_LPD(0, 0, 1):
3437 case BWN_LPD(1, 0, 1):
3439 case BWN_LPD(1, 0, 0):
3443 ("%s:%d: fail", __func__, __LINE__));
3445 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3447 if (reg == BWN_PHY_RFOVER) {
3449 } else if (reg == BWN_PHY_RFOVERVAL) {
3451 case BWN_LPD(0, 1, 1):
3453 case BWN_LPD(0, 0, 1):
3455 case BWN_LPD(1, 0, 1):
3457 case BWN_LPD(1, 0, 0):
3461 ("%s:%d: fail", __func__, __LINE__));
3463 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3469 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
3472 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
3474 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
3475 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
3477 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
3481 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
3483 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
3484 unsigned int a, b, c, d;
3488 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
3490 b = (tmp >> 8) & 0xff;
3491 c = (tmp >> 16) & 0xff;
3492 d = (tmp >> 24) & 0xff;
3493 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
3494 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
3496 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
3497 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
3498 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
3501 a = (a + 32) & 0x3f;
3502 b = (b + 32) & 0x3f;
3503 c = (c + 32) & 0x3f;
3504 d = (d + 32) & 0x3f;
3507 avg = (a + b + c + d + 2) / 4;
3509 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
3510 & BWN_HF_4DB_CCK_POWERBOOST)
3511 avg = (avg >= 13) ? (avg - 13) : 0;
3517 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
3519 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
3520 int rfatt = *rfattp;
3521 int bbatt = *bbattp;
3524 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
3526 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
3528 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
3530 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
3532 if (bbatt > lo->bbatt.max) {
3537 if (bbatt < lo->bbatt.min) {
3542 if (rfatt > lo->rfatt.max) {
3547 if (rfatt < lo->rfatt.min) {
3555 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
3556 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
3560 bwn_phy_lock(struct bwn_mac *mac)
3562 struct bwn_softc *sc = mac->mac_sc;
3563 struct ieee80211com *ic = &sc->sc_ic;
3565 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
3566 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
3568 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
3569 bwn_psctl(mac, BWN_PS_AWAKE);
3573 bwn_phy_unlock(struct bwn_mac *mac)
3575 struct bwn_softc *sc = mac->mac_sc;
3576 struct ieee80211com *ic = &sc->sc_ic;
3578 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
3579 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
3581 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
3586 bwn_rf_lock(struct bwn_mac *mac)
3589 BWN_WRITE_4(mac, BWN_MACCTL,
3590 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
3591 BWN_READ_4(mac, BWN_MACCTL);
3596 bwn_rf_unlock(struct bwn_mac *mac)
3599 BWN_READ_2(mac, BWN_PHYVER);
3600 BWN_WRITE_4(mac, BWN_MACCTL,
3601 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);