if_bwn.c revision 206358
1/*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 15 * 16 * NO WARRANTY 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. 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: head/sys/dev/bwn/if_bwn.c 206358 2010-04-07 15:29:13Z rpaulo $"); 32 33/* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/module.h> 40#include <sys/kernel.h> 41#include <sys/endian.h> 42#include <sys/errno.h> 43#include <sys/firmware.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <machine/bus.h> 47#include <machine/resource.h> 48#include <sys/bus.h> 49#include <sys/rman.h> 50#include <sys/socket.h> 51#include <sys/sockio.h> 52 53#include <net/ethernet.h> 54#include <net/if.h> 55#include <net/if_arp.h> 56#include <net/if_dl.h> 57#include <net/if_llc.h> 58#include <net/if_media.h> 59#include <net/if_types.h> 60 61#include <dev/pci/pcivar.h> 62#include <dev/pci/pcireg.h> 63#include <dev/siba/siba_ids.h> 64#include <dev/siba/sibareg.h> 65#include <dev/siba/sibavar.h> 66 67#include <net80211/ieee80211_var.h> 68#include <net80211/ieee80211_radiotap.h> 69#include <net80211/ieee80211_regdomain.h> 70#include <net80211/ieee80211_phy.h> 71#include <net80211/ieee80211_ratectl.h> 72 73#include <dev/bwn/if_bwnreg.h> 74#include <dev/bwn/if_bwnvar.h> 75 76SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters"); 77 78/* 79 * Tunable & sysctl variables. 80 */ 81 82#ifdef BWN_DEBUG 83static int bwn_debug = 0; 84SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 85 "Broadcom debugging printfs"); 86TUNABLE_INT("hw.bwn.debug", &bwn_debug); 87enum { 88 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 89 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 90 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 91 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 92 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 93 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 94 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 95 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 96 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 97 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 98 BWN_DEBUG_NODE = 0x00000400, /* node management */ 99 BWN_DEBUG_LED = 0x00000800, /* led management */ 100 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 101 BWN_DEBUG_LO = 0x00002000, /* LO */ 102 BWN_DEBUG_FW = 0x00004000, /* firmware */ 103 BWN_DEBUG_WME = 0x00008000, /* WME */ 104 BWN_DEBUG_RF = 0x00010000, /* RF */ 105 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 106 BWN_DEBUG_ANY = 0xffffffff 107}; 108#define DPRINTF(sc, m, fmt, ...) do { \ 109 if (sc->sc_debug & (m)) \ 110 printf(fmt, __VA_ARGS__); \ 111} while (0) 112#else 113#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 114#endif 115 116static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 117SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 118 "uses Bad Frames Preemption"); 119static int bwn_bluetooth = 1; 120SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 121 "turns on Bluetooth Coexistence"); 122static int bwn_hwpctl = 0; 123SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 124 "uses H/W power control"); 125static int bwn_msi_disable = 0; /* MSI disabled */ 126TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 127static int bwn_usedma = 1; 128SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 129 "uses DMA"); 130TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 131static int bwn_wme = 1; 132SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 133 "uses WME support"); 134 135static int bwn_attach_pre(struct bwn_softc *); 136static int bwn_attach_post(struct bwn_softc *); 137static void bwn_sprom_bugfixes(device_t); 138static void bwn_init(void *); 139static int bwn_init_locked(struct bwn_softc *); 140static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 141static void bwn_start(struct ifnet *); 142static int bwn_attach_core(struct bwn_mac *); 143static void bwn_reset_core(struct bwn_mac *, uint32_t); 144static int bwn_phy_getinfo(struct bwn_mac *, int); 145static int bwn_chiptest(struct bwn_mac *); 146static int bwn_setup_channels(struct bwn_mac *, int, int); 147static int bwn_phy_g_attach(struct bwn_mac *); 148static void bwn_phy_g_detach(struct bwn_mac *); 149static void bwn_phy_g_init_pre(struct bwn_mac *); 150static int bwn_phy_g_prepare_hw(struct bwn_mac *); 151static int bwn_phy_g_init(struct bwn_mac *); 152static void bwn_phy_g_exit(struct bwn_mac *); 153static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 154static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 155 uint16_t); 156static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 157static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 158 uint16_t); 159static int bwn_phy_g_hwpctl(struct bwn_mac *); 160static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 161static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 162static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 163static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 164static int bwn_phy_g_im(struct bwn_mac *, int); 165static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 166static void bwn_phy_g_set_txpwr(struct bwn_mac *); 167static void bwn_phy_g_task_15s(struct bwn_mac *); 168static void bwn_phy_g_task_60s(struct bwn_mac *); 169static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 170static void bwn_phy_switch_analog(struct bwn_mac *, int); 171static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 172static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 173 uint16_t); 174static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 175static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 176 uint32_t); 177static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 178 uint16_t); 179static void bwn_addchannels(struct ieee80211_channel [], int, int *, 180 const struct bwn_channelinfo *, int); 181static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 182 const struct ieee80211_bpf_params *); 183static void bwn_updateslot(struct ifnet *); 184static void bwn_update_promisc(struct ifnet *); 185static void bwn_wme_init(struct bwn_mac *); 186static int bwn_wme_update(struct ieee80211com *); 187static void bwn_wme_clear(struct bwn_softc *); 188static void bwn_wme_load(struct bwn_mac *); 189static void bwn_wme_loadparams(struct bwn_mac *, 190 const struct wmeParams *, uint16_t); 191static void bwn_scan_start(struct ieee80211com *); 192static void bwn_scan_end(struct ieee80211com *); 193static void bwn_set_channel(struct ieee80211com *); 194static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 195 const char [IFNAMSIZ], int, int, 196 int, const uint8_t [IEEE80211_ADDR_LEN], 197 const uint8_t [IEEE80211_ADDR_LEN]); 198static void bwn_vap_delete(struct ieee80211vap *); 199static void bwn_stop(struct bwn_softc *, int); 200static void bwn_stop_locked(struct bwn_softc *, int); 201static int bwn_core_init(struct bwn_mac *); 202static void bwn_core_start(struct bwn_mac *); 203static void bwn_core_exit(struct bwn_mac *); 204static void bwn_bt_disable(struct bwn_mac *); 205static int bwn_chip_init(struct bwn_mac *); 206static uint64_t bwn_hf_read(struct bwn_mac *); 207static void bwn_hf_write(struct bwn_mac *, uint64_t); 208static void bwn_set_txretry(struct bwn_mac *, int, int); 209static void bwn_rate_init(struct bwn_mac *); 210static void bwn_set_phytxctl(struct bwn_mac *); 211static void bwn_spu_setdelay(struct bwn_mac *, int); 212static void bwn_bt_enable(struct bwn_mac *); 213static void bwn_set_macaddr(struct bwn_mac *); 214static void bwn_crypt_init(struct bwn_mac *); 215static void bwn_chip_exit(struct bwn_mac *); 216static int bwn_fw_fillinfo(struct bwn_mac *); 217static int bwn_fw_loaducode(struct bwn_mac *); 218static int bwn_gpio_init(struct bwn_mac *); 219static int bwn_fw_loadinitvals(struct bwn_mac *); 220static int bwn_phy_init(struct bwn_mac *); 221static void bwn_set_txantenna(struct bwn_mac *, int); 222static void bwn_set_opmode(struct bwn_mac *); 223static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 224static uint8_t bwn_plcp_getcck(const uint8_t); 225static uint8_t bwn_plcp_getofdm(const uint8_t); 226static void bwn_pio_init(struct bwn_mac *); 227static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 228static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 229 int); 230static void bwn_pio_setupqueue_rx(struct bwn_mac *, 231 struct bwn_pio_rxqueue *, int); 232static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 233static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 234 uint16_t); 235static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 236static int bwn_pio_rx(struct bwn_pio_rxqueue *); 237static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 238static void bwn_pio_handle_txeof(struct bwn_mac *, 239 const struct bwn_txstatus *); 240static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 241static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 242static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 243 uint16_t); 244static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 245 uint32_t); 246static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 247 struct mbuf *); 248static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 249static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 250 struct bwn_pio_txqueue *, uint32_t, const void *, int); 251static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 252 uint16_t, uint32_t); 253static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 254 struct bwn_pio_txqueue *, uint16_t, const void *, int); 255static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 256 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 257static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 258 uint16_t, struct bwn_pio_txpkt **); 259static void bwn_dma_init(struct bwn_mac *); 260static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 261static int bwn_dma_mask2type(uint64_t); 262static uint64_t bwn_dma_mask(struct bwn_mac *); 263static uint16_t bwn_dma_base(int, int); 264static void bwn_dma_ringfree(struct bwn_dma_ring **); 265static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 266 int, struct bwn_dmadesc_generic **, 267 struct bwn_dmadesc_meta **); 268static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 269 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 270 int, int); 271static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 272static void bwn_dma_32_suspend(struct bwn_dma_ring *); 273static void bwn_dma_32_resume(struct bwn_dma_ring *); 274static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 275static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 276static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 277 int, struct bwn_dmadesc_generic **, 278 struct bwn_dmadesc_meta **); 279static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 280 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 281 int, int); 282static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 283static void bwn_dma_64_suspend(struct bwn_dma_ring *); 284static void bwn_dma_64_resume(struct bwn_dma_ring *); 285static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 286static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 287static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 288static void bwn_dma_setup(struct bwn_dma_ring *); 289static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 290static void bwn_dma_cleanup(struct bwn_dma_ring *); 291static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 292static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 293static void bwn_dma_rx(struct bwn_dma_ring *); 294static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 295static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 296 struct bwn_dmadesc_meta *); 297static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 298static int bwn_dma_gettype(struct bwn_mac *); 299static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 300static int bwn_dma_freeslot(struct bwn_dma_ring *); 301static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 302static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 303static int bwn_dma_newbuf(struct bwn_dma_ring *, 304 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 305 int); 306static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 307 bus_size_t, int); 308static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 309static void bwn_dma_handle_txeof(struct bwn_mac *, 310 const struct bwn_txstatus *); 311static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 312 struct mbuf *); 313static int bwn_dma_getslot(struct bwn_dma_ring *); 314static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 315 uint8_t); 316static int bwn_dma_attach(struct bwn_mac *); 317static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 318 int, int, int); 319static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 320 const struct bwn_txstatus *, uint16_t, int *); 321static void bwn_dma_free(struct bwn_mac *); 322static void bwn_phy_g_init_sub(struct bwn_mac *); 323static uint8_t bwn_has_hwpctl(struct bwn_mac *); 324static void bwn_phy_init_b5(struct bwn_mac *); 325static void bwn_phy_init_b6(struct bwn_mac *); 326static void bwn_phy_init_a(struct bwn_mac *); 327static void bwn_loopback_calcgain(struct bwn_mac *); 328static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 329static void bwn_lo_g_init(struct bwn_mac *); 330static void bwn_lo_g_adjust(struct bwn_mac *); 331static void bwn_lo_get_powervector(struct bwn_mac *); 332static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 333 const struct bwn_bbatt *, const struct bwn_rfatt *); 334static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 335static void bwn_phy_hwpctl_init(struct bwn_mac *); 336static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 337static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 338 const struct bwn_bbatt *, const struct bwn_rfatt *, 339 uint8_t); 340static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 341static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 342static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 343static void bwn_wa_init(struct bwn_mac *); 344static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 345 uint16_t); 346static void bwn_dummy_transmission(struct bwn_mac *, int, int); 347static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 348 uint32_t); 349static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 350 uint16_t); 351static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 352static void bwn_mac_suspend(struct bwn_mac *); 353static void bwn_mac_enable(struct bwn_mac *); 354static void bwn_psctl(struct bwn_mac *, uint32_t); 355static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 356static void bwn_nrssi_offset(struct bwn_mac *); 357static void bwn_nrssi_threshold(struct bwn_mac *); 358static void bwn_nrssi_slope_11g(struct bwn_mac *); 359static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 360 int16_t); 361static void bwn_set_original_gains(struct bwn_mac *); 362static void bwn_hwpctl_early_init(struct bwn_mac *); 363static void bwn_hwpctl_init_gphy(struct bwn_mac *); 364static uint16_t bwn_phy_g_chan2freq(uint8_t); 365static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 366static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 367 const char *, struct bwn_fwfile *); 368static void bwn_release_firmware(struct bwn_mac *); 369static void bwn_do_release_fw(struct bwn_fwfile *); 370static uint16_t bwn_fwcaps_read(struct bwn_mac *); 371static int bwn_fwinitvals_write(struct bwn_mac *, 372 const struct bwn_fwinitvals *, size_t, size_t); 373static int bwn_switch_channel(struct bwn_mac *, int); 374static uint16_t bwn_ant2phy(int); 375static void bwn_mac_write_bssid(struct bwn_mac *); 376static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 377 const uint8_t *); 378static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 379 const uint8_t *, size_t, const uint8_t *); 380static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 381 const uint8_t *); 382static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 383 const uint8_t *); 384static void bwn_phy_exit(struct bwn_mac *); 385static void bwn_core_stop(struct bwn_mac *); 386static int bwn_switch_band(struct bwn_softc *, 387 struct ieee80211_channel *); 388static void bwn_phy_reset(struct bwn_mac *); 389static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 390static void bwn_set_pretbtt(struct bwn_mac *); 391static int bwn_intr(void *); 392static void bwn_intrtask(void *, int); 393static void bwn_restart(struct bwn_mac *, const char *); 394static void bwn_intr_ucode_debug(struct bwn_mac *); 395static void bwn_intr_tbtt_indication(struct bwn_mac *); 396static void bwn_intr_atim_end(struct bwn_mac *); 397static void bwn_intr_beacon(struct bwn_mac *); 398static void bwn_intr_pmq(struct bwn_mac *); 399static void bwn_intr_noise(struct bwn_mac *); 400static void bwn_intr_txeof(struct bwn_mac *); 401static void bwn_hwreset(void *, int); 402static void bwn_handle_fwpanic(struct bwn_mac *); 403static void bwn_load_beacon0(struct bwn_mac *); 404static void bwn_load_beacon1(struct bwn_mac *); 405static uint32_t bwn_jssi_read(struct bwn_mac *); 406static void bwn_noise_gensample(struct bwn_mac *); 407static void bwn_handle_txeof(struct bwn_mac *, 408 const struct bwn_txstatus *); 409static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 410static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 411static void bwn_start_locked(struct ifnet *); 412static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 413 struct mbuf *); 414static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 415static int bwn_set_txhdr(struct bwn_mac *, 416 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 417 uint16_t); 418static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 419 const uint8_t); 420static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 421static uint8_t bwn_get_fbrate(uint8_t); 422static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 423static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 424static void bwn_phy_lock(struct bwn_mac *); 425static void bwn_phy_unlock(struct bwn_mac *); 426static void bwn_rf_lock(struct bwn_mac *); 427static void bwn_rf_unlock(struct bwn_mac *); 428static void bwn_txpwr(void *, int); 429static void bwn_tasks(void *); 430static void bwn_task_15s(struct bwn_mac *); 431static void bwn_task_30s(struct bwn_mac *); 432static void bwn_task_60s(struct bwn_mac *); 433static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 434 uint8_t); 435static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 436static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 437 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 438 int, int); 439static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 440static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 441static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 442static void bwn_watchdog(void *); 443static void bwn_dma_stop(struct bwn_mac *); 444static void bwn_pio_stop(struct bwn_mac *); 445static void bwn_dma_ringstop(struct bwn_dma_ring **); 446static void bwn_led_attach(struct bwn_mac *); 447static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 448static void bwn_led_event(struct bwn_mac *, int); 449static void bwn_led_blink_start(struct bwn_mac *, int, int); 450static void bwn_led_blink_next(void *); 451static void bwn_led_blink_end(void *); 452static void bwn_rfswitch(void *); 453static void bwn_rf_turnon(struct bwn_mac *); 454static void bwn_rf_turnoff(struct bwn_mac *); 455static void bwn_phy_lp_init_pre(struct bwn_mac *); 456static int bwn_phy_lp_init(struct bwn_mac *); 457static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 458static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 459static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 460 uint16_t); 461static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 462static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 463static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 464static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 465static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 466static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 467static void bwn_phy_lp_task_60s(struct bwn_mac *); 468static void bwn_phy_lp_readsprom(struct bwn_mac *); 469static void bwn_phy_lp_bbinit(struct bwn_mac *); 470static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 471static void bwn_phy_lp_calib(struct bwn_mac *); 472static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 473static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 474static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 475static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 476static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 477static void bwn_phy_lp_digflt_save(struct bwn_mac *); 478static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 479static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 480static void bwn_phy_lp_bugfix(struct bwn_mac *); 481static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 482static void bwn_phy_lp_tblinit(struct bwn_mac *); 483static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 484static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 485static void bwn_phy_lp_b2062_init(struct bwn_mac *); 486static void bwn_phy_lp_b2063_init(struct bwn_mac *); 487static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 488static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 489static void bwn_phy_lp_set_rccap(struct bwn_mac *); 490static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 491static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 492static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 493static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 494 const void *); 495static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 496static struct bwn_txgain 497 bwn_phy_lp_get_txgain(struct bwn_mac *); 498static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 499static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 500static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 501static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 502static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 503static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 504static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 505static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 506static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 507static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 508static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 509static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 510static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 511static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 512static int bwn_phy_lp_loopback(struct bwn_mac *); 513static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 514static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 515 int); 516static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 517 struct bwn_phy_lp_iq_est *); 518static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 519static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 520static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 521static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 522static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 523static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 524static uint8_t bwn_nbits(int32_t); 525static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 526 struct bwn_txgain_entry *); 527static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 528 struct bwn_txgain_entry); 529static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 530 struct bwn_txgain_entry); 531static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533static void bwn_sysctl_node(struct bwn_softc *); 534 535static struct resource_spec bwn_res_spec_legacy[] = { 536 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 537 { -1, 0, 0 } 538}; 539 540static struct resource_spec bwn_res_spec_msi[] = { 541 { SYS_RES_IRQ, 1, RF_ACTIVE }, 542 { -1, 0, 0 } 543}; 544 545static const struct bwn_channelinfo bwn_chantable_bg = { 546 .channels = { 547 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 548 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 549 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 550 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 551 { 2472, 13, 30 }, { 2484, 14, 30 } }, 552 .nchannels = 14 553}; 554 555static const struct bwn_channelinfo bwn_chantable_a = { 556 .channels = { 557 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 558 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 559 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 560 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 561 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 562 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 563 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 564 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 565 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 566 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 567 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 568 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 569 { 6080, 216, 30 } }, 570 .nchannels = 37 571}; 572 573static const struct bwn_channelinfo bwn_chantable_n = { 574 .channels = { 575 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 576 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 577 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 578 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 579 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 580 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 581 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 582 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 583 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 584 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 585 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 586 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 587 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 588 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 589 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 590 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 591 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 592 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 593 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 594 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 595 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 596 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 597 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 598 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 599 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 600 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 601 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 602 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 603 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 604 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 605 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 606 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 607 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 608 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 609 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 610 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 611 { 6130, 226, 30 }, { 6140, 228, 30 } }, 612 .nchannels = 110 613}; 614 615static const uint8_t bwn_b2063_chantable_data[33][12] = { 616 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 617 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 629 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 630 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 631 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 634 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 635 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 638 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 649}; 650 651static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 652 { 1, 2412, bwn_b2063_chantable_data[0] }, 653 { 2, 2417, bwn_b2063_chantable_data[0] }, 654 { 3, 2422, bwn_b2063_chantable_data[0] }, 655 { 4, 2427, bwn_b2063_chantable_data[1] }, 656 { 5, 2432, bwn_b2063_chantable_data[1] }, 657 { 6, 2437, bwn_b2063_chantable_data[1] }, 658 { 7, 2442, bwn_b2063_chantable_data[1] }, 659 { 8, 2447, bwn_b2063_chantable_data[1] }, 660 { 9, 2452, bwn_b2063_chantable_data[2] }, 661 { 10, 2457, bwn_b2063_chantable_data[2] }, 662 { 11, 2462, bwn_b2063_chantable_data[3] }, 663 { 12, 2467, bwn_b2063_chantable_data[3] }, 664 { 13, 2472, bwn_b2063_chantable_data[3] }, 665 { 14, 2484, bwn_b2063_chantable_data[4] }, 666 { 34, 5170, bwn_b2063_chantable_data[5] }, 667 { 36, 5180, bwn_b2063_chantable_data[6] }, 668 { 38, 5190, bwn_b2063_chantable_data[7] }, 669 { 40, 5200, bwn_b2063_chantable_data[8] }, 670 { 42, 5210, bwn_b2063_chantable_data[9] }, 671 { 44, 5220, bwn_b2063_chantable_data[10] }, 672 { 46, 5230, bwn_b2063_chantable_data[11] }, 673 { 48, 5240, bwn_b2063_chantable_data[12] }, 674 { 52, 5260, bwn_b2063_chantable_data[13] }, 675 { 56, 5280, bwn_b2063_chantable_data[14] }, 676 { 60, 5300, bwn_b2063_chantable_data[14] }, 677 { 64, 5320, bwn_b2063_chantable_data[15] }, 678 { 100, 5500, bwn_b2063_chantable_data[16] }, 679 { 104, 5520, bwn_b2063_chantable_data[17] }, 680 { 108, 5540, bwn_b2063_chantable_data[18] }, 681 { 112, 5560, bwn_b2063_chantable_data[19] }, 682 { 116, 5580, bwn_b2063_chantable_data[20] }, 683 { 120, 5600, bwn_b2063_chantable_data[21] }, 684 { 124, 5620, bwn_b2063_chantable_data[21] }, 685 { 128, 5640, bwn_b2063_chantable_data[22] }, 686 { 132, 5660, bwn_b2063_chantable_data[22] }, 687 { 136, 5680, bwn_b2063_chantable_data[22] }, 688 { 140, 5700, bwn_b2063_chantable_data[23] }, 689 { 149, 5745, bwn_b2063_chantable_data[23] }, 690 { 153, 5765, bwn_b2063_chantable_data[23] }, 691 { 157, 5785, bwn_b2063_chantable_data[23] }, 692 { 161, 5805, bwn_b2063_chantable_data[23] }, 693 { 165, 5825, bwn_b2063_chantable_data[23] }, 694 { 184, 4920, bwn_b2063_chantable_data[24] }, 695 { 188, 4940, bwn_b2063_chantable_data[25] }, 696 { 192, 4960, bwn_b2063_chantable_data[26] }, 697 { 196, 4980, bwn_b2063_chantable_data[27] }, 698 { 200, 5000, bwn_b2063_chantable_data[28] }, 699 { 204, 5020, bwn_b2063_chantable_data[29] }, 700 { 208, 5040, bwn_b2063_chantable_data[30] }, 701 { 212, 5060, bwn_b2063_chantable_data[31] }, 702 { 216, 5080, bwn_b2063_chantable_data[32] } 703}; 704 705static const uint8_t bwn_b2062_chantable_data[22][12] = { 706 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 707 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 727 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 728}; 729 730static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 731 { 1, 2412, bwn_b2062_chantable_data[0] }, 732 { 2, 2417, bwn_b2062_chantable_data[0] }, 733 { 3, 2422, bwn_b2062_chantable_data[0] }, 734 { 4, 2427, bwn_b2062_chantable_data[0] }, 735 { 5, 2432, bwn_b2062_chantable_data[0] }, 736 { 6, 2437, bwn_b2062_chantable_data[0] }, 737 { 7, 2442, bwn_b2062_chantable_data[0] }, 738 { 8, 2447, bwn_b2062_chantable_data[0] }, 739 { 9, 2452, bwn_b2062_chantable_data[0] }, 740 { 10, 2457, bwn_b2062_chantable_data[0] }, 741 { 11, 2462, bwn_b2062_chantable_data[0] }, 742 { 12, 2467, bwn_b2062_chantable_data[0] }, 743 { 13, 2472, bwn_b2062_chantable_data[0] }, 744 { 14, 2484, bwn_b2062_chantable_data[0] }, 745 { 34, 5170, bwn_b2062_chantable_data[1] }, 746 { 38, 5190, bwn_b2062_chantable_data[2] }, 747 { 42, 5210, bwn_b2062_chantable_data[2] }, 748 { 46, 5230, bwn_b2062_chantable_data[3] }, 749 { 36, 5180, bwn_b2062_chantable_data[4] }, 750 { 40, 5200, bwn_b2062_chantable_data[5] }, 751 { 44, 5220, bwn_b2062_chantable_data[6] }, 752 { 48, 5240, bwn_b2062_chantable_data[3] }, 753 { 52, 5260, bwn_b2062_chantable_data[3] }, 754 { 56, 5280, bwn_b2062_chantable_data[3] }, 755 { 60, 5300, bwn_b2062_chantable_data[7] }, 756 { 64, 5320, bwn_b2062_chantable_data[8] }, 757 { 100, 5500, bwn_b2062_chantable_data[9] }, 758 { 104, 5520, bwn_b2062_chantable_data[10] }, 759 { 108, 5540, bwn_b2062_chantable_data[10] }, 760 { 112, 5560, bwn_b2062_chantable_data[10] }, 761 { 116, 5580, bwn_b2062_chantable_data[11] }, 762 { 120, 5600, bwn_b2062_chantable_data[12] }, 763 { 124, 5620, bwn_b2062_chantable_data[12] }, 764 { 128, 5640, bwn_b2062_chantable_data[12] }, 765 { 132, 5660, bwn_b2062_chantable_data[12] }, 766 { 136, 5680, bwn_b2062_chantable_data[12] }, 767 { 140, 5700, bwn_b2062_chantable_data[12] }, 768 { 149, 5745, bwn_b2062_chantable_data[12] }, 769 { 153, 5765, bwn_b2062_chantable_data[12] }, 770 { 157, 5785, bwn_b2062_chantable_data[12] }, 771 { 161, 5805, bwn_b2062_chantable_data[12] }, 772 { 165, 5825, bwn_b2062_chantable_data[12] }, 773 { 184, 4920, bwn_b2062_chantable_data[13] }, 774 { 188, 4940, bwn_b2062_chantable_data[14] }, 775 { 192, 4960, bwn_b2062_chantable_data[15] }, 776 { 196, 4980, bwn_b2062_chantable_data[16] }, 777 { 200, 5000, bwn_b2062_chantable_data[17] }, 778 { 204, 5020, bwn_b2062_chantable_data[18] }, 779 { 208, 5040, bwn_b2062_chantable_data[19] }, 780 { 212, 5060, bwn_b2062_chantable_data[20] }, 781 { 216, 5080, bwn_b2062_chantable_data[21] } 782}; 783 784/* for LP PHY */ 785static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 786 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 787 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 788 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 789 { 13, -66, 13 }, { 14, -66, 13 }, 790}; 791 792/* for LP PHY */ 793static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 794 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 795 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 796 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 797 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 798 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 799 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 800 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 801 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 802 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 803 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 804 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 805 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 806 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 807}; 808 809static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 810 811static const uint8_t bwn_tab_sigsq_tbl[] = { 812 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 813 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 817 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 818}; 819 820static const uint8_t bwn_tab_pllfrac_tbl[] = { 821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 823}; 824 825static const uint16_t bwn_tabl_iqlocal_tbl[] = { 826 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 827 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 830 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 831 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 838}; 839 840static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 841static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 842static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 843static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 844static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 845const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 846 847#define VENDOR_LED_ACT(vendor) \ 848{ \ 849 .vid = PCI_VENDOR_##vendor, \ 850 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 851} 852 853static const struct { 854 uint16_t vid; 855 uint8_t led_act[BWN_LED_MAX]; 856} bwn_vendor_led_act[] = { 857 VENDOR_LED_ACT(COMPAQ), 858 VENDOR_LED_ACT(ASUSTEK) 859}; 860 861static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 862 { BWN_VENDOR_LED_ACT_DEFAULT }; 863 864#undef VENDOR_LED_ACT 865 866static const struct { 867 int on_dur; 868 int off_dur; 869} bwn_led_duration[109] = { 870 [0] = { 400, 100 }, 871 [2] = { 150, 75 }, 872 [4] = { 90, 45 }, 873 [11] = { 66, 34 }, 874 [12] = { 53, 26 }, 875 [18] = { 42, 21 }, 876 [22] = { 35, 17 }, 877 [24] = { 32, 16 }, 878 [36] = { 21, 10 }, 879 [48] = { 16, 8 }, 880 [72] = { 11, 5 }, 881 [96] = { 9, 4 }, 882 [108] = { 7, 3 } 883}; 884 885static const uint16_t bwn_wme_shm_offsets[] = { 886 [0] = BWN_WME_BESTEFFORT, 887 [1] = BWN_WME_BACKGROUND, 888 [2] = BWN_WME_VOICE, 889 [3] = BWN_WME_VIDEO, 890}; 891 892static const struct siba_devid bwn_devs[] = { 893 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 894 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 895 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 896 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 897 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 898 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 899 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 900 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 901 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 902}; 903 904static int 905bwn_probe(device_t dev) 906{ 907 int i; 908 909 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 910 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 911 siba_get_device(dev) == bwn_devs[i].sd_device && 912 siba_get_revid(dev) == bwn_devs[i].sd_rev) 913 return (BUS_PROBE_DEFAULT); 914 } 915 916 return (ENXIO); 917} 918 919static int 920bwn_attach(device_t dev) 921{ 922 struct bwn_mac *mac; 923 struct bwn_softc *sc = device_get_softc(dev); 924 int error, i, msic, reg; 925 926 sc->sc_dev = dev; 927#ifdef BWN_DEBUG 928 sc->sc_debug = bwn_debug; 929#endif 930 931 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 932 error = bwn_attach_pre(sc); 933 if (error != 0) 934 return (error); 935 bwn_sprom_bugfixes(dev); 936 sc->sc_flags |= BWN_FLAG_ATTACHED; 937 } 938 939 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 940 if (siba_get_pci_device(dev) != 0x4313 && 941 siba_get_pci_device(dev) != 0x431a && 942 siba_get_pci_device(dev) != 0x4321) { 943 device_printf(sc->sc_dev, 944 "skip 802.11 cores\n"); 945 return (ENODEV); 946 } 947 } 948 949 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 950 M_NOWAIT | M_ZERO); 951 if (mac == NULL) 952 return (ENOMEM); 953 mac->mac_sc = sc; 954 mac->mac_status = BWN_MAC_STATUS_UNINIT; 955 if (bwn_bfp != 0) 956 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 957 958 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 959 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 960 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 961 962 error = bwn_attach_core(mac); 963 if (error) 964 goto fail0; 965 bwn_led_attach(mac); 966 967 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 968 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 969 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 970 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 971 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 972 mac->mac_phy.rf_rev); 973 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 974 device_printf(sc->sc_dev, "DMA (%d bits)\n", 975 mac->mac_method.dma.dmatype); 976 else 977 device_printf(sc->sc_dev, "PIO\n"); 978 979 /* 980 * setup PCI resources and interrupt. 981 */ 982 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) { 983 msic = pci_msi_count(dev); 984 if (bootverbose) 985 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 986 } else 987 msic = 0; 988 989 mac->mac_intr_spec = bwn_res_spec_legacy; 990 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 991 if (pci_alloc_msi(dev, &msic) == 0) { 992 device_printf(sc->sc_dev, 993 "Using %d MSI messages\n", msic); 994 mac->mac_intr_spec = bwn_res_spec_msi; 995 mac->mac_msi = 1; 996 } 997 } 998 999 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1000 mac->mac_res_irq); 1001 if (error) { 1002 device_printf(sc->sc_dev, 1003 "couldn't allocate IRQ resources (%d)\n", error); 1004 goto fail1; 1005 } 1006 1007 if (mac->mac_msi == 0) 1008 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1009 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1010 &mac->mac_intrhand[0]); 1011 else { 1012 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1013 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1014 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1015 &mac->mac_intrhand[i]); 1016 if (error != 0) { 1017 device_printf(sc->sc_dev, 1018 "couldn't setup interrupt (%d)\n", error); 1019 break; 1020 } 1021 } 1022 } 1023 1024 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1025 1026 /* 1027 * calls attach-post routine 1028 */ 1029 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1030 bwn_attach_post(sc); 1031 1032 return (0); 1033fail1: 1034 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1035 pci_release_msi(dev); 1036fail0: 1037 free(mac, M_DEVBUF); 1038 return (error); 1039} 1040 1041static int 1042bwn_is_valid_ether_addr(uint8_t *addr) 1043{ 1044 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1045 1046 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1047 return (FALSE); 1048 1049 return (TRUE); 1050} 1051 1052static int 1053bwn_attach_post(struct bwn_softc *sc) 1054{ 1055 struct ieee80211com *ic; 1056 struct ifnet *ifp = sc->sc_ifp; 1057 1058 ic = ifp->if_l2com; 1059 ic->ic_ifp = ifp; 1060 /* XXX not right but it's not used anywhere important */ 1061 ic->ic_phytype = IEEE80211_T_OFDM; 1062 ic->ic_opmode = IEEE80211_M_STA; 1063 ic->ic_caps = 1064 IEEE80211_C_STA /* station mode supported */ 1065 | IEEE80211_C_MONITOR /* monitor mode */ 1066 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1067 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1068 | IEEE80211_C_SHSLOT /* short slot time supported */ 1069 | IEEE80211_C_WME /* WME/WMM supported */ 1070 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1071 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1072 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1073 ; 1074 1075 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1076 1077 /* call MI attach routine. */ 1078 ieee80211_ifattach(ic, 1079 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1080 siba_sprom_get_mac_80211a(sc->sc_dev) : 1081 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1082 1083 ic->ic_headroom = sizeof(struct bwn_txhdr); 1084 1085 /* override default methods */ 1086 ic->ic_raw_xmit = bwn_raw_xmit; 1087 ic->ic_updateslot = bwn_updateslot; 1088 ic->ic_update_promisc = bwn_update_promisc; 1089 ic->ic_wme.wme_update = bwn_wme_update; 1090 1091 ic->ic_scan_start = bwn_scan_start; 1092 ic->ic_scan_end = bwn_scan_end; 1093 ic->ic_set_channel = bwn_set_channel; 1094 1095 ic->ic_vap_create = bwn_vap_create; 1096 ic->ic_vap_delete = bwn_vap_delete; 1097 1098 ieee80211_radiotap_attach(ic, 1099 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1100 BWN_TX_RADIOTAP_PRESENT, 1101 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1102 BWN_RX_RADIOTAP_PRESENT); 1103 1104 bwn_sysctl_node(sc); 1105 1106 if (bootverbose) 1107 ieee80211_announce(ic); 1108 return (0); 1109} 1110 1111static void 1112bwn_phy_detach(struct bwn_mac *mac) 1113{ 1114 1115 if (mac->mac_phy.detach != NULL) 1116 mac->mac_phy.detach(mac); 1117} 1118 1119static int 1120bwn_detach(device_t dev) 1121{ 1122 struct bwn_softc *sc = device_get_softc(dev); 1123 struct bwn_mac *mac = sc->sc_curmac; 1124 struct ifnet *ifp = sc->sc_ifp; 1125 struct ieee80211com *ic = ifp->if_l2com; 1126 int i; 1127 1128 sc->sc_flags |= BWN_FLAG_INVALID; 1129 1130 if (device_is_attached(sc->sc_dev)) { 1131 bwn_stop(sc, 1); 1132 bwn_dma_free(mac); 1133 callout_drain(&sc->sc_led_blink_ch); 1134 callout_drain(&sc->sc_rfswitch_ch); 1135 callout_drain(&sc->sc_task_ch); 1136 callout_drain(&sc->sc_watchdog_ch); 1137 bwn_phy_detach(mac); 1138 if (ifp != NULL) { 1139 ieee80211_draintask(ic, &mac->mac_hwreset); 1140 ieee80211_draintask(ic, &mac->mac_txpower); 1141 ieee80211_ifdetach(ic); 1142 if_free(ifp); 1143 } 1144 } 1145 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1146 taskqueue_free(sc->sc_tq); 1147 1148 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1149 if (mac->mac_intrhand[i] != NULL) { 1150 bus_teardown_intr(dev, mac->mac_res_irq[i], 1151 mac->mac_intrhand[i]); 1152 mac->mac_intrhand[i] = NULL; 1153 } 1154 } 1155 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1156 if (mac->mac_msi != 0) 1157 pci_release_msi(dev); 1158 1159 BWN_LOCK_DESTROY(sc); 1160 return (0); 1161} 1162 1163static int 1164bwn_attach_pre(struct bwn_softc *sc) 1165{ 1166 struct ifnet *ifp; 1167 int error = 0; 1168 1169 BWN_LOCK_INIT(sc); 1170 TAILQ_INIT(&sc->sc_maclist); 1171 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1172 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1173 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1174 1175 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1176 taskqueue_thread_enqueue, &sc->sc_tq); 1177 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1178 "%s taskq", device_get_nameunit(sc->sc_dev)); 1179 1180 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1181 if (ifp == NULL) { 1182 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1183 error = ENOSPC; 1184 goto fail; 1185 } 1186 1187 /* set these up early for if_printf use */ 1188 if_initname(ifp, device_get_name(sc->sc_dev), 1189 device_get_unit(sc->sc_dev)); 1190 1191 ifp->if_softc = sc; 1192 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1193 ifp->if_init = bwn_init; 1194 ifp->if_ioctl = bwn_ioctl; 1195 ifp->if_start = bwn_start; 1196 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 1197 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 1198 IFQ_SET_READY(&ifp->if_snd); 1199 1200 return (0); 1201 1202fail: BWN_LOCK_DESTROY(sc); 1203 return (error); 1204} 1205 1206static void 1207bwn_sprom_bugfixes(device_t dev) 1208{ 1209#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1210 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1211 (siba_get_pci_device(dev) == _device) && \ 1212 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1213 (siba_get_pci_subdevice(dev) == _subdevice)) 1214 1215 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1216 siba_get_pci_subdevice(dev) == 0x4e && 1217 siba_get_pci_revid(dev) > 0x40) 1218 siba_sprom_set_bf_lo(dev, 1219 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1220 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1221 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1222 siba_sprom_set_bf_lo(dev, 1223 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1224 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1225 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1226 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1227 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1228 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1229 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1231 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1232 siba_sprom_set_bf_lo(dev, 1233 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1234 } 1235#undef BWN_ISDEV 1236} 1237 1238static int 1239bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1240{ 1241#define IS_RUNNING(ifp) \ 1242 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1243 struct bwn_softc *sc = ifp->if_softc; 1244 struct ieee80211com *ic = ifp->if_l2com; 1245 struct ifreq *ifr = (struct ifreq *)data; 1246 int error = 0, startall; 1247 1248 switch (cmd) { 1249 case SIOCSIFFLAGS: 1250 startall = 0; 1251 if (IS_RUNNING(ifp)) { 1252 bwn_update_promisc(ifp); 1253 } else if (ifp->if_flags & IFF_UP) { 1254 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1255 bwn_init(sc); 1256 startall = 1; 1257 } 1258 } else 1259 bwn_stop(sc, 1); 1260 if (startall) 1261 ieee80211_start_all(ic); 1262 break; 1263 case SIOCGIFMEDIA: 1264 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1265 break; 1266 case SIOCGIFADDR: 1267 error = ether_ioctl(ifp, cmd, data); 1268 break; 1269 default: 1270 error = EINVAL; 1271 break; 1272 } 1273 return (error); 1274} 1275 1276static void 1277bwn_start(struct ifnet *ifp) 1278{ 1279 struct bwn_softc *sc = ifp->if_softc; 1280 1281 BWN_LOCK(sc); 1282 bwn_start_locked(ifp); 1283 BWN_UNLOCK(sc); 1284} 1285 1286static void 1287bwn_start_locked(struct ifnet *ifp) 1288{ 1289 struct bwn_softc *sc = ifp->if_softc; 1290 struct bwn_mac *mac = sc->sc_curmac; 1291 struct ieee80211_frame *wh; 1292 struct ieee80211_node *ni; 1293 struct ieee80211_key *k; 1294 struct mbuf *m; 1295 1296 BWN_ASSERT_LOCKED(sc); 1297 1298 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1299 mac->mac_status < BWN_MAC_STATUS_STARTED) 1300 return; 1301 1302 for (;;) { 1303 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1304 if (m == NULL) 1305 break; 1306 1307 if (bwn_tx_isfull(sc, m)) 1308 break; 1309 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1310 if (ni == NULL) { 1311 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1312 m_freem(m); 1313 ifp->if_oerrors++; 1314 continue; 1315 } 1316 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1317 wh = mtod(m, struct ieee80211_frame *); 1318 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1319 k = ieee80211_crypto_encap(ni, m); 1320 if (k == NULL) { 1321 ieee80211_free_node(ni); 1322 m_freem(m); 1323 ifp->if_oerrors++; 1324 continue; 1325 } 1326 } 1327 wh = NULL; /* Catch any invalid use */ 1328 1329 if (bwn_tx_start(sc, ni, m) != 0) { 1330 if (ni != NULL) 1331 ieee80211_free_node(ni); 1332 ifp->if_oerrors++; 1333 continue; 1334 } 1335 1336 sc->sc_watchdog_timer = 5; 1337 } 1338} 1339 1340static int 1341bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1342{ 1343 struct bwn_dma_ring *dr; 1344 struct bwn_mac *mac = sc->sc_curmac; 1345 struct bwn_pio_txqueue *tq; 1346 struct ifnet *ifp = sc->sc_ifp; 1347 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1348 1349 BWN_ASSERT_LOCKED(sc); 1350 1351 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1352 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1353 if (dr->dr_stop == 1 || 1354 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1355 dr->dr_stop = 1; 1356 goto full; 1357 } 1358 } else { 1359 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1360 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1361 pktlen > (tq->tq_size - tq->tq_used)) { 1362 tq->tq_stop = 1; 1363 goto full; 1364 } 1365 } 1366 return (0); 1367full: 1368 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1369 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1370 return (1); 1371} 1372 1373static int 1374bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1375{ 1376 struct bwn_mac *mac = sc->sc_curmac; 1377 int error; 1378 1379 BWN_ASSERT_LOCKED(sc); 1380 1381 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1382 m_freem(m); 1383 return (ENXIO); 1384 } 1385 1386 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1387 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1388 if (error) { 1389 m_freem(m); 1390 return (error); 1391 } 1392 return (0); 1393} 1394 1395static int 1396bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1397{ 1398 struct bwn_pio_txpkt *tp; 1399 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1400 struct bwn_softc *sc = mac->mac_sc; 1401 struct bwn_txhdr txhdr; 1402 struct mbuf *m_new; 1403 uint32_t ctl32; 1404 int error; 1405 uint16_t ctl16; 1406 1407 BWN_ASSERT_LOCKED(sc); 1408 1409 /* XXX TODO send packets after DTIM */ 1410 1411 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1412 tp = TAILQ_FIRST(&tq->tq_pktlist); 1413 tp->tp_ni = ni; 1414 tp->tp_m = m; 1415 1416 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1417 if (error) { 1418 device_printf(sc->sc_dev, "tx fail\n"); 1419 return (error); 1420 } 1421 1422 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1423 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1424 tq->tq_free--; 1425 1426 if (siba_get_revid(sc->sc_dev) >= 8) { 1427 /* 1428 * XXX please removes m_defrag(9) 1429 */ 1430 m_new = m_defrag(m, M_DONTWAIT); 1431 if (m_new == NULL) { 1432 device_printf(sc->sc_dev, 1433 "%s: can't defrag TX buffer\n", 1434 __func__); 1435 return (ENOBUFS); 1436 } 1437 if (m_new->m_next != NULL) 1438 device_printf(sc->sc_dev, 1439 "TODO: fragmented packets for PIO\n"); 1440 tp->tp_m = m_new; 1441 1442 /* send HEADER */ 1443 ctl32 = bwn_pio_write_multi_4(mac, tq, 1444 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1445 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1446 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1447 /* send BODY */ 1448 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1449 mtod(m_new, const void *), m_new->m_pkthdr.len); 1450 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1451 ctl32 | BWN_PIO8_TXCTL_EOF); 1452 } else { 1453 ctl16 = bwn_pio_write_multi_2(mac, tq, 1454 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1455 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1456 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1457 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1458 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1459 ctl16 | BWN_PIO_TXCTL_EOF); 1460 } 1461 1462 return (0); 1463} 1464 1465static struct bwn_pio_txqueue * 1466bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1467{ 1468 1469 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1470 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1471 1472 switch (prio) { 1473 case 0: 1474 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1475 case 1: 1476 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1477 case 2: 1478 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1479 case 3: 1480 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1481 } 1482 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1483 return (NULL); 1484} 1485 1486static int 1487bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1488{ 1489#define BWN_GET_TXHDRCACHE(slot) \ 1490 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1491 struct bwn_dma *dma = &mac->mac_method.dma; 1492 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1493 struct bwn_dmadesc_generic *desc; 1494 struct bwn_dmadesc_meta *mt; 1495 struct bwn_softc *sc = mac->mac_sc; 1496 struct ifnet *ifp = sc->sc_ifp; 1497 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1498 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1499 1500 BWN_ASSERT_LOCKED(sc); 1501 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1502 1503 /* XXX send after DTIM */ 1504 1505 slot = bwn_dma_getslot(dr); 1506 dr->getdesc(dr, slot, &desc, &mt); 1507 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1508 ("%s:%d: fail", __func__, __LINE__)); 1509 1510 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1511 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1512 BWN_DMA_COOKIE(dr, slot)); 1513 if (error) 1514 goto fail; 1515 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1516 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1517 &mt->mt_paddr, BUS_DMA_NOWAIT); 1518 if (error) { 1519 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1520 __func__, error); 1521 goto fail; 1522 } 1523 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1524 BUS_DMASYNC_PREWRITE); 1525 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1526 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1527 BUS_DMASYNC_PREWRITE); 1528 1529 slot = bwn_dma_getslot(dr); 1530 dr->getdesc(dr, slot, &desc, &mt); 1531 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1532 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1533 mt->mt_m = m; 1534 mt->mt_ni = ni; 1535 1536 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1537 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1538 if (error && error != EFBIG) { 1539 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1540 __func__, error); 1541 goto fail; 1542 } 1543 if (error) { /* error == EFBIG */ 1544 struct mbuf *m_new; 1545 1546 m_new = m_defrag(m, M_DONTWAIT); 1547 if (m_new == NULL) { 1548 if_printf(ifp, "%s: can't defrag TX buffer\n", 1549 __func__); 1550 error = ENOBUFS; 1551 goto fail; 1552 } else { 1553 m = m_new; 1554 } 1555 1556 mt->mt_m = m; 1557 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1558 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1559 if (error) { 1560 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1561 __func__, error); 1562 goto fail; 1563 } 1564 } 1565 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1566 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1567 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1568 BUS_DMASYNC_PREWRITE); 1569 1570 /* XXX send after DTIM */ 1571 1572 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1573 return (0); 1574fail: 1575 dr->dr_curslot = backup[0]; 1576 dr->dr_usedslot = backup[1]; 1577 return (error); 1578#undef BWN_GET_TXHDRCACHE 1579} 1580 1581static void 1582bwn_watchdog(void *arg) 1583{ 1584 struct bwn_softc *sc = arg; 1585 struct ifnet *ifp = sc->sc_ifp; 1586 1587 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1588 if_printf(ifp, "device timeout\n"); 1589 ifp->if_oerrors++; 1590 } 1591 callout_schedule(&sc->sc_watchdog_ch, hz); 1592} 1593 1594static int 1595bwn_attach_core(struct bwn_mac *mac) 1596{ 1597 struct bwn_softc *sc = mac->mac_sc; 1598 int error, have_bg = 0, have_a = 0; 1599 uint32_t high; 1600 1601 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1602 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1603 1604 siba_powerup(sc->sc_dev, 0); 1605 1606 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1607 bwn_reset_core(mac, 1608 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1609 error = bwn_phy_getinfo(mac, high); 1610 if (error) 1611 goto fail; 1612 1613 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1614 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1615 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1616 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1617 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1618 have_a = have_bg = 0; 1619 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1620 have_a = 1; 1621 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1622 mac->mac_phy.type == BWN_PHYTYPE_N || 1623 mac->mac_phy.type == BWN_PHYTYPE_LP) 1624 have_bg = 1; 1625 else 1626 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1627 mac->mac_phy.type)); 1628 } 1629 /* XXX turns off PHY A because it's not supported */ 1630 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1631 mac->mac_phy.type != BWN_PHYTYPE_N) { 1632 have_a = 0; 1633 have_bg = 1; 1634 } 1635 1636 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1637 mac->mac_phy.attach = bwn_phy_g_attach; 1638 mac->mac_phy.detach = bwn_phy_g_detach; 1639 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1640 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1641 mac->mac_phy.init = bwn_phy_g_init; 1642 mac->mac_phy.exit = bwn_phy_g_exit; 1643 mac->mac_phy.phy_read = bwn_phy_g_read; 1644 mac->mac_phy.phy_write = bwn_phy_g_write; 1645 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1646 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1647 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1648 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1649 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1650 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1651 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1652 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1653 mac->mac_phy.set_im = bwn_phy_g_im; 1654 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1655 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1656 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1657 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1658 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1659 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1660 mac->mac_phy.init = bwn_phy_lp_init; 1661 mac->mac_phy.phy_read = bwn_phy_lp_read; 1662 mac->mac_phy.phy_write = bwn_phy_lp_write; 1663 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1664 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1665 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1666 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1667 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1668 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1669 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1670 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1671 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1672 } else { 1673 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1674 mac->mac_phy.type); 1675 error = ENXIO; 1676 goto fail; 1677 } 1678 1679 mac->mac_phy.gmode = have_bg; 1680 if (mac->mac_phy.attach != NULL) { 1681 error = mac->mac_phy.attach(mac); 1682 if (error) { 1683 device_printf(sc->sc_dev, "failed\n"); 1684 goto fail; 1685 } 1686 } 1687 1688 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1689 1690 error = bwn_chiptest(mac); 1691 if (error) 1692 goto fail; 1693 error = bwn_setup_channels(mac, have_bg, have_a); 1694 if (error) { 1695 device_printf(sc->sc_dev, "failed to setup channels\n"); 1696 goto fail; 1697 } 1698 1699 if (sc->sc_curmac == NULL) 1700 sc->sc_curmac = mac; 1701 1702 error = bwn_dma_attach(mac); 1703 if (error != 0) { 1704 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1705 goto fail; 1706 } 1707 1708 mac->mac_phy.switch_analog(mac, 0); 1709 1710 siba_dev_down(sc->sc_dev, 0); 1711fail: 1712 siba_powerdown(sc->sc_dev); 1713 return (error); 1714} 1715 1716static void 1717bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1718{ 1719 struct bwn_softc *sc = mac->mac_sc; 1720 uint32_t low, ctl; 1721 1722 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1723 1724 siba_dev_up(sc->sc_dev, flags); 1725 DELAY(2000); 1726 1727 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1728 ~BWN_TGSLOW_PHYRESET; 1729 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1730 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1731 DELAY(1000); 1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1734 DELAY(1000); 1735 1736 if (mac->mac_phy.switch_analog != NULL) 1737 mac->mac_phy.switch_analog(mac, 1); 1738 1739 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1740 if (flags & BWN_TGSLOW_SUPPORT_G) 1741 ctl |= BWN_MACCTL_GMODE; 1742 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1743} 1744 1745static int 1746bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1747{ 1748 struct bwn_phy *phy = &mac->mac_phy; 1749 struct bwn_softc *sc = mac->mac_sc; 1750 uint32_t tmp; 1751 1752 /* PHY */ 1753 tmp = BWN_READ_2(mac, BWN_PHYVER); 1754 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1755 phy->rf_on = 1; 1756 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1757 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1758 phy->rev = (tmp & BWN_PHYVER_VERSION); 1759 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1760 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1761 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1762 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1763 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1764 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1765 goto unsupphy; 1766 1767 /* RADIO */ 1768 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1769 if (siba_get_chiprev(sc->sc_dev) == 0) 1770 tmp = 0x3205017f; 1771 else if (siba_get_chiprev(sc->sc_dev) == 1) 1772 tmp = 0x4205017f; 1773 else 1774 tmp = 0x5205017f; 1775 } else { 1776 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1777 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1778 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1779 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1780 } 1781 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1782 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1783 phy->rf_manuf = (tmp & 0x00000fff); 1784 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1785 goto unsupradio; 1786 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1787 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1788 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1789 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1790 (phy->type == BWN_PHYTYPE_N && 1791 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1792 (phy->type == BWN_PHYTYPE_LP && 1793 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1794 goto unsupradio; 1795 1796 return (0); 1797unsupphy: 1798 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1799 "analog %#x)\n", 1800 phy->type, phy->rev, phy->analog); 1801 return (ENXIO); 1802unsupradio: 1803 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1804 "rev %#x)\n", 1805 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1806 return (ENXIO); 1807} 1808 1809static int 1810bwn_chiptest(struct bwn_mac *mac) 1811{ 1812#define TESTVAL0 0x55aaaa55 1813#define TESTVAL1 0xaa5555aa 1814 struct bwn_softc *sc = mac->mac_sc; 1815 uint32_t v, backup; 1816 1817 BWN_LOCK(sc); 1818 1819 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1820 1821 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1822 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1823 goto error; 1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1826 goto error; 1827 1828 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1829 1830 if ((siba_get_revid(sc->sc_dev) >= 3) && 1831 (siba_get_revid(sc->sc_dev) <= 10)) { 1832 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1833 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1834 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1835 goto error; 1836 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1837 goto error; 1838 } 1839 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1840 1841 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1842 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1843 goto error; 1844 1845 BWN_UNLOCK(sc); 1846 return (0); 1847error: 1848 BWN_UNLOCK(sc); 1849 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1850 return (ENODEV); 1851} 1852 1853#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1854#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1855 1856static int 1857bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1858{ 1859 struct bwn_softc *sc = mac->mac_sc; 1860 struct ifnet *ifp = sc->sc_ifp; 1861 struct ieee80211com *ic = ifp->if_l2com; 1862 1863 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1864 ic->ic_nchans = 0; 1865 1866 if (have_bg) 1867 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1868 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1869 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1870 if (have_a) 1871 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1872 &ic->ic_nchans, &bwn_chantable_n, 1873 IEEE80211_CHAN_HTA); 1874 } else { 1875 if (have_a) 1876 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1877 &ic->ic_nchans, &bwn_chantable_a, 1878 IEEE80211_CHAN_A); 1879 } 1880 1881 mac->mac_phy.supports_2ghz = have_bg; 1882 mac->mac_phy.supports_5ghz = have_a; 1883 1884 return (ic->ic_nchans == 0 ? ENXIO : 0); 1885} 1886 1887static uint32_t 1888bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1889{ 1890 uint32_t ret; 1891 1892 BWN_ASSERT_LOCKED(mac->mac_sc); 1893 1894 if (way == BWN_SHARED) { 1895 KASSERT((offset & 0x0001) == 0, 1896 ("%s:%d warn", __func__, __LINE__)); 1897 if (offset & 0x0003) { 1898 bwn_shm_ctlword(mac, way, offset >> 2); 1899 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1900 ret <<= 16; 1901 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1902 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1903 goto out; 1904 } 1905 offset >>= 2; 1906 } 1907 bwn_shm_ctlword(mac, way, offset); 1908 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1909out: 1910 return (ret); 1911} 1912 1913static uint16_t 1914bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1915{ 1916 uint16_t ret; 1917 1918 BWN_ASSERT_LOCKED(mac->mac_sc); 1919 1920 if (way == BWN_SHARED) { 1921 KASSERT((offset & 0x0001) == 0, 1922 ("%s:%d warn", __func__, __LINE__)); 1923 if (offset & 0x0003) { 1924 bwn_shm_ctlword(mac, way, offset >> 2); 1925 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1926 goto out; 1927 } 1928 offset >>= 2; 1929 } 1930 bwn_shm_ctlword(mac, way, offset); 1931 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1932out: 1933 1934 return (ret); 1935} 1936 1937static void 1938bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1939 uint16_t offset) 1940{ 1941 uint32_t control; 1942 1943 control = way; 1944 control <<= 16; 1945 control |= offset; 1946 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1947} 1948 1949static void 1950bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1951 uint32_t value) 1952{ 1953 BWN_ASSERT_LOCKED(mac->mac_sc); 1954 1955 if (way == BWN_SHARED) { 1956 KASSERT((offset & 0x0001) == 0, 1957 ("%s:%d warn", __func__, __LINE__)); 1958 if (offset & 0x0003) { 1959 bwn_shm_ctlword(mac, way, offset >> 2); 1960 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1961 (value >> 16) & 0xffff); 1962 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1963 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1964 return; 1965 } 1966 offset >>= 2; 1967 } 1968 bwn_shm_ctlword(mac, way, offset); 1969 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1970} 1971 1972static void 1973bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1974 uint16_t value) 1975{ 1976 BWN_ASSERT_LOCKED(mac->mac_sc); 1977 1978 if (way == BWN_SHARED) { 1979 KASSERT((offset & 0x0001) == 0, 1980 ("%s:%d warn", __func__, __LINE__)); 1981 if (offset & 0x0003) { 1982 bwn_shm_ctlword(mac, way, offset >> 2); 1983 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1984 return; 1985 } 1986 offset >>= 2; 1987 } 1988 bwn_shm_ctlword(mac, way, offset); 1989 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1990} 1991 1992static void 1993bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1994 int txpow) 1995{ 1996 1997 c->ic_freq = freq; 1998 c->ic_flags = flags; 1999 c->ic_ieee = ieee; 2000 c->ic_minpower = 0; 2001 c->ic_maxpower = 2 * txpow; 2002 c->ic_maxregpower = txpow; 2003} 2004 2005static void 2006bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2007 const struct bwn_channelinfo *ci, int flags) 2008{ 2009 struct ieee80211_channel *c; 2010 int i; 2011 2012 c = &chans[*nchans]; 2013 2014 for (i = 0; i < ci->nchannels; i++) { 2015 const struct bwn_channel *hc; 2016 2017 hc = &ci->channels[i]; 2018 if (*nchans >= maxchans) 2019 break; 2020 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2021 c++, (*nchans)++; 2022 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2023 /* g channel have a separate b-only entry */ 2024 if (*nchans >= maxchans) 2025 break; 2026 c[0] = c[-1]; 2027 c[-1].ic_flags = IEEE80211_CHAN_B; 2028 c++, (*nchans)++; 2029 } 2030 if (flags == IEEE80211_CHAN_HTG) { 2031 /* HT g channel have a separate g-only entry */ 2032 if (*nchans >= maxchans) 2033 break; 2034 c[-1].ic_flags = IEEE80211_CHAN_G; 2035 c[0] = c[-1]; 2036 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2037 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2038 c++, (*nchans)++; 2039 } 2040 if (flags == IEEE80211_CHAN_HTA) { 2041 /* HT a channel have a separate a-only entry */ 2042 if (*nchans >= maxchans) 2043 break; 2044 c[-1].ic_flags = IEEE80211_CHAN_A; 2045 c[0] = c[-1]; 2046 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2047 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2048 c++, (*nchans)++; 2049 } 2050 } 2051} 2052 2053static int 2054bwn_phy_g_attach(struct bwn_mac *mac) 2055{ 2056 struct bwn_softc *sc = mac->mac_sc; 2057 struct bwn_phy *phy = &mac->mac_phy; 2058 struct bwn_phy_g *pg = &phy->phy_g; 2059 unsigned int i; 2060 int16_t pab0, pab1, pab2; 2061 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2062 int8_t bg; 2063 2064 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2065 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2066 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2067 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2068 2069 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2070 device_printf(sc->sc_dev, "not supported anymore\n"); 2071 2072 pg->pg_flags = 0; 2073 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2074 pab2 == -1) { 2075 pg->pg_idletssi = 52; 2076 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2077 return (0); 2078 } 2079 2080 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2081 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2082 if (pg->pg_tssi2dbm == NULL) { 2083 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2084 return (ENOMEM); 2085 } 2086 for (i = 0; i < 64; i++) { 2087 int32_t m1, m2, f, q, delta; 2088 int8_t j = 0; 2089 2090 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2091 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2092 f = 256; 2093 2094 do { 2095 if (j > 15) { 2096 device_printf(sc->sc_dev, 2097 "failed to generate tssi2dBm\n"); 2098 free(pg->pg_tssi2dbm, M_DEVBUF); 2099 return (ENOMEM); 2100 } 2101 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2102 f, 2048); 2103 delta = abs(q - f); 2104 f = q; 2105 j++; 2106 } while (delta >= 2); 2107 2108 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2109 128); 2110 } 2111 2112 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2113 return (0); 2114} 2115 2116static void 2117bwn_phy_g_detach(struct bwn_mac *mac) 2118{ 2119 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2120 2121 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2122 free(pg->pg_tssi2dbm, M_DEVBUF); 2123 pg->pg_tssi2dbm = NULL; 2124 } 2125 pg->pg_flags = 0; 2126} 2127 2128static void 2129bwn_phy_g_init_pre(struct bwn_mac *mac) 2130{ 2131 struct bwn_phy *phy = &mac->mac_phy; 2132 struct bwn_phy_g *pg = &phy->phy_g; 2133 void *tssi2dbm; 2134 int idletssi; 2135 unsigned int i; 2136 2137 tssi2dbm = pg->pg_tssi2dbm; 2138 idletssi = pg->pg_idletssi; 2139 2140 memset(pg, 0, sizeof(*pg)); 2141 2142 pg->pg_tssi2dbm = tssi2dbm; 2143 pg->pg_idletssi = idletssi; 2144 2145 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2146 2147 for (i = 0; i < N(pg->pg_nrssi); i++) 2148 pg->pg_nrssi[i] = -1000; 2149 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2150 pg->pg_nrssi_lt[i] = i; 2151 pg->pg_lofcal = 0xffff; 2152 pg->pg_initval = 0xffff; 2153 pg->pg_immode = BWN_IMMODE_NONE; 2154 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2155 pg->pg_avgtssi = 0xff; 2156 2157 pg->pg_loctl.tx_bias = 0xff; 2158 TAILQ_INIT(&pg->pg_loctl.calib_list); 2159} 2160 2161static int 2162bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2163{ 2164 struct bwn_phy *phy = &mac->mac_phy; 2165 struct bwn_phy_g *pg = &phy->phy_g; 2166 struct bwn_softc *sc = mac->mac_sc; 2167 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2168 static const struct bwn_rfatt rfatt0[] = { 2169 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2170 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2171 { 3, 1 }, { 4, 1 } 2172 }; 2173 static const struct bwn_rfatt rfatt1[] = { 2174 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2175 { 14, 1 } 2176 }; 2177 static const struct bwn_rfatt rfatt2[] = { 2178 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2179 { 9, 1 } 2180 }; 2181 static const struct bwn_bbatt bbatt_0[] = { 2182 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2183 }; 2184 2185 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2186 2187 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2188 pg->pg_bbatt.att = 0; 2189 else 2190 pg->pg_bbatt.att = 2; 2191 2192 /* prepare Radio Attenuation */ 2193 pg->pg_rfatt.padmix = 0; 2194 2195 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2196 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2197 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2198 pg->pg_rfatt.att = 2; 2199 goto done; 2200 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2201 pg->pg_rfatt.att = 3; 2202 goto done; 2203 } 2204 } 2205 2206 if (phy->type == BWN_PHYTYPE_A) { 2207 pg->pg_rfatt.att = 0x60; 2208 goto done; 2209 } 2210 2211 switch (phy->rf_ver) { 2212 case 0x2050: 2213 switch (phy->rf_rev) { 2214 case 0: 2215 pg->pg_rfatt.att = 5; 2216 goto done; 2217 case 1: 2218 if (phy->type == BWN_PHYTYPE_G) { 2219 if (siba_get_pci_subvendor(sc->sc_dev) == 2220 SIBA_BOARDVENDOR_BCM && 2221 siba_get_pci_subdevice(sc->sc_dev) == 2222 SIBA_BOARD_BCM4309G && 2223 siba_get_pci_revid(sc->sc_dev) >= 30) 2224 pg->pg_rfatt.att = 3; 2225 else if (siba_get_pci_subvendor(sc->sc_dev) == 2226 SIBA_BOARDVENDOR_BCM && 2227 siba_get_pci_subdevice(sc->sc_dev) == 2228 SIBA_BOARD_BU4306) 2229 pg->pg_rfatt.att = 3; 2230 else 2231 pg->pg_rfatt.att = 1; 2232 } else { 2233 if (siba_get_pci_subvendor(sc->sc_dev) == 2234 SIBA_BOARDVENDOR_BCM && 2235 siba_get_pci_subdevice(sc->sc_dev) == 2236 SIBA_BOARD_BCM4309G && 2237 siba_get_pci_revid(sc->sc_dev) >= 30) 2238 pg->pg_rfatt.att = 7; 2239 else 2240 pg->pg_rfatt.att = 6; 2241 } 2242 goto done; 2243 case 2: 2244 if (phy->type == BWN_PHYTYPE_G) { 2245 if (siba_get_pci_subvendor(sc->sc_dev) == 2246 SIBA_BOARDVENDOR_BCM && 2247 siba_get_pci_subdevice(sc->sc_dev) == 2248 SIBA_BOARD_BCM4309G && 2249 siba_get_pci_revid(sc->sc_dev) >= 30) 2250 pg->pg_rfatt.att = 3; 2251 else if (siba_get_pci_subvendor(sc->sc_dev) == 2252 SIBA_BOARDVENDOR_BCM && 2253 siba_get_pci_subdevice(sc->sc_dev) == 2254 SIBA_BOARD_BU4306) 2255 pg->pg_rfatt.att = 5; 2256 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2257 pg->pg_rfatt.att = 4; 2258 else 2259 pg->pg_rfatt.att = 3; 2260 } else 2261 pg->pg_rfatt.att = 6; 2262 goto done; 2263 case 3: 2264 pg->pg_rfatt.att = 5; 2265 goto done; 2266 case 4: 2267 case 5: 2268 pg->pg_rfatt.att = 1; 2269 goto done; 2270 case 6: 2271 case 7: 2272 pg->pg_rfatt.att = 5; 2273 goto done; 2274 case 8: 2275 pg->pg_rfatt.att = 0xa; 2276 pg->pg_rfatt.padmix = 1; 2277 goto done; 2278 case 9: 2279 default: 2280 pg->pg_rfatt.att = 5; 2281 goto done; 2282 } 2283 break; 2284 case 0x2053: 2285 switch (phy->rf_rev) { 2286 case 1: 2287 pg->pg_rfatt.att = 6; 2288 goto done; 2289 } 2290 break; 2291 } 2292 pg->pg_rfatt.att = 5; 2293done: 2294 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2295 2296 if (!bwn_has_hwpctl(mac)) { 2297 lo->rfatt.array = rfatt0; 2298 lo->rfatt.len = N(rfatt0); 2299 lo->rfatt.min = 0; 2300 lo->rfatt.max = 9; 2301 goto genbbatt; 2302 } 2303 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2304 lo->rfatt.array = rfatt1; 2305 lo->rfatt.len = N(rfatt1); 2306 lo->rfatt.min = 0; 2307 lo->rfatt.max = 14; 2308 goto genbbatt; 2309 } 2310 lo->rfatt.array = rfatt2; 2311 lo->rfatt.len = N(rfatt2); 2312 lo->rfatt.min = 0; 2313 lo->rfatt.max = 9; 2314genbbatt: 2315 lo->bbatt.array = bbatt_0; 2316 lo->bbatt.len = N(bbatt_0); 2317 lo->bbatt.min = 0; 2318 lo->bbatt.max = 8; 2319 2320 BWN_READ_4(mac, BWN_MACCTL); 2321 if (phy->rev == 1) { 2322 phy->gmode = 0; 2323 bwn_reset_core(mac, 0); 2324 bwn_phy_g_init_sub(mac); 2325 phy->gmode = 1; 2326 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2327 } 2328 return (0); 2329} 2330 2331static uint16_t 2332bwn_phy_g_txctl(struct bwn_mac *mac) 2333{ 2334 struct bwn_phy *phy = &mac->mac_phy; 2335 2336 if (phy->rf_ver != 0x2050) 2337 return (0); 2338 if (phy->rf_rev == 1) 2339 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2340 if (phy->rf_rev < 6) 2341 return (BWN_TXCTL_PA2DB); 2342 if (phy->rf_rev == 8) 2343 return (BWN_TXCTL_TXMIX); 2344 return (0); 2345} 2346 2347static int 2348bwn_phy_g_init(struct bwn_mac *mac) 2349{ 2350 2351 bwn_phy_g_init_sub(mac); 2352 return (0); 2353} 2354 2355static void 2356bwn_phy_g_exit(struct bwn_mac *mac) 2357{ 2358 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2359 struct bwn_lo_calib *cal, *tmp; 2360 2361 if (lo == NULL) 2362 return; 2363 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2364 TAILQ_REMOVE(&lo->calib_list, cal, list); 2365 free(cal, M_DEVBUF); 2366 } 2367} 2368 2369static uint16_t 2370bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2371{ 2372 2373 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2374 return (BWN_READ_2(mac, BWN_PHYDATA)); 2375} 2376 2377static void 2378bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2379{ 2380 2381 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2382 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2383} 2384 2385static uint16_t 2386bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2387{ 2388 2389 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2390 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2391 return (BWN_READ_2(mac, BWN_RFDATALO)); 2392} 2393 2394static void 2395bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2396{ 2397 2398 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2399 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2400 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2401} 2402 2403static int 2404bwn_phy_g_hwpctl(struct bwn_mac *mac) 2405{ 2406 2407 return (mac->mac_phy.rev >= 6); 2408} 2409 2410static void 2411bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2412{ 2413 struct bwn_phy *phy = &mac->mac_phy; 2414 struct bwn_phy_g *pg = &phy->phy_g; 2415 unsigned int channel; 2416 uint16_t rfover, rfoverval; 2417 2418 if (on) { 2419 if (phy->rf_on) 2420 return; 2421 2422 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2423 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2424 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2425 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2426 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2427 pg->pg_radioctx_over); 2428 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2429 pg->pg_radioctx_overval); 2430 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2431 } 2432 channel = phy->chan; 2433 bwn_phy_g_switch_chan(mac, 6, 1); 2434 bwn_phy_g_switch_chan(mac, channel, 0); 2435 return; 2436 } 2437 2438 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2439 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2440 pg->pg_radioctx_over = rfover; 2441 pg->pg_radioctx_overval = rfoverval; 2442 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2443 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2444 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2445} 2446 2447static int 2448bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2449{ 2450 2451 if ((newchan < 1) || (newchan > 14)) 2452 return (EINVAL); 2453 bwn_phy_g_switch_chan(mac, newchan, 0); 2454 2455 return (0); 2456} 2457 2458static uint32_t 2459bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2460{ 2461 2462 return (1); 2463} 2464 2465static void 2466bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2467{ 2468 struct bwn_phy *phy = &mac->mac_phy; 2469 uint64_t hf; 2470 int autodiv = 0; 2471 uint16_t tmp; 2472 2473 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2474 autodiv = 1; 2475 2476 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2477 bwn_hf_write(mac, hf); 2478 2479 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2480 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2481 ((autodiv ? BWN_ANTAUTO1 : antenna) 2482 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2483 2484 if (autodiv) { 2485 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2486 if (antenna == BWN_ANTAUTO1) 2487 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2488 else 2489 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2490 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2491 } 2492 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2493 if (autodiv) 2494 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2495 else 2496 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2497 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2498 if (phy->rev >= 2) { 2499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2500 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2501 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2502 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2503 0x15); 2504 if (phy->rev == 2) 2505 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2506 else 2507 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2508 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2509 8); 2510 } 2511 if (phy->rev >= 6) 2512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2513 2514 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2515 bwn_hf_write(mac, hf); 2516} 2517 2518static int 2519bwn_phy_g_im(struct bwn_mac *mac, int mode) 2520{ 2521 struct bwn_phy *phy = &mac->mac_phy; 2522 struct bwn_phy_g *pg = &phy->phy_g; 2523 2524 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2525 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2526 2527 if (phy->rev == 0 || !phy->gmode) 2528 return (ENODEV); 2529 2530 pg->pg_aci_wlan_automatic = 0; 2531 return (0); 2532} 2533 2534static int 2535bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2536{ 2537 struct bwn_phy *phy = &mac->mac_phy; 2538 struct bwn_phy_g *pg = &phy->phy_g; 2539 struct bwn_softc *sc = mac->mac_sc; 2540 unsigned int tssi; 2541 int cck, ofdm; 2542 int power; 2543 int rfatt, bbatt; 2544 unsigned int max; 2545 2546 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2547 2548 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2549 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2550 if (cck < 0 && ofdm < 0) { 2551 if (ignore_tssi == 0) 2552 return (BWN_TXPWR_RES_DONE); 2553 cck = 0; 2554 ofdm = 0; 2555 } 2556 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2557 if (pg->pg_avgtssi != 0xff) 2558 tssi = (tssi + pg->pg_avgtssi) / 2; 2559 pg->pg_avgtssi = tssi; 2560 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2561 2562 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2563 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2564 max -= 3; 2565 if (max >= 120) { 2566 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2567 max = 80; 2568 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2569 } 2570 2571 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2572 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2573 tssi, 0x00), 0x3f)]); 2574 if (power == 0) 2575 return (BWN_TXPWR_RES_DONE); 2576 2577 rfatt = -((power + 7) / 8); 2578 bbatt = (-(power / 2)) - (4 * rfatt); 2579 if ((rfatt == 0) && (bbatt == 0)) 2580 return (BWN_TXPWR_RES_DONE); 2581 pg->pg_bbatt_delta = bbatt; 2582 pg->pg_rfatt_delta = rfatt; 2583 return (BWN_TXPWR_RES_NEED_ADJUST); 2584} 2585 2586static void 2587bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2588{ 2589 struct bwn_phy *phy = &mac->mac_phy; 2590 struct bwn_phy_g *pg = &phy->phy_g; 2591 struct bwn_softc *sc = mac->mac_sc; 2592 int rfatt, bbatt; 2593 uint8_t txctl; 2594 2595 bwn_mac_suspend(mac); 2596 2597 BWN_ASSERT_LOCKED(sc); 2598 2599 bbatt = pg->pg_bbatt.att; 2600 bbatt += pg->pg_bbatt_delta; 2601 rfatt = pg->pg_rfatt.att; 2602 rfatt += pg->pg_rfatt_delta; 2603 2604 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2605 txctl = pg->pg_txctl; 2606 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2607 if (rfatt <= 1) { 2608 if (txctl == 0) { 2609 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2610 rfatt += 2; 2611 bbatt += 2; 2612 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2613 BWN_BFL_PACTRL) { 2614 bbatt += 4 * (rfatt - 2); 2615 rfatt = 2; 2616 } 2617 } else if (rfatt > 4 && txctl) { 2618 txctl = 0; 2619 if (bbatt < 3) { 2620 rfatt -= 3; 2621 bbatt += 2; 2622 } else { 2623 rfatt -= 2; 2624 bbatt -= 2; 2625 } 2626 } 2627 } 2628 pg->pg_txctl = txctl; 2629 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2630 pg->pg_rfatt.att = rfatt; 2631 pg->pg_bbatt.att = bbatt; 2632 2633 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2634 2635 bwn_phy_lock(mac); 2636 bwn_rf_lock(mac); 2637 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2638 pg->pg_txctl); 2639 bwn_rf_unlock(mac); 2640 bwn_phy_unlock(mac); 2641 2642 bwn_mac_enable(mac); 2643} 2644 2645static void 2646bwn_phy_g_task_15s(struct bwn_mac *mac) 2647{ 2648 struct bwn_phy *phy = &mac->mac_phy; 2649 struct bwn_phy_g *pg = &phy->phy_g; 2650 struct bwn_softc *sc = mac->mac_sc; 2651 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2652 unsigned long expire, now; 2653 struct bwn_lo_calib *cal, *tmp; 2654 uint8_t expired = 0; 2655 2656 bwn_mac_suspend(mac); 2657 2658 if (lo == NULL) 2659 goto fail; 2660 2661 BWN_GETTIME(now); 2662 if (bwn_has_hwpctl(mac)) { 2663 expire = now - BWN_LO_PWRVEC_EXPIRE; 2664 if (time_before(lo->pwr_vec_read_time, expire)) { 2665 bwn_lo_get_powervector(mac); 2666 bwn_phy_g_dc_lookup_init(mac, 0); 2667 } 2668 goto fail; 2669 } 2670 2671 expire = now - BWN_LO_CALIB_EXPIRE; 2672 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2673 if (!time_before(cal->calib_time, expire)) 2674 continue; 2675 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2676 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2677 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2678 expired = 1; 2679 } 2680 2681 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2682 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2683 cal->ctl.i, cal->ctl.q); 2684 2685 TAILQ_REMOVE(&lo->calib_list, cal, list); 2686 free(cal, M_DEVBUF); 2687 } 2688 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2689 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2690 &pg->pg_rfatt); 2691 if (cal == NULL) { 2692 device_printf(sc->sc_dev, 2693 "failed to recalibrate LO\n"); 2694 goto fail; 2695 } 2696 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2697 bwn_lo_write(mac, &cal->ctl); 2698 } 2699 2700fail: 2701 bwn_mac_enable(mac); 2702} 2703 2704static void 2705bwn_phy_g_task_60s(struct bwn_mac *mac) 2706{ 2707 struct bwn_phy *phy = &mac->mac_phy; 2708 struct bwn_softc *sc = mac->mac_sc; 2709 uint8_t old = phy->chan; 2710 2711 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2712 return; 2713 2714 bwn_mac_suspend(mac); 2715 bwn_nrssi_slope_11g(mac); 2716 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2717 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2718 bwn_switch_channel(mac, old); 2719 } 2720 bwn_mac_enable(mac); 2721} 2722 2723static void 2724bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2725{ 2726 2727 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2728} 2729 2730static int 2731bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2732 const struct ieee80211_bpf_params *params) 2733{ 2734 struct ieee80211com *ic = ni->ni_ic; 2735 struct ifnet *ifp = ic->ic_ifp; 2736 struct bwn_softc *sc = ifp->if_softc; 2737 struct bwn_mac *mac = sc->sc_curmac; 2738 2739 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2740 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2741 ieee80211_free_node(ni); 2742 m_freem(m); 2743 return (ENETDOWN); 2744 } 2745 2746 BWN_LOCK(sc); 2747 if (bwn_tx_isfull(sc, m)) { 2748 ieee80211_free_node(ni); 2749 m_freem(m); 2750 ifp->if_oerrors++; 2751 BWN_UNLOCK(sc); 2752 return (ENOBUFS); 2753 } 2754 2755 if (bwn_tx_start(sc, ni, m) != 0) { 2756 if (ni != NULL) 2757 ieee80211_free_node(ni); 2758 ifp->if_oerrors++; 2759 } 2760 sc->sc_watchdog_timer = 5; 2761 BWN_UNLOCK(sc); 2762 return (0); 2763} 2764 2765/* 2766 * Callback from the 802.11 layer to update the slot time 2767 * based on the current setting. We use it to notify the 2768 * firmware of ERP changes and the f/w takes care of things 2769 * like slot time and preamble. 2770 */ 2771static void 2772bwn_updateslot(struct ifnet *ifp) 2773{ 2774 struct bwn_softc *sc = ifp->if_softc; 2775 struct ieee80211com *ic = ifp->if_l2com; 2776 struct bwn_mac *mac; 2777 2778 BWN_LOCK(sc); 2779 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2780 mac = (struct bwn_mac *)sc->sc_curmac; 2781 bwn_set_slot_time(mac, 2782 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2783 } 2784 BWN_UNLOCK(sc); 2785} 2786 2787/* 2788 * Callback from the 802.11 layer after a promiscuous mode change. 2789 * Note this interface does not check the operating mode as this 2790 * is an internal callback and we are expected to honor the current 2791 * state (e.g. this is used for setting the interface in promiscuous 2792 * mode when operating in hostap mode to do ACS). 2793 */ 2794static void 2795bwn_update_promisc(struct ifnet *ifp) 2796{ 2797 struct bwn_softc *sc = ifp->if_softc; 2798 struct bwn_mac *mac = sc->sc_curmac; 2799 2800 BWN_LOCK(sc); 2801 mac = sc->sc_curmac; 2802 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2803 if (ifp->if_flags & IFF_PROMISC) 2804 sc->sc_filters |= BWN_MACCTL_PROMISC; 2805 else 2806 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2807 bwn_set_opmode(mac); 2808 } 2809 BWN_UNLOCK(sc); 2810} 2811 2812/* 2813 * Callback from the 802.11 layer to update WME parameters. 2814 */ 2815static int 2816bwn_wme_update(struct ieee80211com *ic) 2817{ 2818 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2819 struct bwn_mac *mac = sc->sc_curmac; 2820 struct wmeParams *wmep; 2821 int i; 2822 2823 BWN_LOCK(sc); 2824 mac = sc->sc_curmac; 2825 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2826 bwn_mac_suspend(mac); 2827 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2828 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2829 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2830 } 2831 bwn_mac_enable(mac); 2832 } 2833 BWN_UNLOCK(sc); 2834 return (0); 2835} 2836 2837static void 2838bwn_scan_start(struct ieee80211com *ic) 2839{ 2840 struct ifnet *ifp = ic->ic_ifp; 2841 struct bwn_softc *sc = ifp->if_softc; 2842 struct bwn_mac *mac; 2843 2844 BWN_LOCK(sc); 2845 mac = sc->sc_curmac; 2846 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2847 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2848 bwn_set_opmode(mac); 2849 /* disable CFP update during scan */ 2850 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2851 } 2852 BWN_UNLOCK(sc); 2853} 2854 2855static void 2856bwn_scan_end(struct ieee80211com *ic) 2857{ 2858 struct ifnet *ifp = ic->ic_ifp; 2859 struct bwn_softc *sc = ifp->if_softc; 2860 struct bwn_mac *mac; 2861 2862 BWN_LOCK(sc); 2863 mac = sc->sc_curmac; 2864 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2865 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2866 bwn_set_opmode(mac); 2867 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2868 } 2869 BWN_UNLOCK(sc); 2870} 2871 2872static void 2873bwn_set_channel(struct ieee80211com *ic) 2874{ 2875 struct ifnet *ifp = ic->ic_ifp; 2876 struct bwn_softc *sc = ifp->if_softc; 2877 struct bwn_mac *mac = sc->sc_curmac; 2878 struct bwn_phy *phy = &mac->mac_phy; 2879 int chan, error; 2880 2881 BWN_LOCK(sc); 2882 2883 error = bwn_switch_band(sc, ic->ic_curchan); 2884 if (error) 2885 goto fail;; 2886 bwn_mac_suspend(mac); 2887 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2888 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2889 if (chan != phy->chan) 2890 bwn_switch_channel(mac, chan); 2891 2892 /* TX power level */ 2893 if (ic->ic_curchan->ic_maxpower != 0 && 2894 ic->ic_curchan->ic_maxpower != phy->txpower) { 2895 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2896 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2897 BWN_TXPWR_IGNORE_TSSI); 2898 } 2899 2900 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2901 if (phy->set_antenna) 2902 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2903 2904 if (sc->sc_rf_enabled != phy->rf_on) { 2905 if (sc->sc_rf_enabled) { 2906 bwn_rf_turnon(mac); 2907 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2908 device_printf(sc->sc_dev, 2909 "please turns on the RF switch\n"); 2910 } else 2911 bwn_rf_turnoff(mac); 2912 } 2913 2914 bwn_mac_enable(mac); 2915 2916fail: 2917 /* 2918 * Setup radio tap channel freq and flags 2919 */ 2920 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2921 htole16(ic->ic_curchan->ic_freq); 2922 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2923 htole16(ic->ic_curchan->ic_flags & 0xffff); 2924 2925 BWN_UNLOCK(sc); 2926} 2927 2928static struct ieee80211vap * 2929bwn_vap_create(struct ieee80211com *ic, 2930 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2931 const uint8_t bssid[IEEE80211_ADDR_LEN], 2932 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2933{ 2934 struct ifnet *ifp = ic->ic_ifp; 2935 struct bwn_softc *sc = ifp->if_softc; 2936 struct ieee80211vap *vap; 2937 struct bwn_vap *bvp; 2938 uint8_t mac[IEEE80211_ADDR_LEN]; 2939 2940 IEEE80211_ADDR_COPY(mac, mac0); 2941 switch (opmode) { 2942 case IEEE80211_M_HOSTAP: 2943 case IEEE80211_M_MBSS: 2944 case IEEE80211_M_STA: 2945 case IEEE80211_M_WDS: 2946 case IEEE80211_M_MONITOR: 2947 case IEEE80211_M_IBSS: 2948 case IEEE80211_M_AHDEMO: 2949 break; 2950 default: 2951 return (NULL); 2952 } 2953 2954 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2955 2956 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2957 M_80211_VAP, M_NOWAIT | M_ZERO); 2958 if (bvp == NULL) { 2959 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2960 return (NULL); 2961 } 2962 vap = &bvp->bv_vap; 2963 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2964 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2965 /* override with driver methods */ 2966 bvp->bv_newstate = vap->iv_newstate; 2967 vap->iv_newstate = bwn_newstate; 2968 2969 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2970 vap->iv_max_aid = BWN_STAID_MAX; 2971 2972 ieee80211_ratectl_init(vap); 2973 2974 /* complete setup */ 2975 ieee80211_vap_attach(vap, ieee80211_media_change, 2976 ieee80211_media_status); 2977 return (vap); 2978} 2979 2980static void 2981bwn_vap_delete(struct ieee80211vap *vap) 2982{ 2983 struct bwn_vap *bvp = BWN_VAP(vap); 2984 2985 ieee80211_ratectl_deinit(vap); 2986 ieee80211_vap_detach(vap); 2987 free(bvp, M_80211_VAP); 2988} 2989 2990static void 2991bwn_init(void *arg) 2992{ 2993 struct bwn_softc *sc = arg; 2994 struct ifnet *ifp = sc->sc_ifp; 2995 struct ieee80211com *ic = ifp->if_l2com; 2996 int error = 0; 2997 2998 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2999 __func__, ifp->if_flags); 3000 3001 BWN_LOCK(sc); 3002 error = bwn_init_locked(sc); 3003 BWN_UNLOCK(sc); 3004 3005 if (error == 0) 3006 ieee80211_start_all(ic); /* start all vap's */ 3007} 3008 3009static int 3010bwn_init_locked(struct bwn_softc *sc) 3011{ 3012 struct bwn_mac *mac; 3013 struct ifnet *ifp = sc->sc_ifp; 3014 int error; 3015 3016 BWN_ASSERT_LOCKED(sc); 3017 3018 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3019 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3020 sc->sc_filters = 0; 3021 bwn_wme_clear(sc); 3022 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3023 sc->sc_rf_enabled = 1; 3024 3025 mac = sc->sc_curmac; 3026 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3027 error = bwn_core_init(mac); 3028 if (error != 0) 3029 return (error); 3030 } 3031 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3032 bwn_core_start(mac); 3033 3034 bwn_set_opmode(mac); 3035 bwn_set_pretbtt(mac); 3036 bwn_spu_setdelay(mac, 0); 3037 bwn_set_macaddr(mac); 3038 3039 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3040 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3041 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3042 3043 return (0); 3044} 3045 3046static void 3047bwn_stop(struct bwn_softc *sc, int statechg) 3048{ 3049 3050 BWN_LOCK(sc); 3051 bwn_stop_locked(sc, statechg); 3052 BWN_UNLOCK(sc); 3053} 3054 3055static void 3056bwn_stop_locked(struct bwn_softc *sc, int statechg) 3057{ 3058 struct bwn_mac *mac = sc->sc_curmac; 3059 struct ifnet *ifp = sc->sc_ifp; 3060 3061 BWN_ASSERT_LOCKED(sc); 3062 3063 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3064 /* XXX FIXME opmode not based on VAP */ 3065 bwn_set_opmode(mac); 3066 bwn_set_macaddr(mac); 3067 } 3068 3069 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3070 bwn_core_stop(mac); 3071 3072 callout_stop(&sc->sc_led_blink_ch); 3073 sc->sc_led_blinking = 0; 3074 3075 bwn_core_exit(mac); 3076 sc->sc_rf_enabled = 0; 3077 3078 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3079} 3080 3081static void 3082bwn_wme_clear(struct bwn_softc *sc) 3083{ 3084#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3085 struct wmeParams *p; 3086 unsigned int i; 3087 3088 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3089 ("%s:%d: fail", __func__, __LINE__)); 3090 3091 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3092 p = &(sc->sc_wmeParams[i]); 3093 3094 switch (bwn_wme_shm_offsets[i]) { 3095 case BWN_WME_VOICE: 3096 p->wmep_txopLimit = 0; 3097 p->wmep_aifsn = 2; 3098 /* XXX FIXME: log2(cwmin) */ 3099 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3100 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3101 break; 3102 case BWN_WME_VIDEO: 3103 p->wmep_txopLimit = 0; 3104 p->wmep_aifsn = 2; 3105 /* XXX FIXME: log2(cwmin) */ 3106 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3107 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3108 break; 3109 case BWN_WME_BESTEFFORT: 3110 p->wmep_txopLimit = 0; 3111 p->wmep_aifsn = 3; 3112 /* XXX FIXME: log2(cwmin) */ 3113 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3114 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3115 break; 3116 case BWN_WME_BACKGROUND: 3117 p->wmep_txopLimit = 0; 3118 p->wmep_aifsn = 7; 3119 /* XXX FIXME: log2(cwmin) */ 3120 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3121 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3122 break; 3123 default: 3124 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3125 } 3126 } 3127} 3128 3129static int 3130bwn_core_init(struct bwn_mac *mac) 3131{ 3132 struct bwn_softc *sc = mac->mac_sc; 3133 uint64_t hf; 3134 int error; 3135 3136 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3137 ("%s:%d: fail", __func__, __LINE__)); 3138 3139 siba_powerup(sc->sc_dev, 0); 3140 if (!siba_dev_isup(sc->sc_dev)) 3141 bwn_reset_core(mac, 3142 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3143 3144 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3145 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3146 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3147 BWN_GETTIME(mac->mac_phy.nexttime); 3148 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3149 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3150 mac->mac_stats.link_noise = -95; 3151 mac->mac_reason_intr = 0; 3152 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3153 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3154#ifdef BWN_DEBUG 3155 if (sc->sc_debug & BWN_DEBUG_XMIT) 3156 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3157#endif 3158 mac->mac_suspended = 1; 3159 mac->mac_task_state = 0; 3160 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3161 3162 mac->mac_phy.init_pre(mac); 3163 3164 siba_pcicore_intr(sc->sc_dev); 3165 3166 siba_fix_imcfglobug(sc->sc_dev); 3167 bwn_bt_disable(mac); 3168 if (mac->mac_phy.prepare_hw) { 3169 error = mac->mac_phy.prepare_hw(mac); 3170 if (error) 3171 goto fail0; 3172 } 3173 error = bwn_chip_init(mac); 3174 if (error) 3175 goto fail0; 3176 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3177 siba_get_revid(sc->sc_dev)); 3178 hf = bwn_hf_read(mac); 3179 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3180 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3181 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3182 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3183 if (mac->mac_phy.rev == 1) 3184 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3185 } 3186 if (mac->mac_phy.rf_ver == 0x2050) { 3187 if (mac->mac_phy.rf_rev < 6) 3188 hf |= BWN_HF_FORCE_VCO_RECALC; 3189 if (mac->mac_phy.rf_rev == 6) 3190 hf |= BWN_HF_4318_TSSI; 3191 } 3192 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3193 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3194 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3195 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3196 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3197 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3198 bwn_hf_write(mac, hf); 3199 3200 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3201 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3202 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3204 3205 bwn_rate_init(mac); 3206 bwn_set_phytxctl(mac); 3207 3208 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3209 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3211 3212 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3213 bwn_pio_init(mac); 3214 else 3215 bwn_dma_init(mac); 3216 if (error) 3217 goto fail1; 3218 bwn_wme_init(mac); 3219 bwn_spu_setdelay(mac, 1); 3220 bwn_bt_enable(mac); 3221 3222 siba_powerup(sc->sc_dev, 3223 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3224 bwn_set_macaddr(mac); 3225 bwn_crypt_init(mac); 3226 3227 /* XXX LED initializatin */ 3228 3229 mac->mac_status = BWN_MAC_STATUS_INITED; 3230 3231 return (error); 3232 3233fail1: 3234 bwn_chip_exit(mac); 3235fail0: 3236 siba_powerdown(sc->sc_dev); 3237 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3238 ("%s:%d: fail", __func__, __LINE__)); 3239 return (error); 3240} 3241 3242static void 3243bwn_core_start(struct bwn_mac *mac) 3244{ 3245 struct bwn_softc *sc = mac->mac_sc; 3246 uint32_t tmp; 3247 3248 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3249 ("%s:%d: fail", __func__, __LINE__)); 3250 3251 if (siba_get_revid(sc->sc_dev) < 5) 3252 return; 3253 3254 while (1) { 3255 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3256 if (!(tmp & 0x00000001)) 3257 break; 3258 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3259 } 3260 3261 bwn_mac_enable(mac); 3262 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3263 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3264 3265 mac->mac_status = BWN_MAC_STATUS_STARTED; 3266} 3267 3268static void 3269bwn_core_exit(struct bwn_mac *mac) 3270{ 3271 struct bwn_softc *sc = mac->mac_sc; 3272 uint32_t macctl; 3273 3274 BWN_ASSERT_LOCKED(mac->mac_sc); 3275 3276 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3277 ("%s:%d: fail", __func__, __LINE__)); 3278 3279 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3280 return; 3281 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3282 3283 macctl = BWN_READ_4(mac, BWN_MACCTL); 3284 macctl &= ~BWN_MACCTL_MCODE_RUN; 3285 macctl |= BWN_MACCTL_MCODE_JMP0; 3286 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3287 3288 bwn_dma_stop(mac); 3289 bwn_pio_stop(mac); 3290 bwn_chip_exit(mac); 3291 mac->mac_phy.switch_analog(mac, 0); 3292 siba_dev_down(sc->sc_dev, 0); 3293 siba_powerdown(sc->sc_dev); 3294} 3295 3296static void 3297bwn_bt_disable(struct bwn_mac *mac) 3298{ 3299 struct bwn_softc *sc = mac->mac_sc; 3300 3301 (void)sc; 3302 /* XXX do nothing yet */ 3303} 3304 3305static int 3306bwn_chip_init(struct bwn_mac *mac) 3307{ 3308 struct bwn_softc *sc = mac->mac_sc; 3309 struct bwn_phy *phy = &mac->mac_phy; 3310 uint32_t macctl; 3311 int error; 3312 3313 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3314 if (phy->gmode) 3315 macctl |= BWN_MACCTL_GMODE; 3316 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3317 3318 error = bwn_fw_fillinfo(mac); 3319 if (error) 3320 return (error); 3321 error = bwn_fw_loaducode(mac); 3322 if (error) 3323 return (error); 3324 3325 error = bwn_gpio_init(mac); 3326 if (error) 3327 return (error); 3328 3329 error = bwn_fw_loadinitvals(mac); 3330 if (error) { 3331 siba_gpio_set(sc->sc_dev, 0); 3332 return (error); 3333 } 3334 phy->switch_analog(mac, 1); 3335 error = bwn_phy_init(mac); 3336 if (error) { 3337 siba_gpio_set(sc->sc_dev, 0); 3338 return (error); 3339 } 3340 if (phy->set_im) 3341 phy->set_im(mac, BWN_IMMODE_NONE); 3342 if (phy->set_antenna) 3343 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3344 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3345 3346 if (phy->type == BWN_PHYTYPE_B) 3347 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3348 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3349 if (siba_get_revid(sc->sc_dev) < 5) 3350 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3351 3352 BWN_WRITE_4(mac, BWN_MACCTL, 3353 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3354 BWN_WRITE_4(mac, BWN_MACCTL, 3355 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3356 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3357 3358 bwn_set_opmode(mac); 3359 if (siba_get_revid(sc->sc_dev) < 3) { 3360 BWN_WRITE_2(mac, 0x060e, 0x0000); 3361 BWN_WRITE_2(mac, 0x0610, 0x8000); 3362 BWN_WRITE_2(mac, 0x0604, 0x0000); 3363 BWN_WRITE_2(mac, 0x0606, 0x0200); 3364 } else { 3365 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3366 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3367 } 3368 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3369 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3370 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3371 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3372 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3373 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3374 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3375 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3376 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3377 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3378 return (error); 3379} 3380 3381/* read hostflags */ 3382static uint64_t 3383bwn_hf_read(struct bwn_mac *mac) 3384{ 3385 uint64_t ret; 3386 3387 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3388 ret <<= 16; 3389 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3390 ret <<= 16; 3391 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3392 return (ret); 3393} 3394 3395static void 3396bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3397{ 3398 3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3400 (value & 0x00000000ffffull)); 3401 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3402 (value & 0x0000ffff0000ull) >> 16); 3403 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3404 (value & 0xffff00000000ULL) >> 32); 3405} 3406 3407static void 3408bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3409{ 3410 3411 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3412 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3413} 3414 3415static void 3416bwn_rate_init(struct bwn_mac *mac) 3417{ 3418 3419 switch (mac->mac_phy.type) { 3420 case BWN_PHYTYPE_A: 3421 case BWN_PHYTYPE_G: 3422 case BWN_PHYTYPE_LP: 3423 case BWN_PHYTYPE_N: 3424 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3425 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3427 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3428 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3429 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3430 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3431 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3432 break; 3433 /* FALLTHROUGH */ 3434 case BWN_PHYTYPE_B: 3435 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3436 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3437 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3438 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3439 break; 3440 default: 3441 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3442 } 3443} 3444 3445static void 3446bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3447{ 3448 uint16_t offset; 3449 3450 if (ofdm) { 3451 offset = 0x480; 3452 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3453 } else { 3454 offset = 0x4c0; 3455 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3456 } 3457 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3458 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3459} 3460 3461static uint8_t 3462bwn_plcp_getcck(const uint8_t bitrate) 3463{ 3464 3465 switch (bitrate) { 3466 case BWN_CCK_RATE_1MB: 3467 return (0x0a); 3468 case BWN_CCK_RATE_2MB: 3469 return (0x14); 3470 case BWN_CCK_RATE_5MB: 3471 return (0x37); 3472 case BWN_CCK_RATE_11MB: 3473 return (0x6e); 3474 } 3475 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3476 return (0); 3477} 3478 3479static uint8_t 3480bwn_plcp_getofdm(const uint8_t bitrate) 3481{ 3482 3483 switch (bitrate) { 3484 case BWN_OFDM_RATE_6MB: 3485 return (0xb); 3486 case BWN_OFDM_RATE_9MB: 3487 return (0xf); 3488 case BWN_OFDM_RATE_12MB: 3489 return (0xa); 3490 case BWN_OFDM_RATE_18MB: 3491 return (0xe); 3492 case BWN_OFDM_RATE_24MB: 3493 return (0x9); 3494 case BWN_OFDM_RATE_36MB: 3495 return (0xd); 3496 case BWN_OFDM_RATE_48MB: 3497 return (0x8); 3498 case BWN_OFDM_RATE_54MB: 3499 return (0xc); 3500 } 3501 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3502 return (0); 3503} 3504 3505static void 3506bwn_set_phytxctl(struct bwn_mac *mac) 3507{ 3508 uint16_t ctl; 3509 3510 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3511 BWN_TX_PHY_TXPWR); 3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3513 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3514 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3515} 3516 3517static void 3518bwn_pio_init(struct bwn_mac *mac) 3519{ 3520 struct bwn_pio *pio = &mac->mac_method.pio; 3521 3522 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3523 & ~BWN_MACCTL_BIGENDIAN); 3524 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3525 3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3528 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3529 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3530 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3531 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3532} 3533 3534static void 3535bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3536 int index) 3537{ 3538 struct bwn_pio_txpkt *tp; 3539 struct bwn_softc *sc = mac->mac_sc; 3540 unsigned int i; 3541 3542 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3543 tq->tq_index = index; 3544 3545 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3546 if (siba_get_revid(sc->sc_dev) >= 8) 3547 tq->tq_size = 1920; 3548 else { 3549 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3550 tq->tq_size -= 80; 3551 } 3552 3553 TAILQ_INIT(&tq->tq_pktlist); 3554 for (i = 0; i < N(tq->tq_pkts); i++) { 3555 tp = &(tq->tq_pkts[i]); 3556 tp->tp_index = i; 3557 tp->tp_queue = tq; 3558 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3559 } 3560} 3561 3562static uint16_t 3563bwn_pio_idx2base(struct bwn_mac *mac, int index) 3564{ 3565 struct bwn_softc *sc = mac->mac_sc; 3566 static const uint16_t bases[] = { 3567 BWN_PIO_BASE0, 3568 BWN_PIO_BASE1, 3569 BWN_PIO_BASE2, 3570 BWN_PIO_BASE3, 3571 BWN_PIO_BASE4, 3572 BWN_PIO_BASE5, 3573 BWN_PIO_BASE6, 3574 BWN_PIO_BASE7, 3575 }; 3576 static const uint16_t bases_rev11[] = { 3577 BWN_PIO11_BASE0, 3578 BWN_PIO11_BASE1, 3579 BWN_PIO11_BASE2, 3580 BWN_PIO11_BASE3, 3581 BWN_PIO11_BASE4, 3582 BWN_PIO11_BASE5, 3583 }; 3584 3585 if (siba_get_revid(sc->sc_dev) >= 11) { 3586 if (index >= N(bases_rev11)) 3587 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3588 return (bases_rev11[index]); 3589 } 3590 if (index >= N(bases)) 3591 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3592 return (bases[index]); 3593} 3594 3595static void 3596bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3597 int index) 3598{ 3599 struct bwn_softc *sc = mac->mac_sc; 3600 3601 prq->prq_mac = mac; 3602 prq->prq_rev = siba_get_revid(sc->sc_dev); 3603 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3604 bwn_dma_rxdirectfifo(mac, index, 1); 3605} 3606 3607static void 3608bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3609{ 3610 if (tq == NULL) 3611 return; 3612 bwn_pio_cancel_tx_packets(tq); 3613} 3614 3615static void 3616bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3617{ 3618 3619 bwn_destroy_pioqueue_tx(pio); 3620} 3621 3622static uint16_t 3623bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3624 uint16_t offset) 3625{ 3626 3627 return (BWN_READ_2(mac, tq->tq_base + offset)); 3628} 3629 3630static void 3631bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3632{ 3633 uint32_t ctl; 3634 int type; 3635 uint16_t base; 3636 3637 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3638 base = bwn_dma_base(type, idx); 3639 if (type == BWN_DMA_64BIT) { 3640 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3641 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3642 if (enable) 3643 ctl |= BWN_DMA64_RXDIRECTFIFO; 3644 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3645 } else { 3646 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3647 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3648 if (enable) 3649 ctl |= BWN_DMA32_RXDIRECTFIFO; 3650 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3651 } 3652} 3653 3654static uint64_t 3655bwn_dma_mask(struct bwn_mac *mac) 3656{ 3657 uint32_t tmp; 3658 uint16_t base; 3659 3660 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3661 if (tmp & SIBA_TGSHIGH_DMA64) 3662 return (BWN_DMA_BIT_MASK(64)); 3663 base = bwn_dma_base(0, 0); 3664 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3665 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3666 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3667 return (BWN_DMA_BIT_MASK(32)); 3668 3669 return (BWN_DMA_BIT_MASK(30)); 3670} 3671 3672static int 3673bwn_dma_mask2type(uint64_t dmamask) 3674{ 3675 3676 if (dmamask == BWN_DMA_BIT_MASK(30)) 3677 return (BWN_DMA_30BIT); 3678 if (dmamask == BWN_DMA_BIT_MASK(32)) 3679 return (BWN_DMA_32BIT); 3680 if (dmamask == BWN_DMA_BIT_MASK(64)) 3681 return (BWN_DMA_64BIT); 3682 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3683 return (BWN_DMA_30BIT); 3684} 3685 3686static void 3687bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3688{ 3689 struct bwn_pio_txpkt *tp; 3690 unsigned int i; 3691 3692 for (i = 0; i < N(tq->tq_pkts); i++) { 3693 tp = &(tq->tq_pkts[i]); 3694 if (tp->tp_m) { 3695 m_freem(tp->tp_m); 3696 tp->tp_m = NULL; 3697 } 3698 } 3699} 3700 3701static uint16_t 3702bwn_dma_base(int type, int controller_idx) 3703{ 3704 static const uint16_t map64[] = { 3705 BWN_DMA64_BASE0, 3706 BWN_DMA64_BASE1, 3707 BWN_DMA64_BASE2, 3708 BWN_DMA64_BASE3, 3709 BWN_DMA64_BASE4, 3710 BWN_DMA64_BASE5, 3711 }; 3712 static const uint16_t map32[] = { 3713 BWN_DMA32_BASE0, 3714 BWN_DMA32_BASE1, 3715 BWN_DMA32_BASE2, 3716 BWN_DMA32_BASE3, 3717 BWN_DMA32_BASE4, 3718 BWN_DMA32_BASE5, 3719 }; 3720 3721 if (type == BWN_DMA_64BIT) { 3722 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3723 ("%s:%d: fail", __func__, __LINE__)); 3724 return (map64[controller_idx]); 3725 } 3726 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3727 ("%s:%d: fail", __func__, __LINE__)); 3728 return (map32[controller_idx]); 3729} 3730 3731static void 3732bwn_dma_init(struct bwn_mac *mac) 3733{ 3734 struct bwn_dma *dma = &mac->mac_method.dma; 3735 3736 /* setup TX DMA channels. */ 3737 bwn_dma_setup(dma->wme[WME_AC_BK]); 3738 bwn_dma_setup(dma->wme[WME_AC_BE]); 3739 bwn_dma_setup(dma->wme[WME_AC_VI]); 3740 bwn_dma_setup(dma->wme[WME_AC_VO]); 3741 bwn_dma_setup(dma->mcast); 3742 /* setup RX DMA channel. */ 3743 bwn_dma_setup(dma->rx); 3744} 3745 3746static struct bwn_dma_ring * 3747bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3748 int for_tx, int type) 3749{ 3750 struct bwn_dma *dma = &mac->mac_method.dma; 3751 struct bwn_dma_ring *dr; 3752 struct bwn_dmadesc_generic *desc; 3753 struct bwn_dmadesc_meta *mt; 3754 struct bwn_softc *sc = mac->mac_sc; 3755 int error, i; 3756 3757 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3758 if (dr == NULL) 3759 goto out; 3760 dr->dr_numslots = BWN_RXRING_SLOTS; 3761 if (for_tx) 3762 dr->dr_numslots = BWN_TXRING_SLOTS; 3763 3764 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3765 M_DEVBUF, M_NOWAIT | M_ZERO); 3766 if (dr->dr_meta == NULL) 3767 goto fail0; 3768 3769 dr->dr_type = type; 3770 dr->dr_mac = mac; 3771 dr->dr_base = bwn_dma_base(type, controller_index); 3772 dr->dr_index = controller_index; 3773 if (type == BWN_DMA_64BIT) { 3774 dr->getdesc = bwn_dma_64_getdesc; 3775 dr->setdesc = bwn_dma_64_setdesc; 3776 dr->start_transfer = bwn_dma_64_start_transfer; 3777 dr->suspend = bwn_dma_64_suspend; 3778 dr->resume = bwn_dma_64_resume; 3779 dr->get_curslot = bwn_dma_64_get_curslot; 3780 dr->set_curslot = bwn_dma_64_set_curslot; 3781 } else { 3782 dr->getdesc = bwn_dma_32_getdesc; 3783 dr->setdesc = bwn_dma_32_setdesc; 3784 dr->start_transfer = bwn_dma_32_start_transfer; 3785 dr->suspend = bwn_dma_32_suspend; 3786 dr->resume = bwn_dma_32_resume; 3787 dr->get_curslot = bwn_dma_32_get_curslot; 3788 dr->set_curslot = bwn_dma_32_set_curslot; 3789 } 3790 if (for_tx) { 3791 dr->dr_tx = 1; 3792 dr->dr_curslot = -1; 3793 } else { 3794 if (dr->dr_index == 0) { 3795 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3796 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3797 } else 3798 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3799 } 3800 3801 error = bwn_dma_allocringmemory(dr); 3802 if (error) 3803 goto fail2; 3804 3805 if (for_tx) { 3806 /* 3807 * Assumption: BWN_TXRING_SLOTS can be divided by 3808 * BWN_TX_SLOTS_PER_FRAME 3809 */ 3810 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3811 ("%s:%d: fail", __func__, __LINE__)); 3812 3813 dr->dr_txhdr_cache = 3814 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3815 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3816 KASSERT(dr->dr_txhdr_cache != NULL, 3817 ("%s:%d: fail", __func__, __LINE__)); 3818 3819 /* 3820 * Create TX ring DMA stuffs 3821 */ 3822 error = bus_dma_tag_create(dma->parent_dtag, 3823 BWN_ALIGN, 0, 3824 BUS_SPACE_MAXADDR, 3825 BUS_SPACE_MAXADDR, 3826 NULL, NULL, 3827 BWN_HDRSIZE(mac), 3828 1, 3829 BUS_SPACE_MAXSIZE_32BIT, 3830 0, 3831 NULL, NULL, 3832 &dr->dr_txring_dtag); 3833 if (error) { 3834 device_printf(sc->sc_dev, 3835 "can't create TX ring DMA tag: TODO frees\n"); 3836 goto fail1; 3837 } 3838 3839 for (i = 0; i < dr->dr_numslots; i += 2) { 3840 dr->getdesc(dr, i, &desc, &mt); 3841 3842 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3843 mt->mt_m = NULL; 3844 mt->mt_ni = NULL; 3845 mt->mt_islast = 0; 3846 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3847 &mt->mt_dmap); 3848 if (error) { 3849 device_printf(sc->sc_dev, 3850 "can't create RX buf DMA map\n"); 3851 goto fail1; 3852 } 3853 3854 dr->getdesc(dr, i + 1, &desc, &mt); 3855 3856 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3857 mt->mt_m = NULL; 3858 mt->mt_ni = NULL; 3859 mt->mt_islast = 1; 3860 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3861 &mt->mt_dmap); 3862 if (error) { 3863 device_printf(sc->sc_dev, 3864 "can't create RX buf DMA map\n"); 3865 goto fail1; 3866 } 3867 } 3868 } else { 3869 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3870 &dr->dr_spare_dmap); 3871 if (error) { 3872 device_printf(sc->sc_dev, 3873 "can't create RX buf DMA map\n"); 3874 goto out; /* XXX wrong! */ 3875 } 3876 3877 for (i = 0; i < dr->dr_numslots; i++) { 3878 dr->getdesc(dr, i, &desc, &mt); 3879 3880 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3881 &mt->mt_dmap); 3882 if (error) { 3883 device_printf(sc->sc_dev, 3884 "can't create RX buf DMA map\n"); 3885 goto out; /* XXX wrong! */ 3886 } 3887 error = bwn_dma_newbuf(dr, desc, mt, 1); 3888 if (error) { 3889 device_printf(sc->sc_dev, 3890 "failed to allocate RX buf\n"); 3891 goto out; /* XXX wrong! */ 3892 } 3893 } 3894 3895 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3896 BUS_DMASYNC_PREWRITE); 3897 3898 dr->dr_usedslot = dr->dr_numslots; 3899 } 3900 3901 out: 3902 return (dr); 3903 3904fail2: 3905 free(dr->dr_txhdr_cache, M_DEVBUF); 3906fail1: 3907 free(dr->dr_meta, M_DEVBUF); 3908fail0: 3909 free(dr, M_DEVBUF); 3910 return (NULL); 3911} 3912 3913static void 3914bwn_dma_ringfree(struct bwn_dma_ring **dr) 3915{ 3916 3917 if (dr == NULL) 3918 return; 3919 3920 bwn_dma_free_descbufs(*dr); 3921 bwn_dma_free_ringmemory(*dr); 3922 3923 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3924 free((*dr)->dr_meta, M_DEVBUF); 3925 free(*dr, M_DEVBUF); 3926 3927 *dr = NULL; 3928} 3929 3930static void 3931bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3932 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3933{ 3934 struct bwn_dmadesc32 *desc; 3935 3936 *meta = &(dr->dr_meta[slot]); 3937 desc = dr->dr_ring_descbase; 3938 desc = &(desc[slot]); 3939 3940 *gdesc = (struct bwn_dmadesc_generic *)desc; 3941} 3942 3943static void 3944bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3945 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3946 int start, int end, int irq) 3947{ 3948 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3949 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3950 uint32_t addr, addrext, ctl; 3951 int slot; 3952 3953 slot = (int)(&(desc->dma.dma32) - descbase); 3954 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3955 ("%s:%d: fail", __func__, __LINE__)); 3956 3957 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3958 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3959 addr |= siba_dma_translation(sc->sc_dev); 3960 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3961 if (slot == dr->dr_numslots - 1) 3962 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3963 if (start) 3964 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3965 if (end) 3966 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3967 if (irq) 3968 ctl |= BWN_DMA32_DCTL_IRQ; 3969 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3970 & BWN_DMA32_DCTL_ADDREXT_MASK; 3971 3972 desc->dma.dma32.control = htole32(ctl); 3973 desc->dma.dma32.address = htole32(addr); 3974} 3975 3976static void 3977bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3978{ 3979 3980 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3981 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3982} 3983 3984static void 3985bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3986{ 3987 3988 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3989 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3990} 3991 3992static void 3993bwn_dma_32_resume(struct bwn_dma_ring *dr) 3994{ 3995 3996 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3997 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3998} 3999 4000static int 4001bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4002{ 4003 uint32_t val; 4004 4005 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4006 val &= BWN_DMA32_RXDPTR; 4007 4008 return (val / sizeof(struct bwn_dmadesc32)); 4009} 4010 4011static void 4012bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4013{ 4014 4015 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4016 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4017} 4018 4019static void 4020bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4021 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4022{ 4023 struct bwn_dmadesc64 *desc; 4024 4025 *meta = &(dr->dr_meta[slot]); 4026 desc = dr->dr_ring_descbase; 4027 desc = &(desc[slot]); 4028 4029 *gdesc = (struct bwn_dmadesc_generic *)desc; 4030} 4031 4032static void 4033bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4034 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4035 int start, int end, int irq) 4036{ 4037 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4038 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4039 int slot; 4040 uint32_t ctl0 = 0, ctl1 = 0; 4041 uint32_t addrlo, addrhi; 4042 uint32_t addrext; 4043 4044 slot = (int)(&(desc->dma.dma64) - descbase); 4045 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4046 ("%s:%d: fail", __func__, __LINE__)); 4047 4048 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4049 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4050 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4051 30; 4052 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4053 if (slot == dr->dr_numslots - 1) 4054 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4055 if (start) 4056 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4057 if (end) 4058 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4059 if (irq) 4060 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4061 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4062 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4063 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4064 4065 desc->dma.dma64.control0 = htole32(ctl0); 4066 desc->dma.dma64.control1 = htole32(ctl1); 4067 desc->dma.dma64.address_low = htole32(addrlo); 4068 desc->dma.dma64.address_high = htole32(addrhi); 4069} 4070 4071static void 4072bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4073{ 4074 4075 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4076 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4077} 4078 4079static void 4080bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4081{ 4082 4083 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4084 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4085} 4086 4087static void 4088bwn_dma_64_resume(struct bwn_dma_ring *dr) 4089{ 4090 4091 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4092 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4093} 4094 4095static int 4096bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4097{ 4098 uint32_t val; 4099 4100 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4101 val &= BWN_DMA64_RXSTATDPTR; 4102 4103 return (val / sizeof(struct bwn_dmadesc64)); 4104} 4105 4106static void 4107bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4108{ 4109 4110 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4111 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4112} 4113 4114static int 4115bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4116{ 4117 struct bwn_mac *mac = dr->dr_mac; 4118 struct bwn_dma *dma = &mac->mac_method.dma; 4119 struct bwn_softc *sc = mac->mac_sc; 4120 int error; 4121 4122 error = bus_dma_tag_create(dma->parent_dtag, 4123 BWN_ALIGN, 0, 4124 BUS_SPACE_MAXADDR, 4125 BUS_SPACE_MAXADDR, 4126 NULL, NULL, 4127 BWN_DMA_RINGMEMSIZE, 4128 1, 4129 BUS_SPACE_MAXSIZE_32BIT, 4130 0, 4131 NULL, NULL, 4132 &dr->dr_ring_dtag); 4133 if (error) { 4134 device_printf(sc->sc_dev, 4135 "can't create TX ring DMA tag: TODO frees\n"); 4136 return (-1); 4137 } 4138 4139 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4140 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4141 &dr->dr_ring_dmap); 4142 if (error) { 4143 device_printf(sc->sc_dev, 4144 "can't allocate DMA mem: TODO frees\n"); 4145 return (-1); 4146 } 4147 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4148 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4149 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4150 if (error) { 4151 device_printf(sc->sc_dev, 4152 "can't load DMA mem: TODO free\n"); 4153 return (-1); 4154 } 4155 4156 return (0); 4157} 4158 4159static void 4160bwn_dma_setup(struct bwn_dma_ring *dr) 4161{ 4162 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4163 uint64_t ring64; 4164 uint32_t addrext, ring32, value; 4165 uint32_t trans = siba_dma_translation(sc->sc_dev); 4166 4167 if (dr->dr_tx) { 4168 dr->dr_curslot = -1; 4169 4170 if (dr->dr_type == BWN_DMA_64BIT) { 4171 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4172 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4173 >> 30; 4174 value = BWN_DMA64_TXENABLE; 4175 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4176 & BWN_DMA64_TXADDREXT_MASK; 4177 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4179 (ring64 & 0xffffffff)); 4180 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4181 ((ring64 >> 32) & 4182 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4183 } else { 4184 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4185 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4186 value = BWN_DMA32_TXENABLE; 4187 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4188 & BWN_DMA32_TXADDREXT_MASK; 4189 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4190 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4191 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4192 } 4193 return; 4194 } 4195 4196 /* 4197 * set for RX 4198 */ 4199 dr->dr_usedslot = dr->dr_numslots; 4200 4201 if (dr->dr_type == BWN_DMA_64BIT) { 4202 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4203 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4204 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4205 value |= BWN_DMA64_RXENABLE; 4206 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4207 & BWN_DMA64_RXADDREXT_MASK; 4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4210 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4211 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4212 | (trans << 1)); 4213 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4214 sizeof(struct bwn_dmadesc64)); 4215 } else { 4216 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4217 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4218 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4219 value |= BWN_DMA32_RXENABLE; 4220 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4221 & BWN_DMA32_RXADDREXT_MASK; 4222 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4224 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4225 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4226 sizeof(struct bwn_dmadesc32)); 4227 } 4228} 4229 4230static void 4231bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4232{ 4233 4234 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4235 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4236 dr->dr_ring_dmap); 4237} 4238 4239static void 4240bwn_dma_cleanup(struct bwn_dma_ring *dr) 4241{ 4242 4243 if (dr->dr_tx) { 4244 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4245 if (dr->dr_type == BWN_DMA_64BIT) { 4246 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4247 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4248 } else 4249 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4250 } else { 4251 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4252 if (dr->dr_type == BWN_DMA_64BIT) { 4253 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4254 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4255 } else 4256 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4257 } 4258} 4259 4260static void 4261bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4262{ 4263 struct bwn_dmadesc_generic *desc; 4264 struct bwn_dmadesc_meta *meta; 4265 struct bwn_mac *mac = dr->dr_mac; 4266 struct bwn_dma *dma = &mac->mac_method.dma; 4267 struct bwn_softc *sc = mac->mac_sc; 4268 int i; 4269 4270 if (!dr->dr_usedslot) 4271 return; 4272 for (i = 0; i < dr->dr_numslots; i++) { 4273 dr->getdesc(dr, i, &desc, &meta); 4274 4275 if (meta->mt_m == NULL) { 4276 if (!dr->dr_tx) 4277 device_printf(sc->sc_dev, "%s: not TX?\n", 4278 __func__); 4279 continue; 4280 } 4281 if (dr->dr_tx) { 4282 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4283 bus_dmamap_unload(dr->dr_txring_dtag, 4284 meta->mt_dmap); 4285 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4286 bus_dmamap_unload(dma->txbuf_dtag, 4287 meta->mt_dmap); 4288 } else 4289 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4290 bwn_dma_free_descbuf(dr, meta); 4291 } 4292} 4293 4294static int 4295bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4296 int type) 4297{ 4298 struct bwn_softc *sc = mac->mac_sc; 4299 uint32_t value; 4300 int i; 4301 uint16_t offset; 4302 4303 for (i = 0; i < 10; i++) { 4304 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4305 BWN_DMA32_TXSTATUS; 4306 value = BWN_READ_4(mac, base + offset); 4307 if (type == BWN_DMA_64BIT) { 4308 value &= BWN_DMA64_TXSTAT; 4309 if (value == BWN_DMA64_TXSTAT_DISABLED || 4310 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4311 value == BWN_DMA64_TXSTAT_STOPPED) 4312 break; 4313 } else { 4314 value &= BWN_DMA32_TXSTATE; 4315 if (value == BWN_DMA32_TXSTAT_DISABLED || 4316 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4317 value == BWN_DMA32_TXSTAT_STOPPED) 4318 break; 4319 } 4320 DELAY(1000); 4321 } 4322 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4323 BWN_WRITE_4(mac, base + offset, 0); 4324 for (i = 0; i < 10; i++) { 4325 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4326 BWN_DMA32_TXSTATUS; 4327 value = BWN_READ_4(mac, base + offset); 4328 if (type == BWN_DMA_64BIT) { 4329 value &= BWN_DMA64_TXSTAT; 4330 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4331 i = -1; 4332 break; 4333 } 4334 } else { 4335 value &= BWN_DMA32_TXSTATE; 4336 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4337 i = -1; 4338 break; 4339 } 4340 } 4341 DELAY(1000); 4342 } 4343 if (i != -1) { 4344 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4345 return (ENODEV); 4346 } 4347 DELAY(1000); 4348 4349 return (0); 4350} 4351 4352static int 4353bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4354 int type) 4355{ 4356 struct bwn_softc *sc = mac->mac_sc; 4357 uint32_t value; 4358 int i; 4359 uint16_t offset; 4360 4361 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4362 BWN_WRITE_4(mac, base + offset, 0); 4363 for (i = 0; i < 10; i++) { 4364 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4365 BWN_DMA32_RXSTATUS; 4366 value = BWN_READ_4(mac, base + offset); 4367 if (type == BWN_DMA_64BIT) { 4368 value &= BWN_DMA64_RXSTAT; 4369 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4370 i = -1; 4371 break; 4372 } 4373 } else { 4374 value &= BWN_DMA32_RXSTATE; 4375 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4376 i = -1; 4377 break; 4378 } 4379 } 4380 DELAY(1000); 4381 } 4382 if (i != -1) { 4383 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4384 return (ENODEV); 4385 } 4386 4387 return (0); 4388} 4389 4390static void 4391bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4392 struct bwn_dmadesc_meta *meta) 4393{ 4394 4395 if (meta->mt_m != NULL) { 4396 m_freem(meta->mt_m); 4397 meta->mt_m = NULL; 4398 } 4399 if (meta->mt_ni != NULL) { 4400 ieee80211_free_node(meta->mt_ni); 4401 meta->mt_ni = NULL; 4402 } 4403} 4404 4405static void 4406bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4407{ 4408 struct bwn_rxhdr4 *rxhdr; 4409 unsigned char *frame; 4410 4411 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4412 rxhdr->frame_len = 0; 4413 4414 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4415 sizeof(struct bwn_plcp6) + 2, 4416 ("%s:%d: fail", __func__, __LINE__)); 4417 frame = mtod(m, char *) + dr->dr_frameoffset; 4418 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4419} 4420 4421static uint8_t 4422bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4423{ 4424 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4425 4426 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4427 == 0xff); 4428} 4429 4430static void 4431bwn_wme_init(struct bwn_mac *mac) 4432{ 4433 4434 bwn_wme_load(mac); 4435 4436 /* enable WME support. */ 4437 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4438 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4439 BWN_IFSCTL_USE_EDCF); 4440} 4441 4442static void 4443bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4444{ 4445 struct bwn_softc *sc = mac->mac_sc; 4446 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4447 uint16_t delay; /* microsec */ 4448 4449 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4450 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4451 delay = 500; 4452 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4453 delay = max(delay, (uint16_t)2400); 4454 4455 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4456} 4457 4458static void 4459bwn_bt_enable(struct bwn_mac *mac) 4460{ 4461 struct bwn_softc *sc = mac->mac_sc; 4462 uint64_t hf; 4463 4464 if (bwn_bluetooth == 0) 4465 return; 4466 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4467 return; 4468 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4469 return; 4470 4471 hf = bwn_hf_read(mac); 4472 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4473 hf |= BWN_HF_BT_COEXISTALT; 4474 else 4475 hf |= BWN_HF_BT_COEXIST; 4476 bwn_hf_write(mac, hf); 4477} 4478 4479static void 4480bwn_set_macaddr(struct bwn_mac *mac) 4481{ 4482 4483 bwn_mac_write_bssid(mac); 4484 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4485} 4486 4487static void 4488bwn_clear_keys(struct bwn_mac *mac) 4489{ 4490 int i; 4491 4492 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4493 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4494 ("%s:%d: fail", __func__, __LINE__)); 4495 4496 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4497 NULL, BWN_SEC_KEYSIZE, NULL); 4498 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4499 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4500 NULL, BWN_SEC_KEYSIZE, NULL); 4501 } 4502 mac->mac_key[i].keyconf = NULL; 4503 } 4504} 4505 4506static void 4507bwn_crypt_init(struct bwn_mac *mac) 4508{ 4509 struct bwn_softc *sc = mac->mac_sc; 4510 4511 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4512 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4513 ("%s:%d: fail", __func__, __LINE__)); 4514 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4515 mac->mac_ktp *= 2; 4516 if (siba_get_revid(sc->sc_dev) >= 5) 4517 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4518 bwn_clear_keys(mac); 4519} 4520 4521static void 4522bwn_chip_exit(struct bwn_mac *mac) 4523{ 4524 struct bwn_softc *sc = mac->mac_sc; 4525 4526 bwn_phy_exit(mac); 4527 siba_gpio_set(sc->sc_dev, 0); 4528} 4529 4530static int 4531bwn_fw_fillinfo(struct bwn_mac *mac) 4532{ 4533 int error; 4534 4535 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4536 if (error == 0) 4537 return (0); 4538 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4539 if (error == 0) 4540 return (0); 4541 return (error); 4542} 4543 4544static int 4545bwn_gpio_init(struct bwn_mac *mac) 4546{ 4547 struct bwn_softc *sc = mac->mac_sc; 4548 uint32_t mask = 0x1f, set = 0xf, value; 4549 4550 BWN_WRITE_4(mac, BWN_MACCTL, 4551 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4552 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4553 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4554 4555 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4556 mask |= 0x0060; 4557 set |= 0x0060; 4558 } 4559 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4560 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4561 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4562 mask |= 0x0200; 4563 set |= 0x0200; 4564 } 4565 if (siba_get_revid(sc->sc_dev) >= 2) 4566 mask |= 0x0010; 4567 4568 value = siba_gpio_get(sc->sc_dev); 4569 if (value == -1) 4570 return (0); 4571 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4572 4573 return (0); 4574} 4575 4576static int 4577bwn_fw_loadinitvals(struct bwn_mac *mac) 4578{ 4579#define GETFWOFFSET(fwp, offset) \ 4580 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4581 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4582 const struct bwn_fwhdr *hdr; 4583 struct bwn_fw *fw = &mac->mac_fw; 4584 int error; 4585 4586 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4587 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4588 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4589 if (error) 4590 return (error); 4591 if (fw->initvals_band.fw) { 4592 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4593 error = bwn_fwinitvals_write(mac, 4594 GETFWOFFSET(fw->initvals_band, hdr_len), 4595 be32toh(hdr->size), 4596 fw->initvals_band.fw->datasize - hdr_len); 4597 } 4598 return (error); 4599#undef GETFWOFFSET 4600} 4601 4602static int 4603bwn_phy_init(struct bwn_mac *mac) 4604{ 4605 struct bwn_softc *sc = mac->mac_sc; 4606 int error; 4607 4608 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4609 mac->mac_phy.rf_onoff(mac, 1); 4610 error = mac->mac_phy.init(mac); 4611 if (error) { 4612 device_printf(sc->sc_dev, "PHY init failed\n"); 4613 goto fail0; 4614 } 4615 error = bwn_switch_channel(mac, 4616 mac->mac_phy.get_default_chan(mac)); 4617 if (error) { 4618 device_printf(sc->sc_dev, 4619 "failed to switch default channel\n"); 4620 goto fail1; 4621 } 4622 return (0); 4623fail1: 4624 if (mac->mac_phy.exit) 4625 mac->mac_phy.exit(mac); 4626fail0: 4627 mac->mac_phy.rf_onoff(mac, 0); 4628 4629 return (error); 4630} 4631 4632static void 4633bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4634{ 4635 uint16_t ant; 4636 uint16_t tmp; 4637 4638 ant = bwn_ant2phy(antenna); 4639 4640 /* For ACK/CTS */ 4641 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4642 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4643 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4644 /* For Probe Resposes */ 4645 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4646 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4647 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4648} 4649 4650static void 4651bwn_set_opmode(struct bwn_mac *mac) 4652{ 4653 struct bwn_softc *sc = mac->mac_sc; 4654 struct ifnet *ifp = sc->sc_ifp; 4655 struct ieee80211com *ic = ifp->if_l2com; 4656 uint32_t ctl; 4657 uint16_t cfp_pretbtt; 4658 4659 ctl = BWN_READ_4(mac, BWN_MACCTL); 4660 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4661 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4662 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4663 ctl |= BWN_MACCTL_STA; 4664 4665 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4666 ic->ic_opmode == IEEE80211_M_MBSS) 4667 ctl |= BWN_MACCTL_HOSTAP; 4668 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4669 ctl &= ~BWN_MACCTL_STA; 4670 ctl |= sc->sc_filters; 4671 4672 if (siba_get_revid(sc->sc_dev) <= 4) 4673 ctl |= BWN_MACCTL_PROMISC; 4674 4675 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4676 4677 cfp_pretbtt = 2; 4678 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4679 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4680 siba_get_chiprev(sc->sc_dev) == 3) 4681 cfp_pretbtt = 100; 4682 else 4683 cfp_pretbtt = 50; 4684 } 4685 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4686} 4687 4688static int 4689bwn_dma_gettype(struct bwn_mac *mac) 4690{ 4691 uint32_t tmp; 4692 uint16_t base; 4693 4694 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4695 if (tmp & SIBA_TGSHIGH_DMA64) 4696 return (BWN_DMA_64BIT); 4697 base = bwn_dma_base(0, 0); 4698 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4699 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4700 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4701 return (BWN_DMA_32BIT); 4702 4703 return (BWN_DMA_30BIT); 4704} 4705 4706static void 4707bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4708{ 4709 if (!error) { 4710 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4711 *((bus_addr_t *)arg) = seg->ds_addr; 4712 } 4713} 4714 4715static void 4716bwn_phy_g_init_sub(struct bwn_mac *mac) 4717{ 4718 struct bwn_phy *phy = &mac->mac_phy; 4719 struct bwn_phy_g *pg = &phy->phy_g; 4720 struct bwn_softc *sc = mac->mac_sc; 4721 uint16_t i, tmp; 4722 4723 if (phy->rev == 1) 4724 bwn_phy_init_b5(mac); 4725 else 4726 bwn_phy_init_b6(mac); 4727 4728 if (phy->rev >= 2 || phy->gmode) 4729 bwn_phy_init_a(mac); 4730 4731 if (phy->rev >= 2) { 4732 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4733 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4734 } 4735 if (phy->rev == 2) { 4736 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4737 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4738 } 4739 if (phy->rev > 5) { 4740 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4741 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4742 } 4743 if (phy->gmode || phy->rev >= 2) { 4744 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4745 tmp &= BWN_PHYVER_VERSION; 4746 if (tmp == 3 || tmp == 5) { 4747 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4748 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4749 } 4750 if (tmp == 5) { 4751 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4752 0x1f00); 4753 } 4754 } 4755 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4756 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4757 if (phy->rf_rev == 8) { 4758 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4759 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4760 } 4761 if (BWN_HAS_LOOPBACK(phy)) 4762 bwn_loopback_calcgain(mac); 4763 4764 if (phy->rf_rev != 8) { 4765 if (pg->pg_initval == 0xffff) 4766 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4767 else 4768 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4769 } 4770 bwn_lo_g_init(mac); 4771 if (BWN_HAS_TXMAG(phy)) { 4772 BWN_RF_WRITE(mac, 0x52, 4773 (BWN_RF_READ(mac, 0x52) & 0xff00) 4774 | pg->pg_loctl.tx_bias | 4775 pg->pg_loctl.tx_magn); 4776 } else { 4777 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4778 } 4779 if (phy->rev >= 6) { 4780 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4781 (pg->pg_loctl.tx_bias << 12)); 4782 } 4783 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4785 else 4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4787 if (phy->rev < 2) 4788 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4789 else 4790 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4791 if (phy->gmode || phy->rev >= 2) { 4792 bwn_lo_g_adjust(mac); 4793 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4794 } 4795 4796 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4797 for (i = 0; i < 64; i++) { 4798 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4799 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4800 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4801 -32), 31)); 4802 } 4803 bwn_nrssi_threshold(mac); 4804 } else if (phy->gmode || phy->rev >= 2) { 4805 if (pg->pg_nrssi[0] == -1000) { 4806 KASSERT(pg->pg_nrssi[1] == -1000, 4807 ("%s:%d: fail", __func__, __LINE__)); 4808 bwn_nrssi_slope_11g(mac); 4809 } else 4810 bwn_nrssi_threshold(mac); 4811 } 4812 if (phy->rf_rev == 8) 4813 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4814 bwn_phy_hwpctl_init(mac); 4815 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4816 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4817 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4818 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4819 } 4820} 4821 4822static uint8_t 4823bwn_has_hwpctl(struct bwn_mac *mac) 4824{ 4825 4826 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4827 return (0); 4828 return (mac->mac_phy.use_hwpctl(mac)); 4829} 4830 4831static void 4832bwn_phy_init_b5(struct bwn_mac *mac) 4833{ 4834 struct bwn_phy *phy = &mac->mac_phy; 4835 struct bwn_phy_g *pg = &phy->phy_g; 4836 struct bwn_softc *sc = mac->mac_sc; 4837 uint16_t offset, value; 4838 uint8_t old_channel; 4839 4840 if (phy->analog == 1) 4841 BWN_RF_SET(mac, 0x007a, 0x0050); 4842 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4843 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4844 value = 0x2120; 4845 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4846 BWN_PHY_WRITE(mac, offset, value); 4847 value += 0x202; 4848 } 4849 } 4850 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4851 if (phy->rf_ver == 0x2050) 4852 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4853 4854 if (phy->gmode || phy->rev >= 2) { 4855 if (phy->rf_ver == 0x2050) { 4856 BWN_RF_SET(mac, 0x007a, 0x0020); 4857 BWN_RF_SET(mac, 0x0051, 0x0004); 4858 } 4859 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4860 4861 BWN_PHY_SET(mac, 0x0802, 0x0100); 4862 BWN_PHY_SET(mac, 0x042b, 0x2000); 4863 4864 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4865 4866 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4867 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4868 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4869 } 4870 4871 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4872 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4873 4874 if (phy->analog == 1) { 4875 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4876 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4877 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4878 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4879 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4880 } else 4881 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4882 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4883 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4884 4885 if (phy->analog == 1) 4886 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4887 else 4888 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4889 4890 if (phy->analog == 0) 4891 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4892 4893 old_channel = phy->chan; 4894 bwn_phy_g_switch_chan(mac, 7, 0); 4895 4896 if (phy->rf_ver != 0x2050) { 4897 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4898 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4899 } 4900 4901 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4902 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4903 4904 if (phy->rf_ver == 0x2050) { 4905 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4906 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4907 } 4908 4909 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4910 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4911 BWN_RF_SET(mac, 0x007a, 0x0007); 4912 4913 bwn_phy_g_switch_chan(mac, old_channel, 0); 4914 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4915 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4916 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4917 4918 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4919 pg->pg_txctl); 4920 4921 if (phy->rf_ver == 0x2050) 4922 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4923 4924 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4925} 4926 4927static void 4928bwn_loopback_calcgain(struct bwn_mac *mac) 4929{ 4930 struct bwn_phy *phy = &mac->mac_phy; 4931 struct bwn_phy_g *pg = &phy->phy_g; 4932 struct bwn_softc *sc = mac->mac_sc; 4933 uint16_t backup_phy[16] = { 0 }; 4934 uint16_t backup_radio[3]; 4935 uint16_t backup_bband; 4936 uint16_t i, j, loop_i_max; 4937 uint16_t trsw_rx; 4938 uint16_t loop1_outer_done, loop1_inner_done; 4939 4940 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4941 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4942 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4943 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4944 if (phy->rev != 1) { 4945 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4946 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4947 } 4948 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4949 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4950 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4951 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4952 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4953 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4954 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4955 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4956 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4957 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4958 backup_bband = pg->pg_bbatt.att; 4959 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4960 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4961 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4962 4963 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4964 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4965 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4966 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4967 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4968 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4969 if (phy->rev != 1) { 4970 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4971 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4972 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4973 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4974 } 4975 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4976 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4977 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4978 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4979 4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4981 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4982 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4983 4984 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4985 if (phy->rev != 1) { 4986 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4987 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4988 } 4989 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4990 4991 if (phy->rf_rev == 8) 4992 BWN_RF_WRITE(mac, 0x43, 0x000f); 4993 else { 4994 BWN_RF_WRITE(mac, 0x52, 0); 4995 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4996 } 4997 bwn_phy_g_set_bbatt(mac, 11); 4998 4999 if (phy->rev >= 3) 5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5001 else 5002 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5003 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5004 5005 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5006 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5007 5008 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5009 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5010 5011 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5012 if (phy->rev >= 7) { 5013 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5014 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5015 } 5016 } 5017 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5018 5019 j = 0; 5020 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5021 for (i = 0; i < loop_i_max; i++) { 5022 for (j = 0; j < 16; j++) { 5023 BWN_RF_WRITE(mac, 0x43, i); 5024 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5025 (j << 8)); 5026 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5027 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5028 DELAY(20); 5029 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5030 goto done0; 5031 } 5032 } 5033done0: 5034 loop1_outer_done = i; 5035 loop1_inner_done = j; 5036 if (j >= 8) { 5037 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5038 trsw_rx = 0x1b; 5039 for (j = j - 8; j < 16; j++) { 5040 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5041 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5042 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5043 DELAY(20); 5044 trsw_rx -= 3; 5045 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5046 goto done1; 5047 } 5048 } else 5049 trsw_rx = 0x18; 5050done1: 5051 5052 if (phy->rev != 1) { 5053 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5054 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5055 } 5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5061 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5062 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5063 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5064 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5065 5066 bwn_phy_g_set_bbatt(mac, backup_bband); 5067 5068 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5069 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5070 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5071 5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5073 DELAY(10); 5074 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5075 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5076 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5077 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5078 5079 pg->pg_max_lb_gain = 5080 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5081 pg->pg_trsw_rx_gain = trsw_rx * 2; 5082} 5083 5084static uint16_t 5085bwn_rf_init_bcm2050(struct bwn_mac *mac) 5086{ 5087 struct bwn_phy *phy = &mac->mac_phy; 5088 uint32_t tmp1 = 0, tmp2 = 0; 5089 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5090 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5091 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5092 static const uint8_t rcc_table[] = { 5093 0x02, 0x03, 0x01, 0x0f, 5094 0x06, 0x07, 0x05, 0x0f, 5095 0x0a, 0x0b, 0x09, 0x0f, 5096 0x0e, 0x0f, 0x0d, 0x0f, 5097 }; 5098 5099 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5100 rfoverval = rfover = cck3 = 0; 5101 radio0 = BWN_RF_READ(mac, 0x43); 5102 radio1 = BWN_RF_READ(mac, 0x51); 5103 radio2 = BWN_RF_READ(mac, 0x52); 5104 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5105 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5106 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5107 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5108 5109 if (phy->type == BWN_PHYTYPE_B) { 5110 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5111 reg0 = BWN_READ_2(mac, 0x3ec); 5112 5113 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5114 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5115 } else if (phy->gmode || phy->rev >= 2) { 5116 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5117 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5118 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5119 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5120 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5121 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5122 5123 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5124 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5125 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5126 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5127 if (BWN_HAS_LOOPBACK(phy)) { 5128 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5129 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5130 if (phy->rev >= 3) 5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5132 else 5133 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5134 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5135 } 5136 5137 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5138 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5139 BWN_LPD(0, 1, 1))); 5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5141 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5142 } 5143 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5144 5145 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5146 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5147 reg1 = BWN_READ_2(mac, 0x3e6); 5148 reg2 = BWN_READ_2(mac, 0x3f4); 5149 5150 if (phy->analog == 0) 5151 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5152 else { 5153 if (phy->analog >= 2) 5154 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5155 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5156 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5157 } 5158 5159 reg = BWN_RF_READ(mac, 0x60); 5160 index = (reg & 0x001e) >> 1; 5161 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5162 5163 if (phy->type == BWN_PHYTYPE_B) 5164 BWN_RF_WRITE(mac, 0x78, 0x26); 5165 if (phy->gmode || phy->rev >= 2) { 5166 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5167 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5168 BWN_LPD(0, 1, 1))); 5169 } 5170 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5171 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5172 if (phy->gmode || phy->rev >= 2) { 5173 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5174 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5175 BWN_LPD(0, 0, 1))); 5176 } 5177 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5178 BWN_RF_SET(mac, 0x51, 0x0004); 5179 if (phy->rf_rev == 8) 5180 BWN_RF_WRITE(mac, 0x43, 0x1f); 5181 else { 5182 BWN_RF_WRITE(mac, 0x52, 0); 5183 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5184 } 5185 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5186 5187 for (i = 0; i < 16; i++) { 5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5191 if (phy->gmode || phy->rev >= 2) { 5192 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5193 bwn_rf_2050_rfoverval(mac, 5194 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5195 } 5196 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5197 DELAY(10); 5198 if (phy->gmode || phy->rev >= 2) { 5199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5200 bwn_rf_2050_rfoverval(mac, 5201 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5202 } 5203 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5204 DELAY(10); 5205 if (phy->gmode || phy->rev >= 2) { 5206 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5207 bwn_rf_2050_rfoverval(mac, 5208 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5209 } 5210 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5211 DELAY(20); 5212 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5213 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5214 if (phy->gmode || phy->rev >= 2) { 5215 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5216 bwn_rf_2050_rfoverval(mac, 5217 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5218 } 5219 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5220 } 5221 DELAY(10); 5222 5223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5224 tmp1++; 5225 tmp1 >>= 9; 5226 5227 for (i = 0; i < 16; i++) { 5228 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5229 BWN_RF_WRITE(mac, 0x78, radio78); 5230 DELAY(10); 5231 for (j = 0; j < 16; j++) { 5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5233 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5234 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5235 if (phy->gmode || phy->rev >= 2) { 5236 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5237 bwn_rf_2050_rfoverval(mac, 5238 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5239 } 5240 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5241 DELAY(10); 5242 if (phy->gmode || phy->rev >= 2) { 5243 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5244 bwn_rf_2050_rfoverval(mac, 5245 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5246 } 5247 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5248 DELAY(10); 5249 if (phy->gmode || phy->rev >= 2) { 5250 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5251 bwn_rf_2050_rfoverval(mac, 5252 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5253 } 5254 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5255 DELAY(10); 5256 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5257 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5258 if (phy->gmode || phy->rev >= 2) { 5259 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5260 bwn_rf_2050_rfoverval(mac, 5261 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5262 } 5263 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5264 } 5265 tmp2++; 5266 tmp2 >>= 8; 5267 if (tmp1 < tmp2) 5268 break; 5269 } 5270 5271 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5272 BWN_RF_WRITE(mac, 0x51, radio1); 5273 BWN_RF_WRITE(mac, 0x52, radio2); 5274 BWN_RF_WRITE(mac, 0x43, radio0); 5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5277 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5278 BWN_WRITE_2(mac, 0x3e6, reg1); 5279 if (phy->analog != 0) 5280 BWN_WRITE_2(mac, 0x3f4, reg2); 5281 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5282 bwn_spu_workaround(mac, phy->chan); 5283 if (phy->type == BWN_PHYTYPE_B) { 5284 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5285 BWN_WRITE_2(mac, 0x3ec, reg0); 5286 } else if (phy->gmode) { 5287 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5288 BWN_READ_2(mac, BWN_PHY_RADIO) 5289 & 0x7fff); 5290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5291 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5292 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5293 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5294 analogoverval); 5295 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5296 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5297 if (BWN_HAS_LOOPBACK(phy)) { 5298 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5299 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5300 } 5301 } 5302 5303 return ((i > 15) ? radio78 : rcc); 5304} 5305 5306static void 5307bwn_phy_init_b6(struct bwn_mac *mac) 5308{ 5309 struct bwn_phy *phy = &mac->mac_phy; 5310 struct bwn_phy_g *pg = &phy->phy_g; 5311 struct bwn_softc *sc = mac->mac_sc; 5312 uint16_t offset, val; 5313 uint8_t old_channel; 5314 5315 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5316 ("%s:%d: fail", __func__, __LINE__)); 5317 5318 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5319 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5320 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5321 BWN_RF_WRITE(mac, 0x51, 0x37); 5322 BWN_RF_WRITE(mac, 0x52, 0x70); 5323 BWN_RF_WRITE(mac, 0x53, 0xb3); 5324 BWN_RF_WRITE(mac, 0x54, 0x9b); 5325 BWN_RF_WRITE(mac, 0x5a, 0x88); 5326 BWN_RF_WRITE(mac, 0x5b, 0x88); 5327 BWN_RF_WRITE(mac, 0x5d, 0x88); 5328 BWN_RF_WRITE(mac, 0x5e, 0x88); 5329 BWN_RF_WRITE(mac, 0x7d, 0x88); 5330 bwn_hf_write(mac, 5331 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5332 } 5333 if (phy->rf_rev == 8) { 5334 BWN_RF_WRITE(mac, 0x51, 0); 5335 BWN_RF_WRITE(mac, 0x52, 0x40); 5336 BWN_RF_WRITE(mac, 0x53, 0xb7); 5337 BWN_RF_WRITE(mac, 0x54, 0x98); 5338 BWN_RF_WRITE(mac, 0x5a, 0x88); 5339 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5340 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5341 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5342 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5343 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5344 } else { 5345 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5346 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5347 } 5348 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5349 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5350 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5351 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5352 } 5353 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5354 BWN_PHY_WRITE(mac, offset, val); 5355 val -= 0x0202; 5356 } 5357 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5358 BWN_PHY_WRITE(mac, offset, val); 5359 val -= 0x0202; 5360 } 5361 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5362 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5363 val += 0x0202; 5364 } 5365 if (phy->type == BWN_PHYTYPE_G) { 5366 BWN_RF_SET(mac, 0x007a, 0x0020); 5367 BWN_RF_SET(mac, 0x0051, 0x0004); 5368 BWN_PHY_SET(mac, 0x0802, 0x0100); 5369 BWN_PHY_SET(mac, 0x042b, 0x2000); 5370 BWN_PHY_WRITE(mac, 0x5b, 0); 5371 BWN_PHY_WRITE(mac, 0x5c, 0); 5372 } 5373 5374 old_channel = phy->chan; 5375 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5376 5377 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5378 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5379 DELAY(40); 5380 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5381 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5382 BWN_RF_WRITE(mac, 0x50, 0x20); 5383 } 5384 if (phy->rf_rev <= 2) { 5385 BWN_RF_WRITE(mac, 0x7c, 0x20); 5386 BWN_RF_WRITE(mac, 0x5a, 0x70); 5387 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5388 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5389 } 5390 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5391 5392 bwn_phy_g_switch_chan(mac, old_channel, 0); 5393 5394 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5395 if (phy->rf_rev >= 6) 5396 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5397 else 5398 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5399 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5400 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5401 pg->pg_txctl); 5402 if (phy->rf_rev <= 5) 5403 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5404 if (phy->rf_rev <= 2) 5405 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5406 5407 if (phy->analog == 4) { 5408 BWN_WRITE_2(mac, 0x3e4, 9); 5409 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5410 } else 5411 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5412 if (phy->type == BWN_PHYTYPE_B) 5413 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5414 else if (phy->type == BWN_PHYTYPE_G) 5415 BWN_WRITE_2(mac, 0x03e6, 0x0); 5416} 5417 5418static void 5419bwn_phy_init_a(struct bwn_mac *mac) 5420{ 5421 struct bwn_phy *phy = &mac->mac_phy; 5422 struct bwn_softc *sc = mac->mac_sc; 5423 5424 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5425 ("%s:%d: fail", __func__, __LINE__)); 5426 5427 if (phy->rev >= 6) { 5428 if (phy->type == BWN_PHYTYPE_A) 5429 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5430 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5431 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5432 else 5433 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5434 } 5435 5436 bwn_wa_init(mac); 5437 5438 if (phy->type == BWN_PHYTYPE_G && 5439 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5440 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5441} 5442 5443static void 5444bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5445{ 5446 int i; 5447 5448 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5449 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5450} 5451 5452static void 5453bwn_wa_agc(struct bwn_mac *mac) 5454{ 5455 struct bwn_phy *phy = &mac->mac_phy; 5456 5457 if (phy->rev == 1) { 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5466 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5467 } else { 5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5470 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5471 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5472 } 5473 5474 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5475 0x5700); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5477 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5478 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5479 BWN_RF_SET(mac, 0x7a, 0x0008); 5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5482 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5484 if (phy->rev == 1) 5485 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5494 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5495 if (phy->rev == 1) { 5496 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5497 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5498 } else { 5499 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5500 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5501 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5502 if (phy->rev >= 6) { 5503 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5504 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5505 (uint16_t)~0xf000, 0x3000); 5506 } 5507 } 5508 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5509 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5510 if (phy->rev == 1) { 5511 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5513 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5514 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5519 } else { 5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5522 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5523 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5524 } 5525 if (phy->rev >= 6) { 5526 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5527 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5528 } 5529 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5530} 5531 5532static void 5533bwn_wa_grev1(struct bwn_mac *mac) 5534{ 5535 struct bwn_phy *phy = &mac->mac_phy; 5536 int i; 5537 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5538 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5539 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5540 5541 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5542 5543 /* init CRSTHRES and ANTDWELL */ 5544 if (phy->rev == 1) { 5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5546 } else if (phy->rev == 2) { 5547 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5548 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5549 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5550 } else { 5551 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5552 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5553 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5554 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5555 } 5556 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5557 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5558 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5559 5560 /* XXX support PHY-A??? */ 5561 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5563 bwn_tab_finefreqg[i]); 5564 5565 /* XXX support PHY-A??? */ 5566 if (phy->rev == 1) 5567 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5569 bwn_tab_noise_g1[i]); 5570 else 5571 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5573 bwn_tab_noise_g2[i]); 5574 5575 5576 for (i = 0; i < N(bwn_tab_rotor); i++) 5577 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5578 bwn_tab_rotor[i]); 5579 5580 /* XXX support PHY-A??? */ 5581 if (phy->rev >= 6) { 5582 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5583 BWN_PHY_ENCORE_EN) 5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5585 else 5586 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5587 } else 5588 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5589 5590 for (i = 0; i < N(bwn_tab_retard); i++) 5591 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5592 bwn_tab_retard[i]); 5593 5594 if (phy->rev == 1) { 5595 for (i = 0; i < 16; i++) 5596 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5597 i, 0x0020); 5598 } else { 5599 for (i = 0; i < 32; i++) 5600 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5601 } 5602 5603 bwn_wa_agc(mac); 5604} 5605 5606static void 5607bwn_wa_grev26789(struct bwn_mac *mac) 5608{ 5609 struct bwn_phy *phy = &mac->mac_phy; 5610 int i; 5611 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5612 uint16_t ofdmrev; 5613 5614 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5615 5616 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5617 5618 /* init CRSTHRES and ANTDWELL */ 5619 if (phy->rev == 1) 5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5621 else if (phy->rev == 2) { 5622 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5623 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5624 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5625 } else { 5626 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5627 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5628 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5629 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5630 } 5631 5632 for (i = 0; i < 64; i++) 5633 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5634 5635 /* XXX support PHY-A??? */ 5636 if (phy->rev == 1) 5637 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5639 bwn_tab_noise_g1[i]); 5640 else 5641 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5642 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5643 bwn_tab_noise_g2[i]); 5644 5645 /* XXX support PHY-A??? */ 5646 if (phy->rev >= 6) { 5647 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5648 BWN_PHY_ENCORE_EN) 5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5650 else 5651 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5652 } else 5653 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5654 5655 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5656 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5657 bwn_tab_sigmasqr2[i]); 5658 5659 if (phy->rev == 1) { 5660 for (i = 0; i < 16; i++) 5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5662 0x0020); 5663 } else { 5664 for (i = 0; i < 32; i++) 5665 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5666 } 5667 5668 bwn_wa_agc(mac); 5669 5670 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5671 if (ofdmrev > 2) { 5672 if (phy->type == BWN_PHYTYPE_A) 5673 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5674 else 5675 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5676 } else { 5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5679 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5680 } 5681 5682 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5683 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5684} 5685 5686static void 5687bwn_wa_init(struct bwn_mac *mac) 5688{ 5689 struct bwn_phy *phy = &mac->mac_phy; 5690 struct bwn_softc *sc = mac->mac_sc; 5691 5692 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5693 5694 switch (phy->rev) { 5695 case 1: 5696 bwn_wa_grev1(mac); 5697 break; 5698 case 2: 5699 case 6: 5700 case 7: 5701 case 8: 5702 case 9: 5703 bwn_wa_grev26789(mac); 5704 break; 5705 default: 5706 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5707 } 5708 5709 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5710 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5711 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5712 if (phy->rev < 2) { 5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5714 0x0002); 5715 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5716 0x0001); 5717 } else { 5718 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5719 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5720 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5721 BWN_BFL_EXTLNA) && 5722 (phy->rev >= 7)) { 5723 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5725 0x0020, 0x0001); 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5727 0x0021, 0x0001); 5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5729 0x0022, 0x0001); 5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5731 0x0023, 0x0000); 5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5733 0x0000, 0x0000); 5734 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5735 0x0003, 0x0002); 5736 } 5737 } 5738 } 5739 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5740 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5741 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5742 } 5743 5744 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5745 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5746} 5747 5748static void 5749bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5750 uint16_t value) 5751{ 5752 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5753 uint16_t addr; 5754 5755 addr = table + offset; 5756 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5757 (addr - 1 != pg->pg_ofdmtab_addr)) { 5758 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5759 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5760 } 5761 pg->pg_ofdmtab_addr = addr; 5762 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5763} 5764 5765static void 5766bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5767 uint32_t value) 5768{ 5769 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5770 uint16_t addr; 5771 5772 addr = table + offset; 5773 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5774 (addr - 1 != pg->pg_ofdmtab_addr)) { 5775 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5776 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5777 } 5778 pg->pg_ofdmtab_addr = addr; 5779 5780 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5781 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5782} 5783 5784static void 5785bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5786 uint16_t value) 5787{ 5788 5789 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5790 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5791} 5792 5793static void 5794bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5795{ 5796 struct bwn_phy *phy = &mac->mac_phy; 5797 struct bwn_softc *sc = mac->mac_sc; 5798 unsigned int i, max_loop; 5799 uint16_t value; 5800 uint32_t buffer[5] = { 5801 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5802 }; 5803 5804 if (ofdm) { 5805 max_loop = 0x1e; 5806 buffer[0] = 0x000201cc; 5807 } else { 5808 max_loop = 0xfa; 5809 buffer[0] = 0x000b846e; 5810 } 5811 5812 BWN_ASSERT_LOCKED(mac->mac_sc); 5813 5814 for (i = 0; i < 5; i++) 5815 bwn_ram_write(mac, i * 4, buffer[i]); 5816 5817 BWN_WRITE_2(mac, 0x0568, 0x0000); 5818 BWN_WRITE_2(mac, 0x07c0, 5819 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5820 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5821 BWN_WRITE_2(mac, 0x050c, value); 5822 if (phy->type == BWN_PHYTYPE_LP) 5823 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5824 BWN_WRITE_2(mac, 0x0508, 0x0000); 5825 BWN_WRITE_2(mac, 0x050a, 0x0000); 5826 BWN_WRITE_2(mac, 0x054c, 0x0000); 5827 BWN_WRITE_2(mac, 0x056a, 0x0014); 5828 BWN_WRITE_2(mac, 0x0568, 0x0826); 5829 BWN_WRITE_2(mac, 0x0500, 0x0000); 5830 if (phy->type == BWN_PHYTYPE_LP) 5831 BWN_WRITE_2(mac, 0x0502, 0x0050); 5832 else 5833 BWN_WRITE_2(mac, 0x0502, 0x0030); 5834 5835 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5836 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5837 for (i = 0x00; i < max_loop; i++) { 5838 value = BWN_READ_2(mac, 0x050e); 5839 if (value & 0x0080) 5840 break; 5841 DELAY(10); 5842 } 5843 for (i = 0x00; i < 0x0a; i++) { 5844 value = BWN_READ_2(mac, 0x050e); 5845 if (value & 0x0400) 5846 break; 5847 DELAY(10); 5848 } 5849 for (i = 0x00; i < 0x19; i++) { 5850 value = BWN_READ_2(mac, 0x0690); 5851 if (!(value & 0x0100)) 5852 break; 5853 DELAY(10); 5854 } 5855 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5856 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5857} 5858 5859static void 5860bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5861{ 5862 uint32_t macctl; 5863 5864 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5865 5866 macctl = BWN_READ_4(mac, BWN_MACCTL); 5867 if (macctl & BWN_MACCTL_BIGENDIAN) 5868 printf("TODO: need swap\n"); 5869 5870 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5871 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5872 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5873} 5874 5875static void 5876bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5877{ 5878 uint16_t value; 5879 5880 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5881 ("%s:%d: fail", __func__, __LINE__)); 5882 5883 value = (uint8_t) (ctl->q); 5884 value |= ((uint8_t) (ctl->i)) << 8; 5885 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5886} 5887 5888static uint16_t 5889bwn_lo_calcfeed(struct bwn_mac *mac, 5890 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5891{ 5892 struct bwn_phy *phy = &mac->mac_phy; 5893 struct bwn_softc *sc = mac->mac_sc; 5894 uint16_t rfover; 5895 uint16_t feedthrough; 5896 5897 if (phy->gmode) { 5898 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5899 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5900 5901 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5902 ("%s:%d: fail", __func__, __LINE__)); 5903 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5904 ("%s:%d: fail", __func__, __LINE__)); 5905 5906 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5907 5908 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5909 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5910 phy->rev > 6) 5911 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5912 5913 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5914 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5915 DELAY(10); 5916 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5917 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5918 DELAY(10); 5919 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5920 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5921 DELAY(10); 5922 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5923 } else { 5924 pga |= BWN_PHY_PGACTL_UNKNOWN; 5925 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5926 DELAY(10); 5927 pga |= BWN_PHY_PGACTL_LOWBANDW; 5928 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5929 DELAY(10); 5930 pga |= BWN_PHY_PGACTL_LPF; 5931 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5932 } 5933 DELAY(21); 5934 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5935 5936 return (feedthrough); 5937} 5938 5939static uint16_t 5940bwn_lo_txctl_regtable(struct bwn_mac *mac, 5941 uint16_t *value, uint16_t *pad_mix_gain) 5942{ 5943 struct bwn_phy *phy = &mac->mac_phy; 5944 uint16_t reg, v, padmix; 5945 5946 if (phy->type == BWN_PHYTYPE_B) { 5947 v = 0x30; 5948 if (phy->rf_rev <= 5) { 5949 reg = 0x43; 5950 padmix = 0; 5951 } else { 5952 reg = 0x52; 5953 padmix = 5; 5954 } 5955 } else { 5956 if (phy->rev >= 2 && phy->rf_rev == 8) { 5957 reg = 0x43; 5958 v = 0x10; 5959 padmix = 2; 5960 } else { 5961 reg = 0x52; 5962 v = 0x30; 5963 padmix = 5; 5964 } 5965 } 5966 if (value) 5967 *value = v; 5968 if (pad_mix_gain) 5969 *pad_mix_gain = padmix; 5970 5971 return (reg); 5972} 5973 5974static void 5975bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5976{ 5977 struct bwn_phy *phy = &mac->mac_phy; 5978 struct bwn_phy_g *pg = &phy->phy_g; 5979 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5980 uint16_t reg, mask; 5981 uint16_t trsw_rx, pga; 5982 uint16_t rf_pctl_reg; 5983 5984 static const uint8_t tx_bias_values[] = { 5985 0x09, 0x08, 0x0a, 0x01, 0x00, 5986 0x02, 0x05, 0x04, 0x06, 5987 }; 5988 static const uint8_t tx_magn_values[] = { 5989 0x70, 0x40, 5990 }; 5991 5992 if (!BWN_HAS_LOOPBACK(phy)) { 5993 rf_pctl_reg = 6; 5994 trsw_rx = 2; 5995 pga = 0; 5996 } else { 5997 int lb_gain; 5998 5999 trsw_rx = 0; 6000 lb_gain = pg->pg_max_lb_gain / 2; 6001 if (lb_gain > 10) { 6002 rf_pctl_reg = 0; 6003 pga = abs(10 - lb_gain) / 6; 6004 pga = MIN(MAX(pga, 0), 15); 6005 } else { 6006 int cmp_val; 6007 int tmp; 6008 6009 pga = 0; 6010 cmp_val = 0x24; 6011 if ((phy->rev >= 2) && 6012 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6013 cmp_val = 0x3c; 6014 tmp = lb_gain; 6015 if ((10 - lb_gain) < cmp_val) 6016 tmp = (10 - lb_gain); 6017 if (tmp < 0) 6018 tmp += 6; 6019 else 6020 tmp += 3; 6021 cmp_val /= 4; 6022 tmp /= 4; 6023 if (tmp >= cmp_val) 6024 rf_pctl_reg = cmp_val; 6025 else 6026 rf_pctl_reg = tmp; 6027 } 6028 } 6029 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6030 bwn_phy_g_set_bbatt(mac, 2); 6031 6032 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6033 mask = ~mask; 6034 BWN_RF_MASK(mac, reg, mask); 6035 6036 if (BWN_HAS_TXMAG(phy)) { 6037 int i, j; 6038 int feedthrough; 6039 int min_feedth = 0xffff; 6040 uint8_t tx_magn, tx_bias; 6041 6042 for (i = 0; i < N(tx_magn_values); i++) { 6043 tx_magn = tx_magn_values[i]; 6044 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6045 for (j = 0; j < N(tx_bias_values); j++) { 6046 tx_bias = tx_bias_values[j]; 6047 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6048 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6049 trsw_rx); 6050 if (feedthrough < min_feedth) { 6051 lo->tx_bias = tx_bias; 6052 lo->tx_magn = tx_magn; 6053 min_feedth = feedthrough; 6054 } 6055 if (lo->tx_bias == 0) 6056 break; 6057 } 6058 BWN_RF_WRITE(mac, 0x52, 6059 (BWN_RF_READ(mac, 0x52) 6060 & 0xff00) | lo->tx_bias | lo-> 6061 tx_magn); 6062 } 6063 } else { 6064 lo->tx_magn = 0; 6065 lo->tx_bias = 0; 6066 BWN_RF_MASK(mac, 0x52, 0xfff0); 6067 } 6068 6069 BWN_GETTIME(lo->txctl_measured_time); 6070} 6071 6072static void 6073bwn_lo_get_powervector(struct bwn_mac *mac) 6074{ 6075 struct bwn_phy *phy = &mac->mac_phy; 6076 struct bwn_phy_g *pg = &phy->phy_g; 6077 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6078 int i; 6079 uint64_t tmp; 6080 uint64_t power_vector = 0; 6081 6082 for (i = 0; i < 8; i += 2) { 6083 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6084 power_vector |= (tmp << (i * 8)); 6085 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6086 } 6087 if (power_vector) 6088 lo->power_vector = power_vector; 6089 6090 BWN_GETTIME(lo->pwr_vec_read_time); 6091} 6092 6093static void 6094bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6095 int use_trsw_rx) 6096{ 6097 struct bwn_phy *phy = &mac->mac_phy; 6098 struct bwn_phy_g *pg = &phy->phy_g; 6099 uint16_t tmp; 6100 6101 if (max_rx_gain < 0) 6102 max_rx_gain = 0; 6103 6104 if (BWN_HAS_LOOPBACK(phy)) { 6105 int trsw_rx = 0; 6106 int trsw_rx_gain; 6107 6108 if (use_trsw_rx) { 6109 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6110 if (max_rx_gain >= trsw_rx_gain) { 6111 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6112 trsw_rx = 0x20; 6113 } 6114 } else 6115 trsw_rx_gain = max_rx_gain; 6116 if (trsw_rx_gain < 9) { 6117 pg->pg_lna_lod_gain = 0; 6118 } else { 6119 pg->pg_lna_lod_gain = 1; 6120 trsw_rx_gain -= 8; 6121 } 6122 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6123 pg->pg_pga_gain = trsw_rx_gain / 3; 6124 if (pg->pg_pga_gain >= 5) { 6125 pg->pg_pga_gain -= 5; 6126 pg->pg_lna_gain = 2; 6127 } else 6128 pg->pg_lna_gain = 0; 6129 } else { 6130 pg->pg_lna_gain = 0; 6131 pg->pg_trsw_rx_gain = 0x20; 6132 if (max_rx_gain >= 0x14) { 6133 pg->pg_lna_lod_gain = 1; 6134 pg->pg_pga_gain = 2; 6135 } else if (max_rx_gain >= 0x12) { 6136 pg->pg_lna_lod_gain = 1; 6137 pg->pg_pga_gain = 1; 6138 } else if (max_rx_gain >= 0xf) { 6139 pg->pg_lna_lod_gain = 1; 6140 pg->pg_pga_gain = 0; 6141 } else { 6142 pg->pg_lna_lod_gain = 0; 6143 pg->pg_pga_gain = 0; 6144 } 6145 } 6146 6147 tmp = BWN_RF_READ(mac, 0x7a); 6148 if (pg->pg_lna_lod_gain == 0) 6149 tmp &= ~0x0008; 6150 else 6151 tmp |= 0x0008; 6152 BWN_RF_WRITE(mac, 0x7a, tmp); 6153} 6154 6155static void 6156bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6157{ 6158 struct bwn_phy *phy = &mac->mac_phy; 6159 struct bwn_phy_g *pg = &phy->phy_g; 6160 struct bwn_softc *sc = mac->mac_sc; 6161 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6162 struct timespec ts; 6163 uint16_t tmp; 6164 6165 if (bwn_has_hwpctl(mac)) { 6166 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6167 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6168 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6169 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6170 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6171 6172 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6173 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6174 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6175 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6176 } 6177 if (phy->type == BWN_PHYTYPE_B && 6178 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6181 } 6182 if (phy->rev >= 2) { 6183 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6184 sav->phy_analogoverval = 6185 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6186 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6187 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6188 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6189 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6190 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6191 6192 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6193 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6194 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6195 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6196 if (phy->type == BWN_PHYTYPE_G) { 6197 if ((phy->rev >= 7) && 6198 (siba_sprom_get_bf_lo(sc->sc_dev) & 6199 BWN_BFL_EXTLNA)) { 6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6201 } else { 6202 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6203 } 6204 } else { 6205 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6206 } 6207 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6208 } 6209 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6210 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6211 sav->rf0 = BWN_RF_READ(mac, 0x43); 6212 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6213 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6214 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6215 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6216 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6217 6218 if (!BWN_HAS_TXMAG(phy)) { 6219 sav->rf2 = BWN_RF_READ(mac, 0x52); 6220 sav->rf2 &= 0x00f0; 6221 } 6222 if (phy->type == BWN_PHYTYPE_B) { 6223 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6224 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6225 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6226 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6227 } else { 6228 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6229 | 0x8000); 6230 } 6231 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6232 & 0xf000); 6233 6234 tmp = 6235 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6236 BWN_PHY_WRITE(mac, tmp, 0x007f); 6237 6238 tmp = sav->phy_syncctl; 6239 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6240 tmp = sav->rf1; 6241 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6242 6243 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6244 if (phy->type == BWN_PHYTYPE_G || 6245 (phy->type == BWN_PHYTYPE_B && 6246 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6248 } else 6249 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6250 if (phy->rev >= 2) 6251 bwn_dummy_transmission(mac, 0, 1); 6252 bwn_phy_g_switch_chan(mac, 6, 0); 6253 BWN_RF_READ(mac, 0x51); 6254 if (phy->type == BWN_PHYTYPE_G) 6255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6256 6257 nanouptime(&ts); 6258 if (time_before(lo->txctl_measured_time, 6259 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6260 bwn_lo_measure_txctl_values(mac); 6261 6262 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6263 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6264 else { 6265 if (phy->type == BWN_PHYTYPE_B) 6266 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6267 else 6268 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6269 } 6270} 6271 6272static void 6273bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6274{ 6275 struct bwn_phy *phy = &mac->mac_phy; 6276 struct bwn_phy_g *pg = &phy->phy_g; 6277 uint16_t tmp; 6278 6279 if (phy->rev >= 2) { 6280 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6281 tmp = (pg->pg_pga_gain << 8); 6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6283 DELAY(5); 6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6285 DELAY(2); 6286 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6287 } else { 6288 tmp = (pg->pg_pga_gain | 0xefa0); 6289 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6290 } 6291 if (phy->type == BWN_PHYTYPE_G) { 6292 if (phy->rev >= 3) 6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6294 else 6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6296 if (phy->rev >= 2) 6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6298 else 6299 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6300 } 6301 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6302 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6303 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6304 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6305 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6306 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6307 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6308 if (!BWN_HAS_TXMAG(phy)) { 6309 tmp = sav->rf2; 6310 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6311 } 6312 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6313 if (phy->type == BWN_PHYTYPE_B && 6314 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6317 } 6318 if (phy->rev >= 2) { 6319 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6320 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6321 sav->phy_analogoverval); 6322 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6323 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6324 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6326 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6327 } 6328 if (bwn_has_hwpctl(mac)) { 6329 tmp = (sav->phy_lomask & 0xbfff); 6330 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6331 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6332 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6333 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6334 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6335 } 6336 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6337} 6338 6339static int 6340bwn_lo_probe_loctl(struct bwn_mac *mac, 6341 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6342{ 6343 struct bwn_phy *phy = &mac->mac_phy; 6344 struct bwn_phy_g *pg = &phy->phy_g; 6345 struct bwn_loctl orig, test; 6346 struct bwn_loctl prev = { -100, -100 }; 6347 static const struct bwn_loctl modifiers[] = { 6348 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6349 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6350 }; 6351 int begin, end, lower = 0, i; 6352 uint16_t feedth; 6353 6354 if (d->curstate == 0) { 6355 begin = 1; 6356 end = 8; 6357 } else if (d->curstate % 2 == 0) { 6358 begin = d->curstate - 1; 6359 end = d->curstate + 1; 6360 } else { 6361 begin = d->curstate - 2; 6362 end = d->curstate + 2; 6363 } 6364 if (begin < 1) 6365 begin += 8; 6366 if (end > 8) 6367 end -= 8; 6368 6369 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6370 i = begin; 6371 d->curstate = i; 6372 while (1) { 6373 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6374 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6375 test.i += modifiers[i - 1].i * d->multipler; 6376 test.q += modifiers[i - 1].q * d->multipler; 6377 if ((test.i != prev.i || test.q != prev.q) && 6378 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6379 bwn_lo_write(mac, &test); 6380 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6381 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6382 if (feedth < d->feedth) { 6383 memcpy(probe, &test, 6384 sizeof(struct bwn_loctl)); 6385 lower = 1; 6386 d->feedth = feedth; 6387 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6388 break; 6389 } 6390 } 6391 memcpy(&prev, &test, sizeof(prev)); 6392 if (i == end) 6393 break; 6394 if (i == 8) 6395 i = 1; 6396 else 6397 i++; 6398 d->curstate = i; 6399 } 6400 6401 return (lower); 6402} 6403 6404static void 6405bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6406{ 6407 struct bwn_phy *phy = &mac->mac_phy; 6408 struct bwn_phy_g *pg = &phy->phy_g; 6409 struct bwn_lo_g_sm d; 6410 struct bwn_loctl probe; 6411 int lower, repeat, cnt = 0; 6412 uint16_t feedth; 6413 6414 d.nmeasure = 0; 6415 d.multipler = 1; 6416 if (BWN_HAS_LOOPBACK(phy)) 6417 d.multipler = 3; 6418 6419 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6420 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6421 6422 do { 6423 bwn_lo_write(mac, &d.loctl); 6424 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6425 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6426 if (feedth < 0x258) { 6427 if (feedth >= 0x12c) 6428 *rxgain += 6; 6429 else 6430 *rxgain += 3; 6431 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6432 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6433 } 6434 d.feedth = feedth; 6435 d.curstate = 0; 6436 do { 6437 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6438 ("%s:%d: fail", __func__, __LINE__)); 6439 memcpy(&probe, &d.loctl, 6440 sizeof(struct bwn_loctl)); 6441 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6442 if (!lower) 6443 break; 6444 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6445 break; 6446 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6447 d.nmeasure++; 6448 } while (d.nmeasure < 24); 6449 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6450 6451 if (BWN_HAS_LOOPBACK(phy)) { 6452 if (d.feedth > 0x1194) 6453 *rxgain -= 6; 6454 else if (d.feedth < 0x5dc) 6455 *rxgain += 3; 6456 if (cnt == 0) { 6457 if (d.feedth <= 0x5dc) { 6458 d.multipler = 1; 6459 cnt++; 6460 } else 6461 d.multipler = 2; 6462 } else if (cnt == 2) 6463 d.multipler = 1; 6464 } 6465 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6466 } while (++cnt < repeat); 6467} 6468 6469static struct bwn_lo_calib * 6470bwn_lo_calibset(struct bwn_mac *mac, 6471 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6472{ 6473 struct bwn_phy *phy = &mac->mac_phy; 6474 struct bwn_phy_g *pg = &phy->phy_g; 6475 struct bwn_loctl loctl = { 0, 0 }; 6476 struct bwn_lo_calib *cal; 6477 struct bwn_lo_g_value sval = { 0 }; 6478 int rxgain; 6479 uint16_t pad, reg, value; 6480 6481 sval.old_channel = phy->chan; 6482 bwn_mac_suspend(mac); 6483 bwn_lo_save(mac, &sval); 6484 6485 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6486 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6487 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6488 6489 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6490 if (rfatt->padmix) 6491 rxgain -= pad; 6492 if (BWN_HAS_LOOPBACK(phy)) 6493 rxgain += pg->pg_max_lb_gain; 6494 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6495 bwn_phy_g_set_bbatt(mac, bbatt->att); 6496 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6497 6498 bwn_lo_restore(mac, &sval); 6499 bwn_mac_enable(mac); 6500 6501 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6502 if (!cal) { 6503 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6504 return (NULL); 6505 } 6506 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6507 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6508 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6509 6510 BWN_GETTIME(cal->calib_time); 6511 6512 return (cal); 6513} 6514 6515static struct bwn_lo_calib * 6516bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6517 const struct bwn_rfatt *rfatt) 6518{ 6519 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6520 struct bwn_lo_calib *c; 6521 6522 TAILQ_FOREACH(c, &lo->calib_list, list) { 6523 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6524 continue; 6525 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6526 continue; 6527 return (c); 6528 } 6529 6530 c = bwn_lo_calibset(mac, bbatt, rfatt); 6531 if (!c) 6532 return (NULL); 6533 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6534 6535 return (c); 6536} 6537 6538static void 6539bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6540{ 6541 struct bwn_phy *phy = &mac->mac_phy; 6542 struct bwn_phy_g *pg = &phy->phy_g; 6543 struct bwn_softc *sc = mac->mac_sc; 6544 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6545 const struct bwn_rfatt *rfatt; 6546 const struct bwn_bbatt *bbatt; 6547 uint64_t pvector; 6548 int i; 6549 int rf_offset, bb_offset; 6550 uint8_t changed = 0; 6551 6552 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6553 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6554 ("%s:%d: fail", __func__, __LINE__)); 6555 6556 pvector = lo->power_vector; 6557 if (!update && !pvector) 6558 return; 6559 6560 bwn_mac_suspend(mac); 6561 6562 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6563 struct bwn_lo_calib *cal; 6564 int idx; 6565 uint16_t val; 6566 6567 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6568 continue; 6569 bb_offset = i / lo->rfatt.len; 6570 rf_offset = i % lo->rfatt.len; 6571 bbatt = &(lo->bbatt.array[bb_offset]); 6572 rfatt = &(lo->rfatt.array[rf_offset]); 6573 6574 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6575 if (!cal) { 6576 device_printf(sc->sc_dev, "LO: Could not " 6577 "calibrate DC table entry\n"); 6578 continue; 6579 } 6580 val = (uint8_t)(cal->ctl.q); 6581 val |= ((uint8_t)(cal->ctl.i)) << 4; 6582 free(cal, M_DEVBUF); 6583 6584 idx = i / 2; 6585 if (i % 2) 6586 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6587 | ((val & 0x00ff) << 8); 6588 else 6589 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6590 | (val & 0x00ff); 6591 changed = 1; 6592 } 6593 if (changed) { 6594 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6595 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6596 } 6597 bwn_mac_enable(mac); 6598} 6599 6600static void 6601bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6602{ 6603 6604 if (!rf->padmix) 6605 return; 6606 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6607 rf->att = 4; 6608} 6609 6610static void 6611bwn_lo_g_adjust(struct bwn_mac *mac) 6612{ 6613 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6614 struct bwn_lo_calib *cal; 6615 struct bwn_rfatt rf; 6616 6617 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6618 bwn_lo_fixup_rfatt(&rf); 6619 6620 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6621 if (!cal) 6622 return; 6623 bwn_lo_write(mac, &cal->ctl); 6624} 6625 6626static void 6627bwn_lo_g_init(struct bwn_mac *mac) 6628{ 6629 6630 if (!bwn_has_hwpctl(mac)) 6631 return; 6632 6633 bwn_lo_get_powervector(mac); 6634 bwn_phy_g_dc_lookup_init(mac, 1); 6635} 6636 6637static void 6638bwn_mac_suspend(struct bwn_mac *mac) 6639{ 6640 struct bwn_softc *sc = mac->mac_sc; 6641 int i; 6642 uint32_t tmp; 6643 6644 KASSERT(mac->mac_suspended >= 0, 6645 ("%s:%d: fail", __func__, __LINE__)); 6646 6647 if (mac->mac_suspended == 0) { 6648 bwn_psctl(mac, BWN_PS_AWAKE); 6649 BWN_WRITE_4(mac, BWN_MACCTL, 6650 BWN_READ_4(mac, BWN_MACCTL) 6651 & ~BWN_MACCTL_ON); 6652 BWN_READ_4(mac, BWN_MACCTL); 6653 for (i = 35; i; i--) { 6654 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6655 if (tmp & BWN_INTR_MAC_SUSPENDED) 6656 goto out; 6657 DELAY(10); 6658 } 6659 for (i = 40; i; i--) { 6660 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6661 if (tmp & BWN_INTR_MAC_SUSPENDED) 6662 goto out; 6663 DELAY(1000); 6664 } 6665 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6666 } 6667out: 6668 mac->mac_suspended++; 6669} 6670 6671static void 6672bwn_mac_enable(struct bwn_mac *mac) 6673{ 6674 struct bwn_softc *sc = mac->mac_sc; 6675 uint16_t state; 6676 6677 state = bwn_shm_read_2(mac, BWN_SHARED, 6678 BWN_SHARED_UCODESTAT); 6679 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6680 state != BWN_SHARED_UCODESTAT_SLEEP) 6681 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6682 6683 mac->mac_suspended--; 6684 KASSERT(mac->mac_suspended >= 0, 6685 ("%s:%d: fail", __func__, __LINE__)); 6686 if (mac->mac_suspended == 0) { 6687 BWN_WRITE_4(mac, BWN_MACCTL, 6688 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6689 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6690 BWN_READ_4(mac, BWN_MACCTL); 6691 BWN_READ_4(mac, BWN_INTR_REASON); 6692 bwn_psctl(mac, 0); 6693 } 6694} 6695 6696static void 6697bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6698{ 6699 struct bwn_softc *sc = mac->mac_sc; 6700 int i; 6701 uint16_t ucstat; 6702 6703 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6704 ("%s:%d: fail", __func__, __LINE__)); 6705 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6706 ("%s:%d: fail", __func__, __LINE__)); 6707 6708 /* XXX forcibly awake and hwps-off */ 6709 6710 BWN_WRITE_4(mac, BWN_MACCTL, 6711 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6712 ~BWN_MACCTL_HWPS); 6713 BWN_READ_4(mac, BWN_MACCTL); 6714 if (siba_get_revid(sc->sc_dev) >= 5) { 6715 for (i = 0; i < 100; i++) { 6716 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6717 BWN_SHARED_UCODESTAT); 6718 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6719 break; 6720 DELAY(10); 6721 } 6722 } 6723} 6724 6725static int16_t 6726bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6727{ 6728 6729 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6730 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6731} 6732 6733static void 6734bwn_nrssi_threshold(struct bwn_mac *mac) 6735{ 6736 struct bwn_phy *phy = &mac->mac_phy; 6737 struct bwn_phy_g *pg = &phy->phy_g; 6738 struct bwn_softc *sc = mac->mac_sc; 6739 int32_t a, b; 6740 int16_t tmp16; 6741 uint16_t tmpu16; 6742 6743 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6744 6745 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6746 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6747 a = 0x13; 6748 b = 0x12; 6749 } else { 6750 a = 0xe; 6751 b = 0x11; 6752 } 6753 6754 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6755 a += (pg->pg_nrssi[0] << 6); 6756 a += (a < 32) ? 31 : 32; 6757 a = a >> 6; 6758 a = MIN(MAX(a, -31), 31); 6759 6760 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6761 b += (pg->pg_nrssi[0] << 6); 6762 if (b < 32) 6763 b += 31; 6764 else 6765 b += 32; 6766 b = b >> 6; 6767 b = MIN(MAX(b, -31), 31); 6768 6769 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6770 tmpu16 |= ((uint32_t)b & 0x0000003f); 6771 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6772 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6773 return; 6774 } 6775 6776 tmp16 = bwn_nrssi_read(mac, 0x20); 6777 if (tmp16 >= 0x20) 6778 tmp16 -= 0x40; 6779 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6780} 6781 6782static void 6783bwn_nrssi_slope_11g(struct bwn_mac *mac) 6784{ 6785#define SAVE_RF_MAX 3 6786#define SAVE_PHY_COMM_MAX 4 6787#define SAVE_PHY3_MAX 8 6788 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6789 { 0x7a, 0x52, 0x43 }; 6790 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6791 { 0x15, 0x5a, 0x59, 0x58 }; 6792 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6793 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6794 0x0801, 0x0060, 0x0014, 0x0478 6795 }; 6796 struct bwn_phy *phy = &mac->mac_phy; 6797 struct bwn_phy_g *pg = &phy->phy_g; 6798 int32_t i, tmp32, phy3_idx = 0; 6799 uint16_t delta, tmp; 6800 uint16_t save_rf[SAVE_RF_MAX]; 6801 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6802 uint16_t save_phy3[SAVE_PHY3_MAX]; 6803 uint16_t ant_div, phy0, chan_ex; 6804 int16_t nrssi0, nrssi1; 6805 6806 KASSERT(phy->type == BWN_PHYTYPE_G, 6807 ("%s:%d: fail", __func__, __LINE__)); 6808 6809 if (phy->rf_rev >= 9) 6810 return; 6811 if (phy->rf_rev == 8) 6812 bwn_nrssi_offset(mac); 6813 6814 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6815 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6816 6817 /* 6818 * Save RF/PHY registers for later restoration 6819 */ 6820 ant_div = BWN_READ_2(mac, 0x03e2); 6821 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6822 for (i = 0; i < SAVE_RF_MAX; ++i) 6823 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6824 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6825 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6826 6827 phy0 = BWN_READ_2(mac, BWN_PHY0); 6828 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6829 if (phy->rev >= 3) { 6830 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6831 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6832 BWN_PHY_WRITE(mac, 0x002e, 0); 6833 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6834 switch (phy->rev) { 6835 case 4: 6836 case 6: 6837 case 7: 6838 BWN_PHY_SET(mac, 0x0478, 0x0100); 6839 BWN_PHY_SET(mac, 0x0801, 0x0040); 6840 break; 6841 case 3: 6842 case 5: 6843 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6844 break; 6845 } 6846 BWN_PHY_SET(mac, 0x0060, 0x0040); 6847 BWN_PHY_SET(mac, 0x0014, 0x0200); 6848 } 6849 /* 6850 * Calculate nrssi0 6851 */ 6852 BWN_RF_SET(mac, 0x007a, 0x0070); 6853 bwn_set_all_gains(mac, 0, 8, 0); 6854 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6855 if (phy->rev >= 2) { 6856 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6857 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6858 } 6859 BWN_RF_SET(mac, 0x007a, 0x0080); 6860 DELAY(20); 6861 6862 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6863 if (nrssi0 >= 0x0020) 6864 nrssi0 -= 0x0040; 6865 6866 /* 6867 * Calculate nrssi1 6868 */ 6869 BWN_RF_MASK(mac, 0x007a, 0x007f); 6870 if (phy->rev >= 2) 6871 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6872 6873 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6874 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6875 BWN_RF_SET(mac, 0x007a, 0x000f); 6876 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6877 if (phy->rev >= 2) { 6878 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6879 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6880 } 6881 6882 bwn_set_all_gains(mac, 3, 0, 1); 6883 if (phy->rf_rev == 8) { 6884 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6885 } else { 6886 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6887 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6888 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6889 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6890 } 6891 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6892 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6893 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6894 DELAY(20); 6895 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6896 6897 /* 6898 * Install calculated narrow RSSI values 6899 */ 6900 if (nrssi1 >= 0x0020) 6901 nrssi1 -= 0x0040; 6902 if (nrssi0 == nrssi1) 6903 pg->pg_nrssi_slope = 0x00010000; 6904 else 6905 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6906 if (nrssi0 >= -4) { 6907 pg->pg_nrssi[0] = nrssi1; 6908 pg->pg_nrssi[1] = nrssi0; 6909 } 6910 6911 /* 6912 * Restore saved RF/PHY registers 6913 */ 6914 if (phy->rev >= 3) { 6915 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6916 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6917 save_phy3[phy3_idx]); 6918 } 6919 } 6920 if (phy->rev >= 2) { 6921 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6922 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6923 } 6924 6925 for (i = 0; i < SAVE_RF_MAX; ++i) 6926 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6927 6928 BWN_WRITE_2(mac, 0x03e2, ant_div); 6929 BWN_WRITE_2(mac, 0x03e6, phy0); 6930 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6931 6932 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6933 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6934 6935 bwn_spu_workaround(mac, phy->chan); 6936 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6937 bwn_set_original_gains(mac); 6938 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6939 if (phy->rev >= 3) { 6940 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6941 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6942 save_phy3[phy3_idx]); 6943 } 6944 } 6945 6946 delta = 0x1f - pg->pg_nrssi[0]; 6947 for (i = 0; i < 64; i++) { 6948 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6949 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6950 pg->pg_nrssi_lt[i] = tmp32; 6951 } 6952 6953 bwn_nrssi_threshold(mac); 6954#undef SAVE_RF_MAX 6955#undef SAVE_PHY_COMM_MAX 6956#undef SAVE_PHY3_MAX 6957} 6958 6959static void 6960bwn_nrssi_offset(struct bwn_mac *mac) 6961{ 6962#define SAVE_RF_MAX 2 6963#define SAVE_PHY_COMM_MAX 10 6964#define SAVE_PHY6_MAX 8 6965 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6966 { 0x7a, 0x43 }; 6967 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6968 0x0001, 0x0811, 0x0812, 0x0814, 6969 0x0815, 0x005a, 0x0059, 0x0058, 6970 0x000a, 0x0003 6971 }; 6972 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6973 0x002e, 0x002f, 0x080f, 0x0810, 6974 0x0801, 0x0060, 0x0014, 0x0478 6975 }; 6976 struct bwn_phy *phy = &mac->mac_phy; 6977 int i, phy6_idx = 0; 6978 uint16_t save_rf[SAVE_RF_MAX]; 6979 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6980 uint16_t save_phy6[SAVE_PHY6_MAX]; 6981 int16_t nrssi; 6982 uint16_t saved = 0xffff; 6983 6984 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6985 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6986 for (i = 0; i < SAVE_RF_MAX; ++i) 6987 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6988 6989 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6990 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6991 BWN_PHY_SET(mac, 0x0811, 0x000c); 6992 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6993 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6994 if (phy->rev >= 6) { 6995 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6996 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6997 6998 BWN_PHY_WRITE(mac, 0x002e, 0); 6999 BWN_PHY_WRITE(mac, 0x002f, 0); 7000 BWN_PHY_WRITE(mac, 0x080f, 0); 7001 BWN_PHY_WRITE(mac, 0x0810, 0); 7002 BWN_PHY_SET(mac, 0x0478, 0x0100); 7003 BWN_PHY_SET(mac, 0x0801, 0x0040); 7004 BWN_PHY_SET(mac, 0x0060, 0x0040); 7005 BWN_PHY_SET(mac, 0x0014, 0x0200); 7006 } 7007 BWN_RF_SET(mac, 0x007a, 0x0070); 7008 BWN_RF_SET(mac, 0x007a, 0x0080); 7009 DELAY(30); 7010 7011 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7012 if (nrssi >= 0x20) 7013 nrssi -= 0x40; 7014 if (nrssi == 31) { 7015 for (i = 7; i >= 4; i--) { 7016 BWN_RF_WRITE(mac, 0x007b, i); 7017 DELAY(20); 7018 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7019 0x003f); 7020 if (nrssi >= 0x20) 7021 nrssi -= 0x40; 7022 if (nrssi < 31 && saved == 0xffff) 7023 saved = i; 7024 } 7025 if (saved == 0xffff) 7026 saved = 4; 7027 } else { 7028 BWN_RF_MASK(mac, 0x007a, 0x007f); 7029 if (phy->rev != 1) { 7030 BWN_PHY_SET(mac, 0x0814, 0x0001); 7031 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7032 } 7033 BWN_PHY_SET(mac, 0x0811, 0x000c); 7034 BWN_PHY_SET(mac, 0x0812, 0x000c); 7035 BWN_PHY_SET(mac, 0x0811, 0x0030); 7036 BWN_PHY_SET(mac, 0x0812, 0x0030); 7037 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7038 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7039 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7040 if (phy->rev == 0) 7041 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7042 else 7043 BWN_PHY_SET(mac, 0x000a, 0x2000); 7044 if (phy->rev != 1) { 7045 BWN_PHY_SET(mac, 0x0814, 0x0004); 7046 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7047 } 7048 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7049 BWN_RF_SET(mac, 0x007a, 0x000f); 7050 bwn_set_all_gains(mac, 3, 0, 1); 7051 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7052 DELAY(30); 7053 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7054 if (nrssi >= 0x20) 7055 nrssi -= 0x40; 7056 if (nrssi == -32) { 7057 for (i = 0; i < 4; i++) { 7058 BWN_RF_WRITE(mac, 0x007b, i); 7059 DELAY(20); 7060 nrssi = (int16_t)((BWN_PHY_READ(mac, 7061 0x047f) >> 8) & 0x003f); 7062 if (nrssi >= 0x20) 7063 nrssi -= 0x40; 7064 if (nrssi > -31 && saved == 0xffff) 7065 saved = i; 7066 } 7067 if (saved == 0xffff) 7068 saved = 3; 7069 } else 7070 saved = 0; 7071 } 7072 BWN_RF_WRITE(mac, 0x007b, saved); 7073 7074 /* 7075 * Restore saved RF/PHY registers 7076 */ 7077 if (phy->rev >= 6) { 7078 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7079 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7080 save_phy6[phy6_idx]); 7081 } 7082 } 7083 if (phy->rev != 1) { 7084 for (i = 3; i < 5; i++) 7085 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7086 save_phy_comm[i]); 7087 } 7088 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7089 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7090 7091 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7092 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7093 7094 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7095 BWN_PHY_SET(mac, 0x0429, 0x8000); 7096 bwn_set_original_gains(mac); 7097 if (phy->rev >= 6) { 7098 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7099 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7100 save_phy6[phy6_idx]); 7101 } 7102 } 7103 7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7105 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7106 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7107} 7108 7109static void 7110bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7111 int16_t third) 7112{ 7113 struct bwn_phy *phy = &mac->mac_phy; 7114 uint16_t i; 7115 uint16_t start = 0x08, end = 0x18; 7116 uint16_t tmp; 7117 uint16_t table; 7118 7119 if (phy->rev <= 1) { 7120 start = 0x10; 7121 end = 0x20; 7122 } 7123 7124 table = BWN_OFDMTAB_GAINX; 7125 if (phy->rev <= 1) 7126 table = BWN_OFDMTAB_GAINX_R1; 7127 for (i = 0; i < 4; i++) 7128 bwn_ofdmtab_write_2(mac, table, i, first); 7129 7130 for (i = start; i < end; i++) 7131 bwn_ofdmtab_write_2(mac, table, i, second); 7132 7133 if (third != -1) { 7134 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7135 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7136 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7137 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7138 } 7139 bwn_dummy_transmission(mac, 0, 1); 7140} 7141 7142static void 7143bwn_set_original_gains(struct bwn_mac *mac) 7144{ 7145 struct bwn_phy *phy = &mac->mac_phy; 7146 uint16_t i, tmp; 7147 uint16_t table; 7148 uint16_t start = 0x0008, end = 0x0018; 7149 7150 if (phy->rev <= 1) { 7151 start = 0x0010; 7152 end = 0x0020; 7153 } 7154 7155 table = BWN_OFDMTAB_GAINX; 7156 if (phy->rev <= 1) 7157 table = BWN_OFDMTAB_GAINX_R1; 7158 for (i = 0; i < 4; i++) { 7159 tmp = (i & 0xfffc); 7160 tmp |= (i & 0x0001) << 1; 7161 tmp |= (i & 0x0002) >> 1; 7162 7163 bwn_ofdmtab_write_2(mac, table, i, tmp); 7164 } 7165 7166 for (i = start; i < end; i++) 7167 bwn_ofdmtab_write_2(mac, table, i, i - start); 7168 7169 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7170 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7171 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7172 bwn_dummy_transmission(mac, 0, 1); 7173} 7174 7175static void 7176bwn_phy_hwpctl_init(struct bwn_mac *mac) 7177{ 7178 struct bwn_phy *phy = &mac->mac_phy; 7179 struct bwn_phy_g *pg = &phy->phy_g; 7180 struct bwn_rfatt old_rfatt, rfatt; 7181 struct bwn_bbatt old_bbatt, bbatt; 7182 struct bwn_softc *sc = mac->mac_sc; 7183 uint8_t old_txctl = 0; 7184 7185 KASSERT(phy->type == BWN_PHYTYPE_G, 7186 ("%s:%d: fail", __func__, __LINE__)); 7187 7188 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7189 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7190 return; 7191 7192 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7193 7194 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7195 7196 if (!phy->gmode) 7197 return; 7198 bwn_hwpctl_early_init(mac); 7199 if (pg->pg_curtssi == 0) { 7200 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7201 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7202 } else { 7203 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7204 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7205 old_txctl = pg->pg_txctl; 7206 7207 bbatt.att = 11; 7208 if (phy->rf_rev == 8) { 7209 rfatt.att = 15; 7210 rfatt.padmix = 1; 7211 } else { 7212 rfatt.att = 9; 7213 rfatt.padmix = 0; 7214 } 7215 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7216 } 7217 bwn_dummy_transmission(mac, 0, 1); 7218 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7219 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7220 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7221 else 7222 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7223 &old_rfatt, old_txctl); 7224 } 7225 bwn_hwpctl_init_gphy(mac); 7226 7227 /* clear TSSI */ 7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7229 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7230 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7231 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7232} 7233 7234static void 7235bwn_hwpctl_early_init(struct bwn_mac *mac) 7236{ 7237 struct bwn_phy *phy = &mac->mac_phy; 7238 7239 if (!bwn_has_hwpctl(mac)) { 7240 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7241 return; 7242 } 7243 7244 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7245 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7246 BWN_PHY_SET(mac, 0x047c, 0x0002); 7247 BWN_PHY_SET(mac, 0x047a, 0xf000); 7248 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7249 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7250 BWN_PHY_SET(mac, 0x005d, 0x8000); 7251 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7252 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7253 BWN_PHY_SET(mac, 0x0036, 0x0400); 7254 } else { 7255 BWN_PHY_SET(mac, 0x0036, 0x0200); 7256 BWN_PHY_SET(mac, 0x0036, 0x0400); 7257 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7258 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7259 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7260 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7261 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7262 } 7263} 7264 7265static void 7266bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7267{ 7268 struct bwn_phy *phy = &mac->mac_phy; 7269 struct bwn_phy_g *pg = &phy->phy_g; 7270 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7271 int i; 7272 uint16_t nr_written = 0, tmp, value; 7273 uint8_t rf, bb; 7274 7275 if (!bwn_has_hwpctl(mac)) { 7276 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7277 return; 7278 } 7279 7280 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7281 (pg->pg_idletssi - pg->pg_curtssi)); 7282 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7283 (pg->pg_idletssi - pg->pg_curtssi)); 7284 7285 for (i = 0; i < 32; i++) 7286 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7287 for (i = 32; i < 64; i++) 7288 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7289 for (i = 0; i < 64; i += 2) { 7290 value = (uint16_t) pg->pg_tssi2dbm[i]; 7291 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7292 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7293 } 7294 7295 for (rf = 0; rf < lo->rfatt.len; rf++) { 7296 for (bb = 0; bb < lo->bbatt.len; bb++) { 7297 if (nr_written >= 0x40) 7298 return; 7299 tmp = lo->bbatt.array[bb].att; 7300 tmp <<= 8; 7301 if (phy->rf_rev == 8) 7302 tmp |= 0x50; 7303 else 7304 tmp |= 0x40; 7305 tmp |= lo->rfatt.array[rf].att; 7306 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7307 nr_written++; 7308 } 7309 } 7310 7311 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7312 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7313 7314 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7315 BWN_PHY_SET(mac, 0x0478, 0x0800); 7316 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7317 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7318 7319 bwn_phy_g_dc_lookup_init(mac, 1); 7320 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7321} 7322 7323static void 7324bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7325{ 7326 struct bwn_softc *sc = mac->mac_sc; 7327 7328 if (spu != 0) 7329 bwn_spu_workaround(mac, channel); 7330 7331 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7332 7333 if (channel == 14) { 7334 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7335 bwn_hf_write(mac, 7336 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7337 else 7338 bwn_hf_write(mac, 7339 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7340 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7341 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7342 return; 7343 } 7344 7345 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7346 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7347} 7348 7349static uint16_t 7350bwn_phy_g_chan2freq(uint8_t channel) 7351{ 7352 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7353 7354 KASSERT(channel >= 1 && channel <= 14, 7355 ("%s:%d: fail", __func__, __LINE__)); 7356 7357 return (bwn_phy_g_rf_channels[channel - 1]); 7358} 7359 7360static void 7361bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7362 const struct bwn_rfatt *rfatt, uint8_t txctl) 7363{ 7364 struct bwn_phy *phy = &mac->mac_phy; 7365 struct bwn_phy_g *pg = &phy->phy_g; 7366 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7367 uint16_t bb, rf; 7368 uint16_t tx_bias, tx_magn; 7369 7370 bb = bbatt->att; 7371 rf = rfatt->att; 7372 tx_bias = lo->tx_bias; 7373 tx_magn = lo->tx_magn; 7374 if (tx_bias == 0xff) 7375 tx_bias = 0; 7376 7377 pg->pg_txctl = txctl; 7378 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7379 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7380 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7381 bwn_phy_g_set_bbatt(mac, bb); 7382 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7383 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7384 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7385 else { 7386 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7387 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7388 } 7389 if (BWN_HAS_TXMAG(phy)) 7390 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7391 else 7392 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7393 bwn_lo_g_adjust(mac); 7394} 7395 7396static void 7397bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7398 uint16_t bbatt) 7399{ 7400 struct bwn_phy *phy = &mac->mac_phy; 7401 7402 if (phy->analog == 0) { 7403 BWN_WRITE_2(mac, BWN_PHY0, 7404 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7405 return; 7406 } 7407 if (phy->analog > 1) { 7408 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7409 return; 7410 } 7411 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7412} 7413 7414static uint16_t 7415bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7416{ 7417 struct bwn_phy *phy = &mac->mac_phy; 7418 struct bwn_phy_g *pg = &phy->phy_g; 7419 struct bwn_softc *sc = mac->mac_sc; 7420 int max_lb_gain; 7421 uint16_t extlna; 7422 uint16_t i; 7423 7424 if (phy->gmode == 0) 7425 return (0); 7426 7427 if (BWN_HAS_LOOPBACK(phy)) { 7428 max_lb_gain = pg->pg_max_lb_gain; 7429 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7430 if (max_lb_gain >= 0x46) { 7431 extlna = 0x3000; 7432 max_lb_gain -= 0x46; 7433 } else if (max_lb_gain >= 0x3a) { 7434 extlna = 0x1000; 7435 max_lb_gain -= 0x3a; 7436 } else if (max_lb_gain >= 0x2e) { 7437 extlna = 0x2000; 7438 max_lb_gain -= 0x2e; 7439 } else { 7440 extlna = 0; 7441 max_lb_gain -= 0x10; 7442 } 7443 7444 for (i = 0; i < 16; i++) { 7445 max_lb_gain -= (i * 6); 7446 if (max_lb_gain < 6) 7447 break; 7448 } 7449 7450 if ((phy->rev < 7) || 7451 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7452 if (reg == BWN_PHY_RFOVER) { 7453 return (0x1b3); 7454 } else if (reg == BWN_PHY_RFOVERVAL) { 7455 extlna |= (i << 8); 7456 switch (lpd) { 7457 case BWN_LPD(0, 1, 1): 7458 return (0x0f92); 7459 case BWN_LPD(0, 0, 1): 7460 case BWN_LPD(1, 0, 1): 7461 return (0x0092 | extlna); 7462 case BWN_LPD(1, 0, 0): 7463 return (0x0093 | extlna); 7464 } 7465 KASSERT(0 == 1, 7466 ("%s:%d: fail", __func__, __LINE__)); 7467 } 7468 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7469 } else { 7470 if (reg == BWN_PHY_RFOVER) 7471 return (0x9b3); 7472 if (reg == BWN_PHY_RFOVERVAL) { 7473 if (extlna) 7474 extlna |= 0x8000; 7475 extlna |= (i << 8); 7476 switch (lpd) { 7477 case BWN_LPD(0, 1, 1): 7478 return (0x8f92); 7479 case BWN_LPD(0, 0, 1): 7480 return (0x8092 | extlna); 7481 case BWN_LPD(1, 0, 1): 7482 return (0x2092 | extlna); 7483 case BWN_LPD(1, 0, 0): 7484 return (0x2093 | extlna); 7485 } 7486 KASSERT(0 == 1, 7487 ("%s:%d: fail", __func__, __LINE__)); 7488 } 7489 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7490 } 7491 return (0); 7492 } 7493 7494 if ((phy->rev < 7) || 7495 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7496 if (reg == BWN_PHY_RFOVER) { 7497 return (0x1b3); 7498 } else if (reg == BWN_PHY_RFOVERVAL) { 7499 switch (lpd) { 7500 case BWN_LPD(0, 1, 1): 7501 return (0x0fb2); 7502 case BWN_LPD(0, 0, 1): 7503 return (0x00b2); 7504 case BWN_LPD(1, 0, 1): 7505 return (0x30b2); 7506 case BWN_LPD(1, 0, 0): 7507 return (0x30b3); 7508 } 7509 KASSERT(0 == 1, 7510 ("%s:%d: fail", __func__, __LINE__)); 7511 } 7512 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7513 } else { 7514 if (reg == BWN_PHY_RFOVER) { 7515 return (0x9b3); 7516 } else if (reg == BWN_PHY_RFOVERVAL) { 7517 switch (lpd) { 7518 case BWN_LPD(0, 1, 1): 7519 return (0x8fb2); 7520 case BWN_LPD(0, 0, 1): 7521 return (0x80b2); 7522 case BWN_LPD(1, 0, 1): 7523 return (0x20b2); 7524 case BWN_LPD(1, 0, 0): 7525 return (0x20b3); 7526 } 7527 KASSERT(0 == 1, 7528 ("%s:%d: fail", __func__, __LINE__)); 7529 } 7530 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7531 } 7532 return (0); 7533} 7534 7535static void 7536bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7537{ 7538 7539 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7540 return; 7541 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7542 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7543 DELAY(1000); 7544 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7545} 7546 7547static int 7548bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7549{ 7550 struct bwn_softc *sc = mac->mac_sc; 7551 struct bwn_fw *fw = &mac->mac_fw; 7552 const uint8_t rev = siba_get_revid(sc->sc_dev); 7553 const char *filename; 7554 uint32_t high; 7555 int error; 7556 7557 /* microcode */ 7558 if (rev >= 5 && rev <= 10) 7559 filename = "ucode5"; 7560 else if (rev >= 11 && rev <= 12) 7561 filename = "ucode11"; 7562 else if (rev == 13) 7563 filename = "ucode13"; 7564 else if (rev == 14) 7565 filename = "ucode14"; 7566 else if (rev >= 15) 7567 filename = "ucode15"; 7568 else { 7569 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7570 bwn_release_firmware(mac); 7571 return (EOPNOTSUPP); 7572 } 7573 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7574 if (error) { 7575 bwn_release_firmware(mac); 7576 return (error); 7577 } 7578 7579 /* PCM */ 7580 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7581 if (rev >= 5 && rev <= 10) { 7582 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7583 if (error == ENOENT) 7584 fw->no_pcmfile = 1; 7585 else if (error) { 7586 bwn_release_firmware(mac); 7587 return (error); 7588 } 7589 } else if (rev < 11) { 7590 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7591 return (EOPNOTSUPP); 7592 } 7593 7594 /* initvals */ 7595 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7596 switch (mac->mac_phy.type) { 7597 case BWN_PHYTYPE_A: 7598 if (rev < 5 || rev > 10) 7599 goto fail1; 7600 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7601 filename = "a0g1initvals5"; 7602 else 7603 filename = "a0g0initvals5"; 7604 break; 7605 case BWN_PHYTYPE_G: 7606 if (rev >= 5 && rev <= 10) 7607 filename = "b0g0initvals5"; 7608 else if (rev >= 13) 7609 filename = "b0g0initvals13"; 7610 else 7611 goto fail1; 7612 break; 7613 case BWN_PHYTYPE_LP: 7614 if (rev == 13) 7615 filename = "lp0initvals13"; 7616 else if (rev == 14) 7617 filename = "lp0initvals14"; 7618 else if (rev >= 15) 7619 filename = "lp0initvals15"; 7620 else 7621 goto fail1; 7622 break; 7623 case BWN_PHYTYPE_N: 7624 if (rev >= 11 && rev <= 12) 7625 filename = "n0initvals11"; 7626 else 7627 goto fail1; 7628 break; 7629 default: 7630 goto fail1; 7631 } 7632 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7633 if (error) { 7634 bwn_release_firmware(mac); 7635 return (error); 7636 } 7637 7638 /* bandswitch initvals */ 7639 switch (mac->mac_phy.type) { 7640 case BWN_PHYTYPE_A: 7641 if (rev >= 5 && rev <= 10) { 7642 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7643 filename = "a0g1bsinitvals5"; 7644 else 7645 filename = "a0g0bsinitvals5"; 7646 } else if (rev >= 11) 7647 filename = NULL; 7648 else 7649 goto fail1; 7650 break; 7651 case BWN_PHYTYPE_G: 7652 if (rev >= 5 && rev <= 10) 7653 filename = "b0g0bsinitvals5"; 7654 else if (rev >= 11) 7655 filename = NULL; 7656 else 7657 goto fail1; 7658 break; 7659 case BWN_PHYTYPE_LP: 7660 if (rev == 13) 7661 filename = "lp0bsinitvals13"; 7662 else if (rev == 14) 7663 filename = "lp0bsinitvals14"; 7664 else if (rev >= 15) 7665 filename = "lp0bsinitvals15"; 7666 else 7667 goto fail1; 7668 break; 7669 case BWN_PHYTYPE_N: 7670 if (rev >= 11 && rev <= 12) 7671 filename = "n0bsinitvals11"; 7672 else 7673 goto fail1; 7674 break; 7675 default: 7676 goto fail1; 7677 } 7678 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7679 if (error) { 7680 bwn_release_firmware(mac); 7681 return (error); 7682 } 7683 return (0); 7684fail1: 7685 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7686 bwn_release_firmware(mac); 7687 return (EOPNOTSUPP); 7688} 7689 7690static int 7691bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7692 const char *name, struct bwn_fwfile *bfw) 7693{ 7694 const struct bwn_fwhdr *hdr; 7695 struct bwn_softc *sc = mac->mac_sc; 7696 const struct firmware *fw; 7697 char namebuf[64]; 7698 7699 if (name == NULL) { 7700 bwn_do_release_fw(bfw); 7701 return (0); 7702 } 7703 if (bfw->filename != NULL) { 7704 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7705 return (0); 7706 bwn_do_release_fw(bfw); 7707 } 7708 7709 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7710 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7711 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7712 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7713 fw = firmware_get(namebuf); 7714 if (fw == NULL) { 7715 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7716 namebuf); 7717 return (ENOENT); 7718 } 7719 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7720 goto fail; 7721 hdr = (const struct bwn_fwhdr *)(fw->data); 7722 switch (hdr->type) { 7723 case BWN_FWTYPE_UCODE: 7724 case BWN_FWTYPE_PCM: 7725 if (be32toh(hdr->size) != 7726 (fw->datasize - sizeof(struct bwn_fwhdr))) 7727 goto fail; 7728 /* FALLTHROUGH */ 7729 case BWN_FWTYPE_IV: 7730 if (hdr->ver != 1) 7731 goto fail; 7732 break; 7733 default: 7734 goto fail; 7735 } 7736 bfw->filename = name; 7737 bfw->fw = fw; 7738 bfw->type = type; 7739 return (0); 7740fail: 7741 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7742 if (fw != NULL) 7743 firmware_put(fw, FIRMWARE_UNLOAD); 7744 return (EPROTO); 7745} 7746 7747static void 7748bwn_release_firmware(struct bwn_mac *mac) 7749{ 7750 7751 bwn_do_release_fw(&mac->mac_fw.ucode); 7752 bwn_do_release_fw(&mac->mac_fw.pcm); 7753 bwn_do_release_fw(&mac->mac_fw.initvals); 7754 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7755} 7756 7757static void 7758bwn_do_release_fw(struct bwn_fwfile *bfw) 7759{ 7760 7761 if (bfw->fw != NULL) 7762 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7763 bfw->fw = NULL; 7764 bfw->filename = NULL; 7765} 7766 7767static int 7768bwn_fw_loaducode(struct bwn_mac *mac) 7769{ 7770#define GETFWOFFSET(fwp, offset) \ 7771 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7772#define GETFWSIZE(fwp, offset) \ 7773 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7774 struct bwn_softc *sc = mac->mac_sc; 7775 const uint32_t *data; 7776 unsigned int i; 7777 uint32_t ctl; 7778 uint16_t date, fwcaps, time; 7779 int error = 0; 7780 7781 ctl = BWN_READ_4(mac, BWN_MACCTL); 7782 ctl |= BWN_MACCTL_MCODE_JMP0; 7783 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7784 __LINE__)); 7785 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7786 for (i = 0; i < 64; i++) 7787 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7788 for (i = 0; i < 4096; i += 2) 7789 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7790 7791 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7792 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7793 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7794 i++) { 7795 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7796 DELAY(10); 7797 } 7798 7799 if (mac->mac_fw.pcm.fw) { 7800 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7801 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7802 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7803 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7804 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7805 sizeof(struct bwn_fwhdr)); i++) { 7806 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7807 DELAY(10); 7808 } 7809 } 7810 7811 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7812 BWN_WRITE_4(mac, BWN_MACCTL, 7813 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7814 BWN_MACCTL_MCODE_RUN); 7815 7816 for (i = 0; i < 21; i++) { 7817 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7818 break; 7819 if (i >= 20) { 7820 device_printf(sc->sc_dev, "ucode timeout\n"); 7821 error = ENXIO; 7822 goto error; 7823 } 7824 DELAY(50000); 7825 } 7826 BWN_READ_4(mac, BWN_INTR_REASON); 7827 7828 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7829 if (mac->mac_fw.rev <= 0x128) { 7830 device_printf(sc->sc_dev, "the firmware is too old\n"); 7831 error = EOPNOTSUPP; 7832 goto error; 7833 } 7834 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7835 BWN_SHARED_UCODE_PATCH); 7836 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7837 mac->mac_fw.opensource = (date == 0xffff); 7838 if (bwn_wme != 0) 7839 mac->mac_flags |= BWN_MAC_FLAG_WME; 7840 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7841 7842 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7843 if (mac->mac_fw.opensource == 0) { 7844 device_printf(sc->sc_dev, 7845 "firmware version (rev %u patch %u date %#x time %#x)\n", 7846 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7847 if (mac->mac_fw.no_pcmfile) 7848 device_printf(sc->sc_dev, 7849 "no HW crypto acceleration due to pcm5\n"); 7850 } else { 7851 mac->mac_fw.patch = time; 7852 fwcaps = bwn_fwcaps_read(mac); 7853 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7854 device_printf(sc->sc_dev, 7855 "disabling HW crypto acceleration\n"); 7856 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7857 } 7858 if (!(fwcaps & BWN_FWCAPS_WME)) { 7859 device_printf(sc->sc_dev, "disabling WME support\n"); 7860 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7861 } 7862 } 7863 7864 if (BWN_ISOLDFMT(mac)) 7865 device_printf(sc->sc_dev, "using old firmware image\n"); 7866 7867 return (0); 7868 7869error: 7870 BWN_WRITE_4(mac, BWN_MACCTL, 7871 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7872 BWN_MACCTL_MCODE_JMP0); 7873 7874 return (error); 7875#undef GETFWSIZE 7876#undef GETFWOFFSET 7877} 7878 7879/* OpenFirmware only */ 7880static uint16_t 7881bwn_fwcaps_read(struct bwn_mac *mac) 7882{ 7883 7884 KASSERT(mac->mac_fw.opensource == 1, 7885 ("%s:%d: fail", __func__, __LINE__)); 7886 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7887} 7888 7889static int 7890bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7891 size_t count, size_t array_size) 7892{ 7893#define GET_NEXTIV16(iv) \ 7894 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7895 sizeof(uint16_t) + sizeof(uint16_t))) 7896#define GET_NEXTIV32(iv) \ 7897 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7898 sizeof(uint16_t) + sizeof(uint32_t))) 7899 struct bwn_softc *sc = mac->mac_sc; 7900 const struct bwn_fwinitvals *iv; 7901 uint16_t offset; 7902 size_t i; 7903 uint8_t bit32; 7904 7905 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7906 ("%s:%d: fail", __func__, __LINE__)); 7907 iv = ivals; 7908 for (i = 0; i < count; i++) { 7909 if (array_size < sizeof(iv->offset_size)) 7910 goto fail; 7911 array_size -= sizeof(iv->offset_size); 7912 offset = be16toh(iv->offset_size); 7913 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7914 offset &= BWN_FWINITVALS_OFFSET_MASK; 7915 if (offset >= 0x1000) 7916 goto fail; 7917 if (bit32) { 7918 if (array_size < sizeof(iv->data.d32)) 7919 goto fail; 7920 array_size -= sizeof(iv->data.d32); 7921 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7922 iv = GET_NEXTIV32(iv); 7923 } else { 7924 7925 if (array_size < sizeof(iv->data.d16)) 7926 goto fail; 7927 array_size -= sizeof(iv->data.d16); 7928 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7929 7930 iv = GET_NEXTIV16(iv); 7931 } 7932 } 7933 if (array_size != 0) 7934 goto fail; 7935 return (0); 7936fail: 7937 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7938 return (EPROTO); 7939#undef GET_NEXTIV16 7940#undef GET_NEXTIV32 7941} 7942 7943static int 7944bwn_switch_channel(struct bwn_mac *mac, int chan) 7945{ 7946 struct bwn_phy *phy = &(mac->mac_phy); 7947 struct bwn_softc *sc = mac->mac_sc; 7948 struct ifnet *ifp = sc->sc_ifp; 7949 struct ieee80211com *ic = ifp->if_l2com; 7950 uint16_t channelcookie, savedcookie; 7951 int error; 7952 7953 if (chan == 0xffff) 7954 chan = phy->get_default_chan(mac); 7955 7956 channelcookie = chan; 7957 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7958 channelcookie |= 0x100; 7959 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7960 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7961 error = phy->switch_channel(mac, chan); 7962 if (error) 7963 goto fail; 7964 7965 mac->mac_phy.chan = chan; 7966 DELAY(8000); 7967 return (0); 7968fail: 7969 device_printf(sc->sc_dev, "failed to switch channel\n"); 7970 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7971 return (error); 7972} 7973 7974static uint16_t 7975bwn_ant2phy(int antenna) 7976{ 7977 7978 switch (antenna) { 7979 case BWN_ANT0: 7980 return (BWN_TX_PHY_ANT0); 7981 case BWN_ANT1: 7982 return (BWN_TX_PHY_ANT1); 7983 case BWN_ANT2: 7984 return (BWN_TX_PHY_ANT2); 7985 case BWN_ANT3: 7986 return (BWN_TX_PHY_ANT3); 7987 case BWN_ANTAUTO: 7988 return (BWN_TX_PHY_ANT01AUTO); 7989 } 7990 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7991 return (0); 7992} 7993 7994static void 7995bwn_wme_load(struct bwn_mac *mac) 7996{ 7997 struct bwn_softc *sc = mac->mac_sc; 7998 int i; 7999 8000 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8001 ("%s:%d: fail", __func__, __LINE__)); 8002 8003 bwn_mac_suspend(mac); 8004 for (i = 0; i < N(sc->sc_wmeParams); i++) 8005 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8006 bwn_wme_shm_offsets[i]); 8007 bwn_mac_enable(mac); 8008} 8009 8010static void 8011bwn_wme_loadparams(struct bwn_mac *mac, 8012 const struct wmeParams *p, uint16_t shm_offset) 8013{ 8014#define SM(_v, _f) (((_v) << _f##_S) & _f) 8015 struct bwn_softc *sc = mac->mac_sc; 8016 uint16_t params[BWN_NR_WMEPARAMS]; 8017 int slot, tmp; 8018 unsigned int i; 8019 8020 slot = BWN_READ_2(mac, BWN_RNG) & 8021 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8022 8023 memset(¶ms, 0, sizeof(params)); 8024 8025 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8026 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8027 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8028 8029 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8030 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8031 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8032 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8033 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8034 params[BWN_WMEPARAM_BSLOTS] = slot; 8035 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8036 8037 for (i = 0; i < N(params); i++) { 8038 if (i == BWN_WMEPARAM_STATUS) { 8039 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8040 shm_offset + (i * 2)); 8041 tmp |= 0x100; 8042 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8043 tmp); 8044 } else { 8045 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8046 params[i]); 8047 } 8048 } 8049} 8050 8051static void 8052bwn_mac_write_bssid(struct bwn_mac *mac) 8053{ 8054 struct bwn_softc *sc = mac->mac_sc; 8055 uint32_t tmp; 8056 int i; 8057 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8058 8059 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8060 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8061 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8062 IEEE80211_ADDR_LEN); 8063 8064 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8065 tmp = (uint32_t) (mac_bssid[i + 0]); 8066 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8067 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8068 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8069 bwn_ram_write(mac, 0x20 + i, tmp); 8070 } 8071} 8072 8073static void 8074bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8075 const uint8_t *macaddr) 8076{ 8077 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8078 uint16_t data; 8079 8080 if (!mac) 8081 macaddr = zero; 8082 8083 offset |= 0x0020; 8084 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8085 8086 data = macaddr[0]; 8087 data |= macaddr[1] << 8; 8088 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8089 data = macaddr[2]; 8090 data |= macaddr[3] << 8; 8091 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8092 data = macaddr[4]; 8093 data |= macaddr[5] << 8; 8094 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8095} 8096 8097static void 8098bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8099 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8100{ 8101 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8102 uint8_t per_sta_keys_start = 8; 8103 8104 if (BWN_SEC_NEWAPI(mac)) 8105 per_sta_keys_start = 4; 8106 8107 KASSERT(index < mac->mac_max_nr_keys, 8108 ("%s:%d: fail", __func__, __LINE__)); 8109 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8110 ("%s:%d: fail", __func__, __LINE__)); 8111 8112 if (index >= per_sta_keys_start) 8113 bwn_key_macwrite(mac, index, NULL); 8114 if (key) 8115 memcpy(buf, key, key_len); 8116 bwn_key_write(mac, index, algorithm, buf); 8117 if (index >= per_sta_keys_start) 8118 bwn_key_macwrite(mac, index, mac_addr); 8119 8120 mac->mac_key[index].algorithm = algorithm; 8121} 8122 8123static void 8124bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8125{ 8126 struct bwn_softc *sc = mac->mac_sc; 8127 uint32_t addrtmp[2] = { 0, 0 }; 8128 uint8_t start = 8; 8129 8130 if (BWN_SEC_NEWAPI(mac)) 8131 start = 4; 8132 8133 KASSERT(index >= start, 8134 ("%s:%d: fail", __func__, __LINE__)); 8135 index -= start; 8136 8137 if (addr) { 8138 addrtmp[0] = addr[0]; 8139 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8140 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8141 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8142 addrtmp[1] = addr[4]; 8143 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8144 } 8145 8146 if (siba_get_revid(sc->sc_dev) >= 5) { 8147 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8148 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8149 } else { 8150 if (index >= 8) { 8151 bwn_shm_write_4(mac, BWN_SHARED, 8152 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8153 bwn_shm_write_2(mac, BWN_SHARED, 8154 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8155 } 8156 } 8157} 8158 8159static void 8160bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8161 const uint8_t *key) 8162{ 8163 unsigned int i; 8164 uint32_t offset; 8165 uint16_t kidx, value; 8166 8167 kidx = BWN_SEC_KEY2FW(mac, index); 8168 bwn_shm_write_2(mac, BWN_SHARED, 8169 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8170 8171 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8172 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8173 value = key[i]; 8174 value |= (uint16_t)(key[i + 1]) << 8; 8175 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8176 } 8177} 8178 8179static void 8180bwn_phy_exit(struct bwn_mac *mac) 8181{ 8182 8183 mac->mac_phy.rf_onoff(mac, 0); 8184 if (mac->mac_phy.exit != NULL) 8185 mac->mac_phy.exit(mac); 8186} 8187 8188static void 8189bwn_dma_free(struct bwn_mac *mac) 8190{ 8191 struct bwn_dma *dma; 8192 8193 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8194 return; 8195 dma = &mac->mac_method.dma; 8196 8197 bwn_dma_ringfree(&dma->rx); 8198 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8199 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8200 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8201 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8202 bwn_dma_ringfree(&dma->mcast); 8203} 8204 8205static void 8206bwn_core_stop(struct bwn_mac *mac) 8207{ 8208 struct bwn_softc *sc = mac->mac_sc; 8209 8210 BWN_ASSERT_LOCKED(sc); 8211 8212 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8213 return; 8214 8215 callout_stop(&sc->sc_rfswitch_ch); 8216 callout_stop(&sc->sc_task_ch); 8217 callout_stop(&sc->sc_watchdog_ch); 8218 sc->sc_watchdog_timer = 0; 8219 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8220 BWN_READ_4(mac, BWN_INTR_MASK); 8221 bwn_mac_suspend(mac); 8222 8223 mac->mac_status = BWN_MAC_STATUS_INITED; 8224} 8225 8226static int 8227bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8228{ 8229 struct bwn_mac *up_dev = NULL; 8230 struct bwn_mac *down_dev; 8231 struct bwn_mac *mac; 8232 int err, status; 8233 uint8_t gmode; 8234 8235 BWN_ASSERT_LOCKED(sc); 8236 8237 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8238 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8239 mac->mac_phy.supports_2ghz) { 8240 up_dev = mac; 8241 gmode = 1; 8242 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8243 mac->mac_phy.supports_5ghz) { 8244 up_dev = mac; 8245 gmode = 0; 8246 } else { 8247 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8248 return (EINVAL); 8249 } 8250 if (up_dev != NULL) 8251 break; 8252 } 8253 if (up_dev == NULL) { 8254 device_printf(sc->sc_dev, "Could not find a device\n"); 8255 return (ENODEV); 8256 } 8257 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8258 return (0); 8259 8260 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8261 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8262 8263 down_dev = sc->sc_curmac;; 8264 status = down_dev->mac_status; 8265 if (status >= BWN_MAC_STATUS_STARTED) 8266 bwn_core_stop(down_dev); 8267 if (status >= BWN_MAC_STATUS_INITED) 8268 bwn_core_exit(down_dev); 8269 8270 if (down_dev != up_dev) 8271 bwn_phy_reset(down_dev); 8272 8273 up_dev->mac_phy.gmode = gmode; 8274 if (status >= BWN_MAC_STATUS_INITED) { 8275 err = bwn_core_init(up_dev); 8276 if (err) { 8277 device_printf(sc->sc_dev, 8278 "fatal: failed to initialize for %s-GHz\n", 8279 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8280 goto fail; 8281 } 8282 } 8283 if (status >= BWN_MAC_STATUS_STARTED) 8284 bwn_core_start(up_dev); 8285 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8286 sc->sc_curmac = up_dev; 8287 8288 return (0); 8289fail: 8290 sc->sc_curmac = NULL; 8291 return (err); 8292} 8293 8294static void 8295bwn_rf_turnon(struct bwn_mac *mac) 8296{ 8297 8298 bwn_mac_suspend(mac); 8299 mac->mac_phy.rf_onoff(mac, 1); 8300 mac->mac_phy.rf_on = 1; 8301 bwn_mac_enable(mac); 8302} 8303 8304static void 8305bwn_rf_turnoff(struct bwn_mac *mac) 8306{ 8307 8308 bwn_mac_suspend(mac); 8309 mac->mac_phy.rf_onoff(mac, 0); 8310 mac->mac_phy.rf_on = 0; 8311 bwn_mac_enable(mac); 8312} 8313 8314static void 8315bwn_phy_reset(struct bwn_mac *mac) 8316{ 8317 struct bwn_softc *sc = mac->mac_sc; 8318 8319 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8320 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8321 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8322 DELAY(1000); 8323 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8324 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8325 BWN_TGSLOW_PHYRESET); 8326 DELAY(1000); 8327} 8328 8329static int 8330bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8331{ 8332 struct bwn_vap *bvp = BWN_VAP(vap); 8333 struct ieee80211com *ic= vap->iv_ic; 8334 struct ifnet *ifp = ic->ic_ifp; 8335 enum ieee80211_state ostate = vap->iv_state; 8336 struct bwn_softc *sc = ifp->if_softc; 8337 struct bwn_mac *mac = sc->sc_curmac; 8338 int error; 8339 8340 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8341 ieee80211_state_name[vap->iv_state], 8342 ieee80211_state_name[nstate]); 8343 8344 error = bvp->bv_newstate(vap, nstate, arg); 8345 if (error != 0) 8346 return (error); 8347 8348 BWN_LOCK(sc); 8349 8350 bwn_led_newstate(mac, nstate); 8351 8352 /* 8353 * Clear the BSSID when we stop a STA 8354 */ 8355 if (vap->iv_opmode == IEEE80211_M_STA) { 8356 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8357 /* 8358 * Clear out the BSSID. If we reassociate to 8359 * the same AP, this will reinialize things 8360 * correctly... 8361 */ 8362 if (ic->ic_opmode == IEEE80211_M_STA && 8363 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8364 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8365 bwn_set_macaddr(mac); 8366 } 8367 } 8368 } 8369 8370 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8371 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8372 /* XXX nothing to do? */ 8373 } else if (nstate == IEEE80211_S_RUN) { 8374 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8375 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8376 bwn_set_opmode(mac); 8377 bwn_set_pretbtt(mac); 8378 bwn_spu_setdelay(mac, 0); 8379 bwn_set_macaddr(mac); 8380 } 8381 8382 BWN_UNLOCK(sc); 8383 8384 return (error); 8385} 8386 8387static void 8388bwn_set_pretbtt(struct bwn_mac *mac) 8389{ 8390 struct bwn_softc *sc = mac->mac_sc; 8391 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8392 uint16_t pretbtt; 8393 8394 if (ic->ic_opmode == IEEE80211_M_IBSS) 8395 pretbtt = 2; 8396 else 8397 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8398 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8399 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8400} 8401 8402static int 8403bwn_intr(void *arg) 8404{ 8405 struct bwn_mac *mac = arg; 8406 struct bwn_softc *sc = mac->mac_sc; 8407 uint32_t reason; 8408 8409 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8410 (sc->sc_flags & BWN_FLAG_INVALID)) 8411 return (FILTER_STRAY); 8412 8413 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8414 if (reason == 0xffffffff) /* shared IRQ */ 8415 return (FILTER_STRAY); 8416 reason &= mac->mac_intr_mask; 8417 if (reason == 0) 8418 return (FILTER_HANDLED); 8419 8420 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8421 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8422 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8423 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8424 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8425 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8426 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8427 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8428 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8429 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8430 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8431 8432 /* Disable interrupts. */ 8433 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8434 8435 mac->mac_reason_intr = reason; 8436 8437 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8438 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8439 8440 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8441 return (FILTER_HANDLED); 8442} 8443 8444static void 8445bwn_intrtask(void *arg, int npending) 8446{ 8447 struct bwn_mac *mac = arg; 8448 struct bwn_softc *sc = mac->mac_sc; 8449 struct ifnet *ifp = sc->sc_ifp; 8450 uint32_t merged = 0; 8451 int i, tx = 0, rx = 0; 8452 8453 BWN_LOCK(sc); 8454 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8455 (sc->sc_flags & BWN_FLAG_INVALID)) { 8456 BWN_UNLOCK(sc); 8457 return; 8458 } 8459 8460 for (i = 0; i < N(mac->mac_reason); i++) 8461 merged |= mac->mac_reason[i]; 8462 8463 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8464 device_printf(sc->sc_dev, "MAC trans error\n"); 8465 8466 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8467 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8468 mac->mac_phy.txerrors--; 8469 if (mac->mac_phy.txerrors == 0) { 8470 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8471 bwn_restart(mac, "PHY TX errors"); 8472 } 8473 } 8474 8475 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8476 if (merged & BWN_DMAINTR_FATALMASK) { 8477 device_printf(sc->sc_dev, 8478 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8479 mac->mac_reason[0], mac->mac_reason[1], 8480 mac->mac_reason[2], mac->mac_reason[3], 8481 mac->mac_reason[4], mac->mac_reason[5]); 8482 bwn_restart(mac, "DMA error"); 8483 BWN_UNLOCK(sc); 8484 return; 8485 } 8486 if (merged & BWN_DMAINTR_NONFATALMASK) { 8487 device_printf(sc->sc_dev, 8488 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8489 mac->mac_reason[0], mac->mac_reason[1], 8490 mac->mac_reason[2], mac->mac_reason[3], 8491 mac->mac_reason[4], mac->mac_reason[5]); 8492 } 8493 } 8494 8495 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8496 bwn_intr_ucode_debug(mac); 8497 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8498 bwn_intr_tbtt_indication(mac); 8499 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8500 bwn_intr_atim_end(mac); 8501 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8502 bwn_intr_beacon(mac); 8503 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8504 bwn_intr_pmq(mac); 8505 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8506 bwn_intr_noise(mac); 8507 8508 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8509 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8510 bwn_dma_rx(mac->mac_method.dma.rx); 8511 rx = 1; 8512 } 8513 } else 8514 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8515 8516 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8517 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8518 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8519 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8520 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8521 8522 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8523 bwn_intr_txeof(mac); 8524 tx = 1; 8525 } 8526 8527 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8528 8529 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8530 int evt = BWN_LED_EVENT_NONE; 8531 8532 if (tx && rx) { 8533 if (sc->sc_rx_rate > sc->sc_tx_rate) 8534 evt = BWN_LED_EVENT_RX; 8535 else 8536 evt = BWN_LED_EVENT_TX; 8537 } else if (tx) { 8538 evt = BWN_LED_EVENT_TX; 8539 } else if (rx) { 8540 evt = BWN_LED_EVENT_RX; 8541 } else if (rx == 0) { 8542 evt = BWN_LED_EVENT_POLL; 8543 } 8544 8545 if (evt != BWN_LED_EVENT_NONE) 8546 bwn_led_event(mac, evt); 8547 } 8548 8549 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8550 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8551 bwn_start_locked(ifp); 8552 } 8553 8554 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8555 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8556 8557 BWN_UNLOCK(sc); 8558} 8559 8560static void 8561bwn_restart(struct bwn_mac *mac, const char *msg) 8562{ 8563 struct bwn_softc *sc = mac->mac_sc; 8564 struct ifnet *ifp = sc->sc_ifp; 8565 struct ieee80211com *ic = ifp->if_l2com; 8566 8567 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8568 return; 8569 8570 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8571 ieee80211_runtask(ic, &mac->mac_hwreset); 8572} 8573 8574static void 8575bwn_intr_ucode_debug(struct bwn_mac *mac) 8576{ 8577 struct bwn_softc *sc = mac->mac_sc; 8578 uint16_t reason; 8579 8580 if (mac->mac_fw.opensource == 0) 8581 return; 8582 8583 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8584 switch (reason) { 8585 case BWN_DEBUGINTR_PANIC: 8586 bwn_handle_fwpanic(mac); 8587 break; 8588 case BWN_DEBUGINTR_DUMP_SHM: 8589 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8590 break; 8591 case BWN_DEBUGINTR_DUMP_REGS: 8592 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8593 break; 8594 case BWN_DEBUGINTR_MARKER: 8595 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8596 break; 8597 default: 8598 device_printf(sc->sc_dev, 8599 "ucode debug unknown reason: %#x\n", reason); 8600 } 8601 8602 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8603 BWN_DEBUGINTR_ACK); 8604} 8605 8606static void 8607bwn_intr_tbtt_indication(struct bwn_mac *mac) 8608{ 8609 struct bwn_softc *sc = mac->mac_sc; 8610 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8611 8612 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8613 bwn_psctl(mac, 0); 8614 if (ic->ic_opmode == IEEE80211_M_IBSS) 8615 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8616} 8617 8618static void 8619bwn_intr_atim_end(struct bwn_mac *mac) 8620{ 8621 8622 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8623 BWN_WRITE_4(mac, BWN_MACCMD, 8624 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8625 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8626 } 8627} 8628 8629static void 8630bwn_intr_beacon(struct bwn_mac *mac) 8631{ 8632 struct bwn_softc *sc = mac->mac_sc; 8633 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8634 uint32_t cmd, beacon0, beacon1; 8635 8636 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8637 ic->ic_opmode == IEEE80211_M_MBSS) 8638 return; 8639 8640 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8641 8642 cmd = BWN_READ_4(mac, BWN_MACCMD); 8643 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8644 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8645 8646 if (beacon0 && beacon1) { 8647 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8648 mac->mac_intr_mask |= BWN_INTR_BEACON; 8649 return; 8650 } 8651 8652 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8653 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8654 bwn_load_beacon0(mac); 8655 bwn_load_beacon1(mac); 8656 cmd = BWN_READ_4(mac, BWN_MACCMD); 8657 cmd |= BWN_MACCMD_BEACON0_VALID; 8658 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8659 } else { 8660 if (!beacon0) { 8661 bwn_load_beacon0(mac); 8662 cmd = BWN_READ_4(mac, BWN_MACCMD); 8663 cmd |= BWN_MACCMD_BEACON0_VALID; 8664 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8665 } else if (!beacon1) { 8666 bwn_load_beacon1(mac); 8667 cmd = BWN_READ_4(mac, BWN_MACCMD); 8668 cmd |= BWN_MACCMD_BEACON1_VALID; 8669 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8670 } 8671 } 8672} 8673 8674static void 8675bwn_intr_pmq(struct bwn_mac *mac) 8676{ 8677 uint32_t tmp; 8678 8679 while (1) { 8680 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8681 if (!(tmp & 0x00000008)) 8682 break; 8683 } 8684 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8685} 8686 8687static void 8688bwn_intr_noise(struct bwn_mac *mac) 8689{ 8690 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8691 uint16_t tmp; 8692 uint8_t noise[4]; 8693 uint8_t i, j; 8694 int32_t average; 8695 8696 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8697 return; 8698 8699 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8700 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8701 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8702 noise[3] == 0x7f) 8703 goto new; 8704 8705 KASSERT(mac->mac_noise.noi_nsamples < 8, 8706 ("%s:%d: fail", __func__, __LINE__)); 8707 i = mac->mac_noise.noi_nsamples; 8708 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8709 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8710 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8711 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8712 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8713 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8714 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8715 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8716 mac->mac_noise.noi_nsamples++; 8717 if (mac->mac_noise.noi_nsamples == 8) { 8718 average = 0; 8719 for (i = 0; i < 8; i++) { 8720 for (j = 0; j < 4; j++) 8721 average += mac->mac_noise.noi_samples[i][j]; 8722 } 8723 average = (((average / 32) * 125) + 64) / 128; 8724 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8725 if (tmp >= 8) 8726 average += 2; 8727 else 8728 average -= 25; 8729 average -= (tmp == 8) ? 72 : 48; 8730 8731 mac->mac_stats.link_noise = average; 8732 mac->mac_noise.noi_running = 0; 8733 return; 8734 } 8735new: 8736 bwn_noise_gensample(mac); 8737} 8738 8739static int 8740bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8741{ 8742 struct bwn_mac *mac = prq->prq_mac; 8743 struct bwn_softc *sc = mac->mac_sc; 8744 unsigned int i; 8745 8746 BWN_ASSERT_LOCKED(sc); 8747 8748 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8749 return (0); 8750 8751 for (i = 0; i < 5000; i++) { 8752 if (bwn_pio_rxeof(prq) == 0) 8753 break; 8754 } 8755 if (i >= 5000) 8756 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8757 return ((i > 0) ? 1 : 0); 8758} 8759 8760static void 8761bwn_dma_rx(struct bwn_dma_ring *dr) 8762{ 8763 int slot, curslot; 8764 8765 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8766 curslot = dr->get_curslot(dr); 8767 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8768 ("%s:%d: fail", __func__, __LINE__)); 8769 8770 slot = dr->dr_curslot; 8771 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8772 bwn_dma_rxeof(dr, &slot); 8773 8774 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8775 BUS_DMASYNC_PREWRITE); 8776 8777 dr->set_curslot(dr, slot); 8778 dr->dr_curslot = slot; 8779} 8780 8781static void 8782bwn_intr_txeof(struct bwn_mac *mac) 8783{ 8784 struct bwn_txstatus stat; 8785 uint32_t stat0, stat1; 8786 uint16_t tmp; 8787 8788 BWN_ASSERT_LOCKED(mac->mac_sc); 8789 8790 while (1) { 8791 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8792 if (!(stat0 & 0x00000001)) 8793 break; 8794 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8795 8796 stat.cookie = (stat0 >> 16); 8797 stat.seq = (stat1 & 0x0000ffff); 8798 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8799 tmp = (stat0 & 0x0000ffff); 8800 stat.framecnt = ((tmp & 0xf000) >> 12); 8801 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8802 stat.sreason = ((tmp & 0x001c) >> 2); 8803 stat.pm = (tmp & 0x0080) ? 1 : 0; 8804 stat.im = (tmp & 0x0040) ? 1 : 0; 8805 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8806 stat.ack = (tmp & 0x0002) ? 1 : 0; 8807 8808 bwn_handle_txeof(mac, &stat); 8809 } 8810} 8811 8812static void 8813bwn_hwreset(void *arg, int npending) 8814{ 8815 struct bwn_mac *mac = arg; 8816 struct bwn_softc *sc = mac->mac_sc; 8817 int error = 0; 8818 int prev_status; 8819 8820 BWN_LOCK(sc); 8821 8822 prev_status = mac->mac_status; 8823 if (prev_status >= BWN_MAC_STATUS_STARTED) 8824 bwn_core_stop(mac); 8825 if (prev_status >= BWN_MAC_STATUS_INITED) 8826 bwn_core_exit(mac); 8827 8828 if (prev_status >= BWN_MAC_STATUS_INITED) { 8829 error = bwn_core_init(mac); 8830 if (error) 8831 goto out; 8832 } 8833 if (prev_status >= BWN_MAC_STATUS_STARTED) 8834 bwn_core_start(mac); 8835out: 8836 if (error) { 8837 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8838 sc->sc_curmac = NULL; 8839 } 8840 BWN_UNLOCK(sc); 8841} 8842 8843static void 8844bwn_handle_fwpanic(struct bwn_mac *mac) 8845{ 8846 struct bwn_softc *sc = mac->mac_sc; 8847 uint16_t reason; 8848 8849 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8850 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8851 8852 if (reason == BWN_FWPANIC_RESTART) 8853 bwn_restart(mac, "ucode panic"); 8854} 8855 8856static void 8857bwn_load_beacon0(struct bwn_mac *mac) 8858{ 8859 8860 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8861} 8862 8863static void 8864bwn_load_beacon1(struct bwn_mac *mac) 8865{ 8866 8867 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8868} 8869 8870static uint32_t 8871bwn_jssi_read(struct bwn_mac *mac) 8872{ 8873 uint32_t val = 0; 8874 8875 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8876 val <<= 16; 8877 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8878 8879 return (val); 8880} 8881 8882static void 8883bwn_noise_gensample(struct bwn_mac *mac) 8884{ 8885 uint32_t jssi = 0x7f7f7f7f; 8886 8887 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8888 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8889 BWN_WRITE_4(mac, BWN_MACCMD, 8890 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8891} 8892 8893static int 8894bwn_dma_freeslot(struct bwn_dma_ring *dr) 8895{ 8896 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8897 8898 return (dr->dr_numslots - dr->dr_usedslot); 8899} 8900 8901static int 8902bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8903{ 8904 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8905 8906 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8907 ("%s:%d: fail", __func__, __LINE__)); 8908 if (slot == dr->dr_numslots - 1) 8909 return (0); 8910 return (slot + 1); 8911} 8912 8913static void 8914bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8915{ 8916 struct bwn_mac *mac = dr->dr_mac; 8917 struct bwn_softc *sc = mac->mac_sc; 8918 struct bwn_dma *dma = &mac->mac_method.dma; 8919 struct bwn_dmadesc_generic *desc; 8920 struct bwn_dmadesc_meta *meta; 8921 struct bwn_rxhdr4 *rxhdr; 8922 struct ifnet *ifp = sc->sc_ifp; 8923 struct mbuf *m; 8924 uint32_t macstat; 8925 int32_t tmp; 8926 int cnt = 0; 8927 uint16_t len; 8928 8929 dr->getdesc(dr, *slot, &desc, &meta); 8930 8931 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8932 m = meta->mt_m; 8933 8934 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8935 ifp->if_ierrors++; 8936 return; 8937 } 8938 8939 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8940 len = le16toh(rxhdr->frame_len); 8941 if (len <= 0) { 8942 ifp->if_ierrors++; 8943 return; 8944 } 8945 if (bwn_dma_check_redzone(dr, m)) { 8946 device_printf(sc->sc_dev, "redzone error.\n"); 8947 bwn_dma_set_redzone(dr, m); 8948 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8949 BUS_DMASYNC_PREWRITE); 8950 return; 8951 } 8952 if (len > dr->dr_rx_bufsize) { 8953 tmp = len; 8954 while (1) { 8955 dr->getdesc(dr, *slot, &desc, &meta); 8956 bwn_dma_set_redzone(dr, meta->mt_m); 8957 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8958 BUS_DMASYNC_PREWRITE); 8959 *slot = bwn_dma_nextslot(dr, *slot); 8960 cnt++; 8961 tmp -= dr->dr_rx_bufsize; 8962 if (tmp <= 0) 8963 break; 8964 } 8965 device_printf(sc->sc_dev, "too small buffer " 8966 "(len %u buffer %u dropped %d)\n", 8967 len, dr->dr_rx_bufsize, cnt); 8968 return; 8969 } 8970 macstat = le32toh(rxhdr->mac_status); 8971 if (macstat & BWN_RX_MAC_FCSERR) { 8972 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8973 device_printf(sc->sc_dev, "RX drop\n"); 8974 return; 8975 } 8976 } 8977 8978 m->m_pkthdr.rcvif = ifp; 8979 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8980 m_adj(m, dr->dr_frameoffset); 8981 8982 bwn_rxeof(dr->dr_mac, m, rxhdr); 8983} 8984 8985static void 8986bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8987{ 8988 struct bwn_dma_ring *dr; 8989 struct bwn_dmadesc_generic *desc; 8990 struct bwn_dmadesc_meta *meta; 8991 struct bwn_pio_txqueue *tq; 8992 struct bwn_pio_txpkt *tp = NULL; 8993 struct bwn_softc *sc = mac->mac_sc; 8994 struct bwn_stats *stats = &mac->mac_stats; 8995 struct ieee80211_node *ni; 8996 struct ieee80211vap *vap; 8997 int slot; 8998 8999 BWN_ASSERT_LOCKED(mac->mac_sc); 9000 9001 if (status->im) 9002 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9003 if (status->ampdu) 9004 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9005 if (status->rtscnt) { 9006 if (status->rtscnt == 0xf) 9007 stats->rtsfail++; 9008 else 9009 stats->rts++; 9010 } 9011 9012 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9013 if (status->ack) { 9014 dr = bwn_dma_parse_cookie(mac, status, 9015 status->cookie, &slot); 9016 if (dr == NULL) { 9017 device_printf(sc->sc_dev, 9018 "failed to parse cookie\n"); 9019 return; 9020 } 9021 while (1) { 9022 dr->getdesc(dr, slot, &desc, &meta); 9023 if (meta->mt_islast) { 9024 ni = meta->mt_ni; 9025 vap = ni->ni_vap; 9026 ieee80211_ratectl_tx_complete(vap, ni, 9027 status->ack ? 9028 IEEE80211_RATECTL_TX_SUCCESS : 9029 IEEE80211_RATECTL_TX_FAILURE, 9030 NULL, 0); 9031 break; 9032 } 9033 slot = bwn_dma_nextslot(dr, slot); 9034 } 9035 } 9036 bwn_dma_handle_txeof(mac, status); 9037 } else { 9038 if (status->ack) { 9039 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9040 if (tq == NULL) { 9041 device_printf(sc->sc_dev, 9042 "failed to parse cookie\n"); 9043 return; 9044 } 9045 ni = tp->tp_ni; 9046 vap = ni->ni_vap; 9047 ieee80211_ratectl_tx_complete(vap, ni, 9048 status->ack ? 9049 IEEE80211_RATECTL_TX_SUCCESS : 9050 IEEE80211_RATECTL_TX_FAILURE, 9051 NULL, 0); 9052 } 9053 bwn_pio_handle_txeof(mac, status); 9054 } 9055 9056 bwn_phy_txpower_check(mac, 0); 9057} 9058 9059static uint8_t 9060bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9061{ 9062 struct bwn_mac *mac = prq->prq_mac; 9063 struct bwn_softc *sc = mac->mac_sc; 9064 struct bwn_rxhdr4 rxhdr; 9065 struct ifnet *ifp = sc->sc_ifp; 9066 struct mbuf *m; 9067 uint32_t ctl32, macstat, v32; 9068 unsigned int i, padding; 9069 uint16_t ctl16, len, v16; 9070 unsigned char *mp; 9071 char *data; 9072 9073 memset(&rxhdr, 0, sizeof(rxhdr)); 9074 9075 if (prq->prq_rev >= 8) { 9076 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9077 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9078 return (0); 9079 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9080 BWN_PIO8_RXCTL_FRAMEREADY); 9081 for (i = 0; i < 10; i++) { 9082 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9083 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9084 goto ready; 9085 DELAY(10); 9086 } 9087 } else { 9088 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9089 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9090 return (0); 9091 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9092 BWN_PIO_RXCTL_FRAMEREADY); 9093 for (i = 0; i < 10; i++) { 9094 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9095 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9096 goto ready; 9097 DELAY(10); 9098 } 9099 } 9100 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9101 return (1); 9102ready: 9103 if (prq->prq_rev >= 8) 9104 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9105 prq->prq_base + BWN_PIO8_RXDATA); 9106 else 9107 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9108 prq->prq_base + BWN_PIO_RXDATA); 9109 len = le16toh(rxhdr.frame_len); 9110 if (len > 0x700) { 9111 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9112 goto error; 9113 } 9114 if (len == 0) { 9115 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9116 goto error; 9117 } 9118 9119 macstat = le32toh(rxhdr.mac_status); 9120 if (macstat & BWN_RX_MAC_FCSERR) { 9121 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9122 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9123 goto error; 9124 } 9125 } 9126 9127 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9128 KASSERT(len + padding <= MCLBYTES, ("too big..\n")); 9129 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9130 if (m == NULL) { 9131 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9132 goto error; 9133 } 9134 mp = mtod(m, unsigned char *); 9135 if (prq->prq_rev >= 8) { 9136 siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3), 9137 prq->prq_base + BWN_PIO8_RXDATA); 9138 if (len & 3) { 9139 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9140 data = &(mp[len + padding - 1]); 9141 switch (len & 3) { 9142 case 3: 9143 *data = (v32 >> 16); 9144 data--; 9145 case 2: 9146 *data = (v32 >> 8); 9147 data--; 9148 case 1: 9149 *data = v32; 9150 } 9151 } 9152 } else { 9153 siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1), 9154 prq->prq_base + BWN_PIO_RXDATA); 9155 if (len & 1) { 9156 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9157 mp[len + padding - 1] = v16; 9158 } 9159 } 9160 9161 m->m_pkthdr.rcvif = ifp; 9162 m->m_len = m->m_pkthdr.len = len + padding; 9163 9164 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9165 9166 return (1); 9167error: 9168 if (prq->prq_rev >= 8) 9169 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9170 BWN_PIO8_RXCTL_DATAREADY); 9171 else 9172 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9173 return (1); 9174} 9175 9176static int 9177bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9178 struct bwn_dmadesc_meta *meta, int init) 9179{ 9180 struct bwn_mac *mac = dr->dr_mac; 9181 struct bwn_dma *dma = &mac->mac_method.dma; 9182 struct bwn_rxhdr4 *hdr; 9183 bus_dmamap_t map; 9184 bus_addr_t paddr; 9185 struct mbuf *m; 9186 int error; 9187 9188 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9189 if (m == NULL) { 9190 error = ENOBUFS; 9191 9192 /* 9193 * If the NIC is up and running, we need to: 9194 * - Clear RX buffer's header. 9195 * - Restore RX descriptor settings. 9196 */ 9197 if (init) 9198 return (error); 9199 else 9200 goto back; 9201 } 9202 m->m_len = m->m_pkthdr.len = MCLBYTES; 9203 9204 bwn_dma_set_redzone(dr, m); 9205 9206 /* 9207 * Try to load RX buf into temporary DMA map 9208 */ 9209 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9210 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9211 if (error) { 9212 m_freem(m); 9213 9214 /* 9215 * See the comment above 9216 */ 9217 if (init) 9218 return (error); 9219 else 9220 goto back; 9221 } 9222 9223 if (!init) 9224 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9225 meta->mt_m = m; 9226 meta->mt_paddr = paddr; 9227 9228 /* 9229 * Swap RX buf's DMA map with the loaded temporary one 9230 */ 9231 map = meta->mt_dmap; 9232 meta->mt_dmap = dr->dr_spare_dmap; 9233 dr->dr_spare_dmap = map; 9234 9235back: 9236 /* 9237 * Clear RX buf header 9238 */ 9239 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9240 bzero(hdr, sizeof(*hdr)); 9241 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9242 BUS_DMASYNC_PREWRITE); 9243 9244 /* 9245 * Setup RX buf descriptor 9246 */ 9247 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9248 sizeof(*hdr), 0, 0, 0); 9249 return (error); 9250} 9251 9252static void 9253bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9254 bus_size_t mapsz __unused, int error) 9255{ 9256 9257 if (!error) { 9258 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9259 *((bus_addr_t *)arg) = seg->ds_addr; 9260 } 9261} 9262 9263static int 9264bwn_hwrate2ieeerate(int rate) 9265{ 9266 9267 switch (rate) { 9268 case BWN_CCK_RATE_1MB: 9269 return (2); 9270 case BWN_CCK_RATE_2MB: 9271 return (4); 9272 case BWN_CCK_RATE_5MB: 9273 return (11); 9274 case BWN_CCK_RATE_11MB: 9275 return (22); 9276 case BWN_OFDM_RATE_6MB: 9277 return (12); 9278 case BWN_OFDM_RATE_9MB: 9279 return (18); 9280 case BWN_OFDM_RATE_12MB: 9281 return (24); 9282 case BWN_OFDM_RATE_18MB: 9283 return (36); 9284 case BWN_OFDM_RATE_24MB: 9285 return (48); 9286 case BWN_OFDM_RATE_36MB: 9287 return (72); 9288 case BWN_OFDM_RATE_48MB: 9289 return (96); 9290 case BWN_OFDM_RATE_54MB: 9291 return (108); 9292 default: 9293 printf("Ooops\n"); 9294 return (0); 9295 } 9296} 9297 9298static void 9299bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9300{ 9301 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9302 struct bwn_plcp6 *plcp; 9303 struct bwn_softc *sc = mac->mac_sc; 9304 struct ieee80211_frame_min *wh; 9305 struct ieee80211_node *ni; 9306 struct ifnet *ifp = sc->sc_ifp; 9307 struct ieee80211com *ic = ifp->if_l2com; 9308 uint32_t macstat; 9309 int padding, rate, rssi = 0, noise = 0, type; 9310 uint16_t phytype, phystat0, phystat3, chanstat; 9311 unsigned char *mp = mtod(m, unsigned char *); 9312 static int rx_mac_dec_rpt = 0; 9313 9314 BWN_ASSERT_LOCKED(sc); 9315 9316 phystat0 = le16toh(rxhdr->phy_status0); 9317 phystat3 = le16toh(rxhdr->phy_status3); 9318 macstat = le32toh(rxhdr->mac_status); 9319 chanstat = le16toh(rxhdr->channel); 9320 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9321 9322 if (macstat & BWN_RX_MAC_FCSERR) 9323 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9324 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9325 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9326 if (macstat & BWN_RX_MAC_DECERR) 9327 goto drop; 9328 9329 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9330 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9331 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9332 m->m_pkthdr.len); 9333 goto drop; 9334 } 9335 plcp = (struct bwn_plcp6 *)(mp + padding); 9336 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9337 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9338 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9339 m->m_pkthdr.len); 9340 goto drop; 9341 } 9342 wh = mtod(m, struct ieee80211_frame_min *); 9343 9344 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9345 device_printf(sc->sc_dev, 9346 "RX decryption attempted (old %d keyidx %#x)\n", 9347 BWN_ISOLDFMT(mac), 9348 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9349 9350 /* XXX calculating RSSI & noise & antenna */ 9351 9352 if (phystat0 & BWN_RX_PHYST0_OFDM) 9353 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9354 phytype == BWN_PHYTYPE_A); 9355 else 9356 rate = bwn_plcp_get_cckrate(mac, plcp); 9357 if (rate == -1) { 9358 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9359 goto drop; 9360 } 9361 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9362 9363 /* RX radio tap */ 9364 if (ieee80211_radiotap_active(ic)) 9365 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9366 m_adj(m, -IEEE80211_CRC_LEN); 9367 9368 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9369 noise = mac->mac_stats.link_noise; 9370 9371 BWN_UNLOCK(sc); 9372 9373 ni = ieee80211_find_rxnode(ic, wh); 9374 if (ni != NULL) { 9375 type = ieee80211_input(ni, m, rssi, noise); 9376 ieee80211_free_node(ni); 9377 } else 9378 type = ieee80211_input_all(ic, m, rssi, noise); 9379 9380 BWN_LOCK(sc); 9381 return; 9382drop: 9383 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9384} 9385 9386static void 9387bwn_dma_handle_txeof(struct bwn_mac *mac, 9388 const struct bwn_txstatus *status) 9389{ 9390 struct bwn_dma *dma = &mac->mac_method.dma; 9391 struct bwn_dma_ring *dr; 9392 struct bwn_dmadesc_generic *desc; 9393 struct bwn_dmadesc_meta *meta; 9394 struct bwn_softc *sc = mac->mac_sc; 9395 struct ieee80211_node *ni; 9396 struct ifnet *ifp = sc->sc_ifp; 9397 struct mbuf *m; 9398 int slot; 9399 9400 BWN_ASSERT_LOCKED(sc); 9401 9402 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9403 if (dr == NULL) { 9404 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9405 return; 9406 } 9407 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9408 9409 while (1) { 9410 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9411 ("%s:%d: fail", __func__, __LINE__)); 9412 dr->getdesc(dr, slot, &desc, &meta); 9413 9414 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9415 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9416 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9417 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9418 9419 if (meta->mt_islast) { 9420 KASSERT(meta->mt_m != NULL, 9421 ("%s:%d: fail", __func__, __LINE__)); 9422 9423 ni = meta->mt_ni; 9424 m = meta->mt_m; 9425 if (ni != NULL) { 9426 /* 9427 * Do any tx complete callback. Note this must 9428 * be done before releasing the node reference. 9429 */ 9430 if (m->m_flags & M_TXCB) 9431 ieee80211_process_callback(ni, m, 0); 9432 ieee80211_free_node(ni); 9433 meta->mt_ni = NULL; 9434 } 9435 m_freem(m); 9436 meta->mt_m = NULL; 9437 } else { 9438 KASSERT(meta->mt_m == NULL, 9439 ("%s:%d: fail", __func__, __LINE__)); 9440 } 9441 9442 dr->dr_usedslot--; 9443 if (meta->mt_islast) { 9444 ifp->if_opackets++; 9445 break; 9446 } 9447 slot = bwn_dma_nextslot(dr, slot); 9448 } 9449 sc->sc_watchdog_timer = 0; 9450 if (dr->dr_stop) { 9451 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9452 ("%s:%d: fail", __func__, __LINE__)); 9453 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9454 dr->dr_stop = 0; 9455 } 9456} 9457 9458static void 9459bwn_pio_handle_txeof(struct bwn_mac *mac, 9460 const struct bwn_txstatus *status) 9461{ 9462 struct bwn_pio_txqueue *tq; 9463 struct bwn_pio_txpkt *tp = NULL; 9464 struct bwn_softc *sc = mac->mac_sc; 9465 struct ifnet *ifp = sc->sc_ifp; 9466 9467 BWN_ASSERT_LOCKED(sc); 9468 9469 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9470 if (tq == NULL) 9471 return; 9472 9473 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9474 tq->tq_free++; 9475 9476 if (tp->tp_ni != NULL) { 9477 /* 9478 * Do any tx complete callback. Note this must 9479 * be done before releasing the node reference. 9480 */ 9481 if (tp->tp_m->m_flags & M_TXCB) 9482 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9483 ieee80211_free_node(tp->tp_ni); 9484 tp->tp_ni = NULL; 9485 } 9486 m_freem(tp->tp_m); 9487 tp->tp_m = NULL; 9488 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9489 9490 ifp->if_opackets++; 9491 9492 sc->sc_watchdog_timer = 0; 9493 if (tq->tq_stop) { 9494 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9495 tq->tq_stop = 0; 9496 } 9497} 9498 9499static void 9500bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9501{ 9502 struct bwn_softc *sc = mac->mac_sc; 9503 struct bwn_phy *phy = &mac->mac_phy; 9504 struct ifnet *ifp = sc->sc_ifp; 9505 struct ieee80211com *ic = ifp->if_l2com; 9506 unsigned long now; 9507 int result; 9508 9509 BWN_GETTIME(now); 9510 9511 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9512 return; 9513 phy->nexttime = now + 2 * 1000; 9514 9515 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9516 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9517 return; 9518 9519 if (phy->recalc_txpwr != NULL) { 9520 result = phy->recalc_txpwr(mac, 9521 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9522 if (result == BWN_TXPWR_RES_DONE) 9523 return; 9524 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9525 ("%s: fail", __func__)); 9526 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9527 9528 ieee80211_runtask(ic, &mac->mac_txpower); 9529 } 9530} 9531 9532static uint16_t 9533bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9534{ 9535 9536 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9537} 9538 9539static uint32_t 9540bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9541{ 9542 9543 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9544} 9545 9546static void 9547bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9548{ 9549 9550 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9551} 9552 9553static void 9554bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9555{ 9556 9557 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9558} 9559 9560static int 9561bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9562{ 9563 9564 switch (rate) { 9565 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9566 case 12: 9567 return (BWN_OFDM_RATE_6MB); 9568 case 18: 9569 return (BWN_OFDM_RATE_9MB); 9570 case 24: 9571 return (BWN_OFDM_RATE_12MB); 9572 case 36: 9573 return (BWN_OFDM_RATE_18MB); 9574 case 48: 9575 return (BWN_OFDM_RATE_24MB); 9576 case 72: 9577 return (BWN_OFDM_RATE_36MB); 9578 case 96: 9579 return (BWN_OFDM_RATE_48MB); 9580 case 108: 9581 return (BWN_OFDM_RATE_54MB); 9582 /* CCK rates (NB: not IEEE std, device-specific) */ 9583 case 2: 9584 return (BWN_CCK_RATE_1MB); 9585 case 4: 9586 return (BWN_CCK_RATE_2MB); 9587 case 11: 9588 return (BWN_CCK_RATE_5MB); 9589 case 22: 9590 return (BWN_CCK_RATE_11MB); 9591 } 9592 9593 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9594 return (BWN_CCK_RATE_1MB); 9595} 9596 9597static int 9598bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9599 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9600{ 9601 const struct bwn_phy *phy = &mac->mac_phy; 9602 struct bwn_softc *sc = mac->mac_sc; 9603 struct ieee80211_frame *wh; 9604 struct ieee80211_frame *protwh; 9605 struct ieee80211_frame_cts *cts; 9606 struct ieee80211_frame_rts *rts; 9607 const struct ieee80211_txparam *tp; 9608 struct ieee80211vap *vap = ni->ni_vap; 9609 struct ifnet *ifp = sc->sc_ifp; 9610 struct ieee80211com *ic = ifp->if_l2com; 9611 struct mbuf *mprot; 9612 unsigned int len; 9613 uint32_t macctl = 0; 9614 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9615 uint16_t phyctl = 0; 9616 uint8_t rate, rate_fb; 9617 9618 wh = mtod(m, struct ieee80211_frame *); 9619 memset(txhdr, 0, sizeof(*txhdr)); 9620 9621 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9622 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9623 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9624 9625 /* 9626 * Find TX rate 9627 */ 9628 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9629 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9630 rate = rate_fb = tp->mgmtrate; 9631 else if (ismcast) 9632 rate = rate_fb = tp->mcastrate; 9633 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9634 rate = rate_fb = tp->ucastrate; 9635 else { 9636 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9637 rate = ni->ni_txrate; 9638 9639 if (rix > 0) 9640 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9641 IEEE80211_RATE_VAL; 9642 else 9643 rate_fb = rate; 9644 } 9645 9646 sc->sc_tx_rate = rate; 9647 9648 rate = bwn_ieeerate2hwrate(sc, rate); 9649 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9650 9651 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9652 bwn_plcp_getcck(rate); 9653 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9654 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9655 9656 if ((rate_fb == rate) || 9657 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9658 (*(u_int16_t *)wh->i_dur == htole16(0))) 9659 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9660 else 9661 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9662 m->m_pkthdr.len, rate, isshort); 9663 9664 /* XXX TX encryption */ 9665 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9666 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9667 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9668 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9669 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9670 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9671 9672 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9673 BWN_TX_EFT_FB_CCK; 9674 txhdr->chan = phy->chan; 9675 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9676 BWN_TX_PHY_ENC_CCK; 9677 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9678 rate == BWN_CCK_RATE_11MB)) 9679 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9680 9681 /* XXX TX antenna selection */ 9682 9683 switch (bwn_antenna_sanitize(mac, 0)) { 9684 case 0: 9685 phyctl |= BWN_TX_PHY_ANT01AUTO; 9686 break; 9687 case 1: 9688 phyctl |= BWN_TX_PHY_ANT0; 9689 break; 9690 case 2: 9691 phyctl |= BWN_TX_PHY_ANT1; 9692 break; 9693 case 3: 9694 phyctl |= BWN_TX_PHY_ANT2; 9695 break; 9696 case 4: 9697 phyctl |= BWN_TX_PHY_ANT3; 9698 break; 9699 default: 9700 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9701 } 9702 9703 if (!ismcast) 9704 macctl |= BWN_TX_MAC_ACK; 9705 9706 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9707 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9708 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9709 macctl |= BWN_TX_MAC_LONGFRAME; 9710 9711 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9712 /* XXX RTS rate is always 1MB??? */ 9713 rts_rate = BWN_CCK_RATE_1MB; 9714 rts_rate_fb = bwn_get_fbrate(rts_rate); 9715 9716 protdur = ieee80211_compute_duration(ic->ic_rt, 9717 m->m_pkthdr.len, rate, isshort) + 9718 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9719 9720 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9721 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9722 (txhdr->body.old.rts_frame) : 9723 (txhdr->body.new.rts_frame)); 9724 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9725 protdur); 9726 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9727 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9728 mprot->m_pkthdr.len); 9729 m_freem(mprot); 9730 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9731 len = sizeof(struct ieee80211_frame_cts); 9732 } else { 9733 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9734 (txhdr->body.old.rts_frame) : 9735 (txhdr->body.new.rts_frame)); 9736 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9737 isshort); 9738 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9739 wh->i_addr2, protdur); 9740 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9741 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9742 mprot->m_pkthdr.len); 9743 m_freem(mprot); 9744 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9745 len = sizeof(struct ieee80211_frame_rts); 9746 } 9747 len += IEEE80211_CRC_LEN; 9748 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9749 &txhdr->body.old.rts_plcp : 9750 &txhdr->body.new.rts_plcp), len, rts_rate); 9751 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9752 rts_rate_fb); 9753 9754 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9755 (&txhdr->body.old.rts_frame) : 9756 (&txhdr->body.new.rts_frame)); 9757 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9758 9759 if (BWN_ISOFDMRATE(rts_rate)) { 9760 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9761 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9762 } else { 9763 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9764 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9765 } 9766 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9767 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9768 } 9769 9770 if (BWN_ISOLDFMT(mac)) 9771 txhdr->body.old.cookie = htole16(cookie); 9772 else 9773 txhdr->body.new.cookie = htole16(cookie); 9774 9775 txhdr->macctl = htole32(macctl); 9776 txhdr->phyctl = htole16(phyctl); 9777 9778 /* 9779 * TX radio tap 9780 */ 9781 if (ieee80211_radiotap_active_vap(vap)) { 9782 sc->sc_tx_th.wt_flags = 0; 9783 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9784 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9785 if (isshort && 9786 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9787 rate == BWN_CCK_RATE_11MB)) 9788 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9789 sc->sc_tx_th.wt_rate = rate; 9790 9791 ieee80211_radiotap_tx(vap, m); 9792 } 9793 9794 return (0); 9795} 9796 9797static void 9798bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9799 const uint8_t rate) 9800{ 9801 uint32_t d, plen; 9802 uint8_t *raw = plcp->o.raw; 9803 9804 if (BWN_ISOFDMRATE(rate)) { 9805 d = bwn_plcp_getofdm(rate); 9806 KASSERT(!(octets & 0xf000), 9807 ("%s:%d: fail", __func__, __LINE__)); 9808 d |= (octets << 5); 9809 plcp->o.data = htole32(d); 9810 } else { 9811 plen = octets * 16 / rate; 9812 if ((octets * 16 % rate) > 0) { 9813 plen++; 9814 if ((rate == BWN_CCK_RATE_11MB) 9815 && ((octets * 8 % 11) < 4)) { 9816 raw[1] = 0x84; 9817 } else 9818 raw[1] = 0x04; 9819 } else 9820 raw[1] = 0x04; 9821 plcp->o.data |= htole32(plen << 16); 9822 raw[0] = bwn_plcp_getcck(rate); 9823 } 9824} 9825 9826static uint8_t 9827bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9828{ 9829 struct bwn_softc *sc = mac->mac_sc; 9830 uint8_t mask; 9831 9832 if (n == 0) 9833 return (0); 9834 if (mac->mac_phy.gmode) 9835 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9836 else 9837 mask = siba_sprom_get_ant_a(sc->sc_dev); 9838 if (!(mask & (1 << (n - 1)))) 9839 return (0); 9840 return (n); 9841} 9842 9843static uint8_t 9844bwn_get_fbrate(uint8_t bitrate) 9845{ 9846 switch (bitrate) { 9847 case BWN_CCK_RATE_1MB: 9848 return (BWN_CCK_RATE_1MB); 9849 case BWN_CCK_RATE_2MB: 9850 return (BWN_CCK_RATE_1MB); 9851 case BWN_CCK_RATE_5MB: 9852 return (BWN_CCK_RATE_2MB); 9853 case BWN_CCK_RATE_11MB: 9854 return (BWN_CCK_RATE_5MB); 9855 case BWN_OFDM_RATE_6MB: 9856 return (BWN_CCK_RATE_5MB); 9857 case BWN_OFDM_RATE_9MB: 9858 return (BWN_OFDM_RATE_6MB); 9859 case BWN_OFDM_RATE_12MB: 9860 return (BWN_OFDM_RATE_9MB); 9861 case BWN_OFDM_RATE_18MB: 9862 return (BWN_OFDM_RATE_12MB); 9863 case BWN_OFDM_RATE_24MB: 9864 return (BWN_OFDM_RATE_18MB); 9865 case BWN_OFDM_RATE_36MB: 9866 return (BWN_OFDM_RATE_24MB); 9867 case BWN_OFDM_RATE_48MB: 9868 return (BWN_OFDM_RATE_36MB); 9869 case BWN_OFDM_RATE_54MB: 9870 return (BWN_OFDM_RATE_48MB); 9871 } 9872 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9873 return (0); 9874} 9875 9876static uint32_t 9877bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9878 uint32_t ctl, const void *_data, int len) 9879{ 9880 struct bwn_softc *sc = mac->mac_sc; 9881 uint32_t value = 0; 9882 const uint8_t *data = _data; 9883 9884 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9885 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9886 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9887 9888 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9889 tq->tq_base + BWN_PIO8_TXDATA); 9890 if (len & 3) { 9891 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9892 BWN_PIO8_TXCTL_24_31); 9893 data = &(data[len - 1]); 9894 switch (len & 3) { 9895 case 3: 9896 ctl |= BWN_PIO8_TXCTL_16_23; 9897 value |= (uint32_t)(*data) << 16; 9898 data--; 9899 case 2: 9900 ctl |= BWN_PIO8_TXCTL_8_15; 9901 value |= (uint32_t)(*data) << 8; 9902 data--; 9903 case 1: 9904 value |= (uint32_t)(*data); 9905 } 9906 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9907 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9908 } 9909 9910 return (ctl); 9911} 9912 9913static void 9914bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9915 uint16_t offset, uint32_t value) 9916{ 9917 9918 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9919} 9920 9921static uint16_t 9922bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9923 uint16_t ctl, const void *_data, int len) 9924{ 9925 struct bwn_softc *sc = mac->mac_sc; 9926 const uint8_t *data = _data; 9927 9928 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9929 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9930 9931 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9932 tq->tq_base + BWN_PIO_TXDATA); 9933 if (len & 1) { 9934 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9935 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9936 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9937 } 9938 9939 return (ctl); 9940} 9941 9942static uint16_t 9943bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9944 uint16_t ctl, struct mbuf *m0) 9945{ 9946 int i, j = 0; 9947 uint16_t data = 0; 9948 const uint8_t *buf; 9949 struct mbuf *m = m0; 9950 9951 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9952 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9953 9954 for (; m != NULL; m = m->m_next) { 9955 buf = mtod(m, const uint8_t *); 9956 for (i = 0; i < m->m_len; i++) { 9957 if (!((j++) % 2)) 9958 data |= buf[i]; 9959 else { 9960 data |= (buf[i] << 8); 9961 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9962 data = 0; 9963 } 9964 } 9965 } 9966 if (m0->m_pkthdr.len % 2) { 9967 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9968 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9969 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9970 } 9971 9972 return (ctl); 9973} 9974 9975static void 9976bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9977{ 9978 9979 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9980 return; 9981 BWN_WRITE_2(mac, 0x684, 510 + time); 9982 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9983} 9984 9985static struct bwn_dma_ring * 9986bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9987{ 9988 9989 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9990 return (mac->mac_method.dma.wme[WME_AC_BE]); 9991 9992 switch (prio) { 9993 case 3: 9994 return (mac->mac_method.dma.wme[WME_AC_VO]); 9995 case 2: 9996 return (mac->mac_method.dma.wme[WME_AC_VI]); 9997 case 0: 9998 return (mac->mac_method.dma.wme[WME_AC_BE]); 9999 case 1: 10000 return (mac->mac_method.dma.wme[WME_AC_BK]); 10001 } 10002 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10003 return (NULL); 10004} 10005 10006static int 10007bwn_dma_getslot(struct bwn_dma_ring *dr) 10008{ 10009 int slot; 10010 10011 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10012 10013 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10014 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10015 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10016 10017 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10018 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10019 dr->dr_curslot = slot; 10020 dr->dr_usedslot++; 10021 10022 return (slot); 10023} 10024 10025static int 10026bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10027{ 10028 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10029 unsigned int a, b, c, d; 10030 unsigned int avg; 10031 uint32_t tmp; 10032 10033 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10034 a = tmp & 0xff; 10035 b = (tmp >> 8) & 0xff; 10036 c = (tmp >> 16) & 0xff; 10037 d = (tmp >> 24) & 0xff; 10038 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10039 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10040 return (ENOENT); 10041 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10042 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10043 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10044 10045 if (ofdm) { 10046 a = (a + 32) & 0x3f; 10047 b = (b + 32) & 0x3f; 10048 c = (c + 32) & 0x3f; 10049 d = (d + 32) & 0x3f; 10050 } 10051 10052 avg = (a + b + c + d + 2) / 4; 10053 if (ofdm) { 10054 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10055 & BWN_HF_4DB_CCK_POWERBOOST) 10056 avg = (avg >= 13) ? (avg - 13) : 0; 10057 } 10058 return (avg); 10059} 10060 10061static void 10062bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10063{ 10064 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10065 int rfatt = *rfattp; 10066 int bbatt = *bbattp; 10067 10068 while (1) { 10069 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10070 break; 10071 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10072 break; 10073 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10074 break; 10075 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10076 break; 10077 if (bbatt > lo->bbatt.max) { 10078 bbatt -= 4; 10079 rfatt += 1; 10080 continue; 10081 } 10082 if (bbatt < lo->bbatt.min) { 10083 bbatt += 4; 10084 rfatt -= 1; 10085 continue; 10086 } 10087 if (rfatt > lo->rfatt.max) { 10088 rfatt -= 1; 10089 bbatt += 4; 10090 continue; 10091 } 10092 if (rfatt < lo->rfatt.min) { 10093 rfatt += 1; 10094 bbatt -= 4; 10095 continue; 10096 } 10097 break; 10098 } 10099 10100 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10101 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10102} 10103 10104static void 10105bwn_phy_lock(struct bwn_mac *mac) 10106{ 10107 struct bwn_softc *sc = mac->mac_sc; 10108 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10109 10110 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10111 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10112 10113 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10114 bwn_psctl(mac, BWN_PS_AWAKE); 10115} 10116 10117static void 10118bwn_phy_unlock(struct bwn_mac *mac) 10119{ 10120 struct bwn_softc *sc = mac->mac_sc; 10121 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10122 10123 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10124 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10125 10126 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10127 bwn_psctl(mac, 0); 10128} 10129 10130static void 10131bwn_rf_lock(struct bwn_mac *mac) 10132{ 10133 10134 BWN_WRITE_4(mac, BWN_MACCTL, 10135 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10136 BWN_READ_4(mac, BWN_MACCTL); 10137 DELAY(10); 10138} 10139 10140static void 10141bwn_rf_unlock(struct bwn_mac *mac) 10142{ 10143 10144 BWN_READ_2(mac, BWN_PHYVER); 10145 BWN_WRITE_4(mac, BWN_MACCTL, 10146 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10147} 10148 10149static struct bwn_pio_txqueue * 10150bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10151 struct bwn_pio_txpkt **pack) 10152{ 10153 struct bwn_pio *pio = &mac->mac_method.pio; 10154 struct bwn_pio_txqueue *tq = NULL; 10155 unsigned int index; 10156 10157 switch (cookie & 0xf000) { 10158 case 0x1000: 10159 tq = &pio->wme[WME_AC_BK]; 10160 break; 10161 case 0x2000: 10162 tq = &pio->wme[WME_AC_BE]; 10163 break; 10164 case 0x3000: 10165 tq = &pio->wme[WME_AC_VI]; 10166 break; 10167 case 0x4000: 10168 tq = &pio->wme[WME_AC_VO]; 10169 break; 10170 case 0x5000: 10171 tq = &pio->mcast; 10172 break; 10173 } 10174 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10175 if (tq == NULL) 10176 return (NULL); 10177 index = (cookie & 0x0fff); 10178 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10179 if (index >= N(tq->tq_pkts)) 10180 return (NULL); 10181 *pack = &tq->tq_pkts[index]; 10182 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10183 return (tq); 10184} 10185 10186static void 10187bwn_txpwr(void *arg, int npending) 10188{ 10189 struct bwn_mac *mac = arg; 10190 struct bwn_softc *sc = mac->mac_sc; 10191 10192 BWN_LOCK(sc); 10193 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10194 mac->mac_phy.set_txpwr != NULL) 10195 mac->mac_phy.set_txpwr(mac); 10196 BWN_UNLOCK(sc); 10197} 10198 10199static void 10200bwn_task_15s(struct bwn_mac *mac) 10201{ 10202 uint16_t reg; 10203 10204 if (mac->mac_fw.opensource) { 10205 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10206 if (reg) { 10207 bwn_restart(mac, "fw watchdog"); 10208 return; 10209 } 10210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10211 } 10212 if (mac->mac_phy.task_15s) 10213 mac->mac_phy.task_15s(mac); 10214 10215 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10216} 10217 10218static void 10219bwn_task_30s(struct bwn_mac *mac) 10220{ 10221 10222 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10223 return; 10224 mac->mac_noise.noi_running = 1; 10225 mac->mac_noise.noi_nsamples = 0; 10226 10227 bwn_noise_gensample(mac); 10228} 10229 10230static void 10231bwn_task_60s(struct bwn_mac *mac) 10232{ 10233 10234 if (mac->mac_phy.task_60s) 10235 mac->mac_phy.task_60s(mac); 10236 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10237} 10238 10239static void 10240bwn_tasks(void *arg) 10241{ 10242 struct bwn_mac *mac = arg; 10243 struct bwn_softc *sc = mac->mac_sc; 10244 10245 BWN_ASSERT_LOCKED(sc); 10246 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10247 return; 10248 10249 if (mac->mac_task_state % 4 == 0) 10250 bwn_task_60s(mac); 10251 if (mac->mac_task_state % 2 == 0) 10252 bwn_task_30s(mac); 10253 bwn_task_15s(mac); 10254 10255 mac->mac_task_state++; 10256 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10257} 10258 10259static int 10260bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10261{ 10262 struct bwn_softc *sc = mac->mac_sc; 10263 10264 KASSERT(a == 0, ("not support APHY\n")); 10265 10266 switch (plcp->o.raw[0] & 0xf) { 10267 case 0xb: 10268 return (BWN_OFDM_RATE_6MB); 10269 case 0xf: 10270 return (BWN_OFDM_RATE_9MB); 10271 case 0xa: 10272 return (BWN_OFDM_RATE_12MB); 10273 case 0xe: 10274 return (BWN_OFDM_RATE_18MB); 10275 case 0x9: 10276 return (BWN_OFDM_RATE_24MB); 10277 case 0xd: 10278 return (BWN_OFDM_RATE_36MB); 10279 case 0x8: 10280 return (BWN_OFDM_RATE_48MB); 10281 case 0xc: 10282 return (BWN_OFDM_RATE_54MB); 10283 } 10284 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10285 plcp->o.raw[0] & 0xf); 10286 return (-1); 10287} 10288 10289static int 10290bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10291{ 10292 struct bwn_softc *sc = mac->mac_sc; 10293 10294 switch (plcp->o.raw[0]) { 10295 case 0x0a: 10296 return (BWN_CCK_RATE_1MB); 10297 case 0x14: 10298 return (BWN_CCK_RATE_2MB); 10299 case 0x37: 10300 return (BWN_CCK_RATE_5MB); 10301 case 0x6e: 10302 return (BWN_CCK_RATE_11MB); 10303 } 10304 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10305 return (-1); 10306} 10307 10308static void 10309bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10310 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10311 int rssi, int noise) 10312{ 10313 struct bwn_softc *sc = mac->mac_sc; 10314 const struct ieee80211_frame_min *wh; 10315 uint64_t tsf; 10316 uint16_t low_mactime_now; 10317 10318 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10319 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10320 10321 wh = mtod(m, const struct ieee80211_frame_min *); 10322 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10323 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10324 10325 bwn_tsf_read(mac, &tsf); 10326 low_mactime_now = tsf; 10327 tsf = tsf & ~0xffffULL; 10328 tsf += le16toh(rxhdr->mac_time); 10329 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10330 tsf -= 0x10000; 10331 10332 sc->sc_rx_th.wr_tsf = tsf; 10333 sc->sc_rx_th.wr_rate = rate; 10334 sc->sc_rx_th.wr_antsignal = rssi; 10335 sc->sc_rx_th.wr_antnoise = noise; 10336} 10337 10338static void 10339bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10340{ 10341 uint32_t low, high; 10342 10343 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10344 ("%s:%d: fail", __func__, __LINE__)); 10345 10346 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10347 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10348 *tsf = high; 10349 *tsf <<= 32; 10350 *tsf |= low; 10351} 10352 10353static int 10354bwn_dma_attach(struct bwn_mac *mac) 10355{ 10356 struct bwn_dma *dma = &mac->mac_method.dma; 10357 struct bwn_softc *sc = mac->mac_sc; 10358 bus_addr_t lowaddr = 0; 10359 int error; 10360 10361 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10362 return (0); 10363 10364 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10365 10366 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10367 10368 dma->dmatype = bwn_dma_gettype(mac); 10369 if (dma->dmatype == BWN_DMA_30BIT) 10370 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10371 else if (dma->dmatype == BWN_DMA_32BIT) 10372 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10373 else 10374 lowaddr = BUS_SPACE_MAXADDR; 10375 10376 /* 10377 * Create top level DMA tag 10378 */ 10379 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10380 BWN_ALIGN, 0, /* alignment, bounds */ 10381 lowaddr, /* lowaddr */ 10382 BUS_SPACE_MAXADDR, /* highaddr */ 10383 NULL, NULL, /* filter, filterarg */ 10384 MAXBSIZE, /* maxsize */ 10385 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10386 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10387 0, /* flags */ 10388 NULL, NULL, /* lockfunc, lockarg */ 10389 &dma->parent_dtag); 10390 if (error) { 10391 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10392 return (error); 10393 } 10394 10395 /* 10396 * Create TX/RX mbuf DMA tag 10397 */ 10398 error = bus_dma_tag_create(dma->parent_dtag, 10399 1, 10400 0, 10401 BUS_SPACE_MAXADDR, 10402 BUS_SPACE_MAXADDR, 10403 NULL, NULL, 10404 MCLBYTES, 10405 1, 10406 BUS_SPACE_MAXSIZE_32BIT, 10407 0, 10408 NULL, NULL, 10409 &dma->rxbuf_dtag); 10410 if (error) { 10411 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10412 goto fail0; 10413 } 10414 error = bus_dma_tag_create(dma->parent_dtag, 10415 1, 10416 0, 10417 BUS_SPACE_MAXADDR, 10418 BUS_SPACE_MAXADDR, 10419 NULL, NULL, 10420 MCLBYTES, 10421 1, 10422 BUS_SPACE_MAXSIZE_32BIT, 10423 0, 10424 NULL, NULL, 10425 &dma->txbuf_dtag); 10426 if (error) { 10427 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10428 goto fail1; 10429 } 10430 10431 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10432 if (!dma->wme[WME_AC_BK]) 10433 goto fail2; 10434 10435 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10436 if (!dma->wme[WME_AC_BE]) 10437 goto fail3; 10438 10439 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10440 if (!dma->wme[WME_AC_VI]) 10441 goto fail4; 10442 10443 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10444 if (!dma->wme[WME_AC_VO]) 10445 goto fail5; 10446 10447 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10448 if (!dma->mcast) 10449 goto fail6; 10450 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10451 if (!dma->rx) 10452 goto fail7; 10453 10454 return (error); 10455 10456fail7: bwn_dma_ringfree(&dma->mcast); 10457fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10458fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10459fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10460fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10461fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10462fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10463fail0: bus_dma_tag_destroy(dma->parent_dtag); 10464 return (error); 10465} 10466 10467static struct bwn_dma_ring * 10468bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10469 uint16_t cookie, int *slot) 10470{ 10471 struct bwn_dma *dma = &mac->mac_method.dma; 10472 struct bwn_dma_ring *dr; 10473 struct bwn_softc *sc = mac->mac_sc; 10474 10475 BWN_ASSERT_LOCKED(mac->mac_sc); 10476 10477 switch (cookie & 0xf000) { 10478 case 0x1000: 10479 dr = dma->wme[WME_AC_BK]; 10480 break; 10481 case 0x2000: 10482 dr = dma->wme[WME_AC_BE]; 10483 break; 10484 case 0x3000: 10485 dr = dma->wme[WME_AC_VI]; 10486 break; 10487 case 0x4000: 10488 dr = dma->wme[WME_AC_VO]; 10489 break; 10490 case 0x5000: 10491 dr = dma->mcast; 10492 break; 10493 default: 10494 dr = NULL; 10495 KASSERT(0 == 1, 10496 ("invalid cookie value %d", cookie & 0xf000)); 10497 } 10498 *slot = (cookie & 0x0fff); 10499 if (*slot < 0 || *slot >= dr->dr_numslots) { 10500 /* 10501 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10502 * that it occurs events which have same H/W sequence numbers. 10503 * When it's occurred just prints a WARNING msgs and ignores. 10504 */ 10505 KASSERT(status->seq == dma->lastseq, 10506 ("%s:%d: fail", __func__, __LINE__)); 10507 device_printf(sc->sc_dev, 10508 "out of slot ranges (0 < %d < %d)\n", *slot, 10509 dr->dr_numslots); 10510 return (NULL); 10511 } 10512 dma->lastseq = status->seq; 10513 return (dr); 10514} 10515 10516static void 10517bwn_dma_stop(struct bwn_mac *mac) 10518{ 10519 struct bwn_dma *dma; 10520 10521 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10522 return; 10523 dma = &mac->mac_method.dma; 10524 10525 bwn_dma_ringstop(&dma->rx); 10526 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10527 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10528 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10529 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10530 bwn_dma_ringstop(&dma->mcast); 10531} 10532 10533static void 10534bwn_dma_ringstop(struct bwn_dma_ring **dr) 10535{ 10536 10537 if (dr == NULL) 10538 return; 10539 10540 bwn_dma_cleanup(*dr); 10541} 10542 10543static void 10544bwn_pio_stop(struct bwn_mac *mac) 10545{ 10546 struct bwn_pio *pio; 10547 10548 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10549 return; 10550 pio = &mac->mac_method.pio; 10551 10552 bwn_destroy_queue_tx(&pio->mcast); 10553 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10554 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10557} 10558 10559static void 10560bwn_led_attach(struct bwn_mac *mac) 10561{ 10562 struct bwn_softc *sc = mac->mac_sc; 10563 const uint8_t *led_act = NULL; 10564 uint16_t val[BWN_LED_MAX]; 10565 int i; 10566 10567 sc->sc_led_idle = (2350 * hz) / 1000; 10568 sc->sc_led_blink = 1; 10569 10570 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10571 if (siba_get_pci_subvendor(sc->sc_dev) == 10572 bwn_vendor_led_act[i].vid) { 10573 led_act = bwn_vendor_led_act[i].led_act; 10574 break; 10575 } 10576 } 10577 if (led_act == NULL) 10578 led_act = bwn_default_led_act; 10579 10580 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10581 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10582 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10583 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10584 10585 for (i = 0; i < BWN_LED_MAX; ++i) { 10586 struct bwn_led *led = &sc->sc_leds[i]; 10587 10588 if (val[i] == 0xff) { 10589 led->led_act = led_act[i]; 10590 } else { 10591 if (val[i] & BWN_LED_ACT_LOW) 10592 led->led_flags |= BWN_LED_F_ACTLOW; 10593 led->led_act = val[i] & BWN_LED_ACT_MASK; 10594 } 10595 led->led_mask = (1 << i); 10596 10597 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10598 led->led_act == BWN_LED_ACT_BLINK_POLL || 10599 led->led_act == BWN_LED_ACT_BLINK) { 10600 led->led_flags |= BWN_LED_F_BLINK; 10601 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10602 led->led_flags |= BWN_LED_F_POLLABLE; 10603 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10604 led->led_flags |= BWN_LED_F_SLOW; 10605 10606 if (sc->sc_blink_led == NULL) { 10607 sc->sc_blink_led = led; 10608 if (led->led_flags & BWN_LED_F_SLOW) 10609 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10610 } 10611 } 10612 10613 DPRINTF(sc, BWN_DEBUG_LED, 10614 "%dth led, act %d, lowact %d\n", i, 10615 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10616 } 10617 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10618} 10619 10620static __inline uint16_t 10621bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10622{ 10623 10624 if (led->led_flags & BWN_LED_F_ACTLOW) 10625 on = !on; 10626 if (on) 10627 val |= led->led_mask; 10628 else 10629 val &= ~led->led_mask; 10630 return val; 10631} 10632 10633static void 10634bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10635{ 10636 struct bwn_softc *sc = mac->mac_sc; 10637 struct ifnet *ifp = sc->sc_ifp; 10638 struct ieee80211com *ic = ifp->if_l2com; 10639 uint16_t val; 10640 int i; 10641 10642 if (nstate == IEEE80211_S_INIT) { 10643 callout_stop(&sc->sc_led_blink_ch); 10644 sc->sc_led_blinking = 0; 10645 } 10646 10647 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10648 return; 10649 10650 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10651 for (i = 0; i < BWN_LED_MAX; ++i) { 10652 struct bwn_led *led = &sc->sc_leds[i]; 10653 int on; 10654 10655 if (led->led_act == BWN_LED_ACT_UNKN || 10656 led->led_act == BWN_LED_ACT_NULL) 10657 continue; 10658 10659 if ((led->led_flags & BWN_LED_F_BLINK) && 10660 nstate != IEEE80211_S_INIT) 10661 continue; 10662 10663 switch (led->led_act) { 10664 case BWN_LED_ACT_ON: /* Always on */ 10665 on = 1; 10666 break; 10667 case BWN_LED_ACT_OFF: /* Always off */ 10668 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10669 on = 0; 10670 break; 10671 default: 10672 on = 1; 10673 switch (nstate) { 10674 case IEEE80211_S_INIT: 10675 on = 0; 10676 break; 10677 case IEEE80211_S_RUN: 10678 if (led->led_act == BWN_LED_ACT_11G && 10679 ic->ic_curmode != IEEE80211_MODE_11G) 10680 on = 0; 10681 break; 10682 default: 10683 if (led->led_act == BWN_LED_ACT_ASSOC) 10684 on = 0; 10685 break; 10686 } 10687 break; 10688 } 10689 10690 val = bwn_led_onoff(led, val, on); 10691 } 10692 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10693} 10694 10695static void 10696bwn_led_event(struct bwn_mac *mac, int event) 10697{ 10698 struct bwn_softc *sc = mac->mac_sc; 10699 struct bwn_led *led = sc->sc_blink_led; 10700 int rate; 10701 10702 if (event == BWN_LED_EVENT_POLL) { 10703 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10704 return; 10705 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10706 return; 10707 } 10708 10709 sc->sc_led_ticks = ticks; 10710 if (sc->sc_led_blinking) 10711 return; 10712 10713 switch (event) { 10714 case BWN_LED_EVENT_RX: 10715 rate = sc->sc_rx_rate; 10716 break; 10717 case BWN_LED_EVENT_TX: 10718 rate = sc->sc_tx_rate; 10719 break; 10720 case BWN_LED_EVENT_POLL: 10721 rate = 0; 10722 break; 10723 default: 10724 panic("unknown LED event %d\n", event); 10725 break; 10726 } 10727 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10728 bwn_led_duration[rate].off_dur); 10729} 10730 10731static void 10732bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10733{ 10734 struct bwn_softc *sc = mac->mac_sc; 10735 struct bwn_led *led = sc->sc_blink_led; 10736 uint16_t val; 10737 10738 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10739 val = bwn_led_onoff(led, val, 1); 10740 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10741 10742 if (led->led_flags & BWN_LED_F_SLOW) { 10743 BWN_LED_SLOWDOWN(on_dur); 10744 BWN_LED_SLOWDOWN(off_dur); 10745 } 10746 10747 sc->sc_led_blinking = 1; 10748 sc->sc_led_blink_offdur = off_dur; 10749 10750 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10751} 10752 10753static void 10754bwn_led_blink_next(void *arg) 10755{ 10756 struct bwn_mac *mac = arg; 10757 struct bwn_softc *sc = mac->mac_sc; 10758 uint16_t val; 10759 10760 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10761 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10762 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10763 10764 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10765 bwn_led_blink_end, mac); 10766} 10767 10768static void 10769bwn_led_blink_end(void *arg) 10770{ 10771 struct bwn_mac *mac = arg; 10772 struct bwn_softc *sc = mac->mac_sc; 10773 10774 sc->sc_led_blinking = 0; 10775} 10776 10777static int 10778bwn_suspend(device_t dev) 10779{ 10780 struct bwn_softc *sc = device_get_softc(dev); 10781 10782 bwn_stop(sc, 1); 10783 return (0); 10784} 10785 10786static int 10787bwn_resume(device_t dev) 10788{ 10789 struct bwn_softc *sc = device_get_softc(dev); 10790 struct ifnet *ifp = sc->sc_ifp; 10791 10792 if (ifp->if_flags & IFF_UP) 10793 bwn_init(sc); 10794 return (0); 10795} 10796 10797static void 10798bwn_rfswitch(void *arg) 10799{ 10800 struct bwn_softc *sc = arg; 10801 struct bwn_mac *mac = sc->sc_curmac; 10802 int cur = 0, prev = 0; 10803 10804 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10805 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10806 10807 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10808 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10809 & BWN_RF_HWENABLED_HI_MASK)) 10810 cur = 1; 10811 } else { 10812 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10813 & BWN_RF_HWENABLED_LO_MASK) 10814 cur = 1; 10815 } 10816 10817 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10818 prev = 1; 10819 10820 if (cur != prev) { 10821 if (cur) 10822 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10823 else 10824 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10825 10826 device_printf(sc->sc_dev, 10827 "status of RF switch is changed to %s\n", 10828 cur ? "ON" : "OFF"); 10829 if (cur != mac->mac_phy.rf_on) { 10830 if (cur) 10831 bwn_rf_turnon(mac); 10832 else 10833 bwn_rf_turnoff(mac); 10834 } 10835 } 10836 10837 callout_schedule(&sc->sc_rfswitch_ch, hz); 10838} 10839 10840static void 10841bwn_phy_lp_init_pre(struct bwn_mac *mac) 10842{ 10843 struct bwn_phy *phy = &mac->mac_phy; 10844 struct bwn_phy_lp *plp = &phy->phy_lp; 10845 10846 plp->plp_antenna = BWN_ANT_DEFAULT; 10847} 10848 10849static int 10850bwn_phy_lp_init(struct bwn_mac *mac) 10851{ 10852 static const struct bwn_stxtable tables[] = { 10853 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10854 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10855 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10856 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10857 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10858 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10859 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10860 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10861 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10862 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10863 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10864 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10865 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10866 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10867 { 2, 11, 0x40, 0, 0x0f } 10868 }; 10869 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10870 struct bwn_softc *sc = mac->mac_sc; 10871 const struct bwn_stxtable *st; 10872 struct ifnet *ifp = sc->sc_ifp; 10873 struct ieee80211com *ic = ifp->if_l2com; 10874 int i, error; 10875 uint16_t tmp; 10876 10877 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10878 bwn_phy_lp_bbinit(mac); 10879 10880 /* initialize RF */ 10881 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10882 DELAY(1); 10883 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10884 DELAY(1); 10885 10886 if (mac->mac_phy.rf_ver == 0x2062) 10887 bwn_phy_lp_b2062_init(mac); 10888 else { 10889 bwn_phy_lp_b2063_init(mac); 10890 10891 /* synchronize stx table. */ 10892 for (i = 0; i < N(tables); i++) { 10893 st = &tables[i]; 10894 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10895 tmp >>= st->st_rfshift; 10896 tmp <<= st->st_physhift; 10897 BWN_PHY_SETMASK(mac, 10898 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10899 ~(st->st_mask << st->st_physhift), tmp); 10900 } 10901 10902 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10903 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10904 } 10905 10906 /* calibrate RC */ 10907 if (mac->mac_phy.rev >= 2) 10908 bwn_phy_lp_rxcal_r2(mac); 10909 else if (!plp->plp_rccap) { 10910 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10911 bwn_phy_lp_rccal_r12(mac); 10912 } else 10913 bwn_phy_lp_set_rccap(mac); 10914 10915 error = bwn_phy_lp_switch_channel(mac, 7); 10916 if (error) 10917 device_printf(sc->sc_dev, 10918 "failed to change channel 7 (%d)\n", error); 10919 bwn_phy_lp_txpctl_init(mac); 10920 bwn_phy_lp_calib(mac); 10921 return (0); 10922} 10923 10924static uint16_t 10925bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10926{ 10927 10928 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10929 return (BWN_READ_2(mac, BWN_PHYDATA)); 10930} 10931 10932static void 10933bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10934{ 10935 10936 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10937 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10938} 10939 10940static void 10941bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10942 uint16_t set) 10943{ 10944 10945 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10946 BWN_WRITE_2(mac, BWN_PHYDATA, 10947 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10948} 10949 10950static uint16_t 10951bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10952{ 10953 10954 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10955 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10956 reg |= 0x100; 10957 if (mac->mac_phy.rev >= 2) 10958 reg |= 0x200; 10959 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10960 return BWN_READ_2(mac, BWN_RFDATALO); 10961} 10962 10963static void 10964bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10965{ 10966 10967 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10968 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10969 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10970} 10971 10972static void 10973bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10974{ 10975 10976 if (on) { 10977 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10978 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10979 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10980 return; 10981 } 10982 10983 if (mac->mac_phy.rev >= 2) { 10984 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10985 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10986 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10987 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10988 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10989 return; 10990 } 10991 10992 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10993 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10994 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10995 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10996} 10997 10998static int 10999bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11000{ 11001 struct bwn_phy *phy = &mac->mac_phy; 11002 struct bwn_phy_lp *plp = &phy->phy_lp; 11003 int error; 11004 11005 if (phy->rf_ver == 0x2063) { 11006 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11007 if (error) 11008 return (error); 11009 } else { 11010 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11011 if (error) 11012 return (error); 11013 bwn_phy_lp_set_anafilter(mac, chan); 11014 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11015 } 11016 11017 plp->plp_chan = chan; 11018 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11019 return (0); 11020} 11021 11022static uint32_t 11023bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11024{ 11025 struct bwn_softc *sc = mac->mac_sc; 11026 struct ifnet *ifp = sc->sc_ifp; 11027 struct ieee80211com *ic = ifp->if_l2com; 11028 11029 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11030} 11031 11032static void 11033bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11034{ 11035 struct bwn_phy *phy = &mac->mac_phy; 11036 struct bwn_phy_lp *plp = &phy->phy_lp; 11037 11038 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11039 return; 11040 11041 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11042 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11043 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11044 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11045 plp->plp_antenna = antenna; 11046} 11047 11048static void 11049bwn_phy_lp_task_60s(struct bwn_mac *mac) 11050{ 11051 11052 bwn_phy_lp_calib(mac); 11053} 11054 11055static void 11056bwn_phy_lp_readsprom(struct bwn_mac *mac) 11057{ 11058 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11059 struct bwn_softc *sc = mac->mac_sc; 11060 struct ifnet *ifp = sc->sc_ifp; 11061 struct ieee80211com *ic = ifp->if_l2com; 11062 11063 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11064 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11065 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11066 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11067 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11068 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11069 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11070 return; 11071 } 11072 11073 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11074 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11075 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11076 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11077 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11078 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11079 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11080 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11081} 11082 11083static void 11084bwn_phy_lp_bbinit(struct bwn_mac *mac) 11085{ 11086 11087 bwn_phy_lp_tblinit(mac); 11088 if (mac->mac_phy.rev >= 2) 11089 bwn_phy_lp_bbinit_r2(mac); 11090 else 11091 bwn_phy_lp_bbinit_r01(mac); 11092} 11093 11094static void 11095bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11096{ 11097 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11098 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11099 struct bwn_softc *sc = mac->mac_sc; 11100 struct ifnet *ifp = sc->sc_ifp; 11101 struct ieee80211com *ic = ifp->if_l2com; 11102 11103 bwn_phy_lp_set_txgain(mac, 11104 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11105 bwn_phy_lp_set_bbmult(mac, 150); 11106} 11107 11108static void 11109bwn_phy_lp_calib(struct bwn_mac *mac) 11110{ 11111 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11112 struct bwn_softc *sc = mac->mac_sc; 11113 struct ifnet *ifp = sc->sc_ifp; 11114 struct ieee80211com *ic = ifp->if_l2com; 11115 const struct bwn_rxcompco *rc = NULL; 11116 struct bwn_txgain ogain; 11117 int i, omode, oafeovr, orf, obbmult; 11118 uint8_t mode, fc = 0; 11119 11120 if (plp->plp_chanfullcal != plp->plp_chan) { 11121 plp->plp_chanfullcal = plp->plp_chan; 11122 fc = 1; 11123 } 11124 11125 bwn_mac_suspend(mac); 11126 11127 /* BlueTooth Coexistance Override */ 11128 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11129 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11130 11131 if (mac->mac_phy.rev >= 2) 11132 bwn_phy_lp_digflt_save(mac); 11133 bwn_phy_lp_get_txpctlmode(mac); 11134 mode = plp->plp_txpctlmode; 11135 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11136 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11137 bwn_phy_lp_bugfix(mac); 11138 if (mac->mac_phy.rev >= 2 && fc == 1) { 11139 bwn_phy_lp_get_txpctlmode(mac); 11140 omode = plp->plp_txpctlmode; 11141 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11142 if (oafeovr) 11143 ogain = bwn_phy_lp_get_txgain(mac); 11144 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11145 obbmult = bwn_phy_lp_get_bbmult(mac); 11146 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11147 if (oafeovr) 11148 bwn_phy_lp_set_txgain(mac, &ogain); 11149 bwn_phy_lp_set_bbmult(mac, obbmult); 11150 bwn_phy_lp_set_txpctlmode(mac, omode); 11151 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11152 } 11153 bwn_phy_lp_set_txpctlmode(mac, mode); 11154 if (mac->mac_phy.rev >= 2) 11155 bwn_phy_lp_digflt_restore(mac); 11156 11157 /* do RX IQ Calculation; assumes that noise is true. */ 11158 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11159 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11160 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11161 rc = &bwn_rxcompco_5354[i]; 11162 } 11163 } else if (mac->mac_phy.rev >= 2) 11164 rc = &bwn_rxcompco_r2; 11165 else { 11166 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11167 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11168 rc = &bwn_rxcompco_r12[i]; 11169 } 11170 } 11171 if (rc == NULL) 11172 goto fail; 11173 11174 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11175 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11176 11177 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11178 11179 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11180 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11181 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11182 } else { 11183 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11184 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11185 } 11186 11187 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11188 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11189 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11190 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11191 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11192 bwn_phy_lp_set_deaf(mac, 0); 11193 /* XXX no checking return value? */ 11194 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11195 bwn_phy_lp_clear_deaf(mac, 0); 11196 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11197 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11199 11200 /* disable RX GAIN override. */ 11201 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11204 if (mac->mac_phy.rev >= 2) { 11205 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11206 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11207 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11208 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11209 } 11210 } else { 11211 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11212 } 11213 11214 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11215 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11216fail: 11217 bwn_mac_enable(mac); 11218} 11219 11220static void 11221bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11222{ 11223 11224 if (on) { 11225 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11226 return; 11227 } 11228 11229 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11230 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11231} 11232 11233static int 11234bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11235{ 11236 static const struct bwn_b206x_chan *bc = NULL; 11237 struct bwn_softc *sc = mac->mac_sc; 11238 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11239 tmp[6]; 11240 uint16_t old, scale, tmp16; 11241 int i, div; 11242 11243 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11244 if (bwn_b2063_chantable[i].bc_chan == chan) { 11245 bc = &bwn_b2063_chantable[i]; 11246 break; 11247 } 11248 } 11249 if (bc == NULL) 11250 return (EINVAL); 11251 11252 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11253 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11256 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11261 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11262 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11263 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11264 11265 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11266 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11267 11268 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11269 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11270 freqref = freqxtal * 3; 11271 div = (freqxtal <= 26000000 ? 1 : 2); 11272 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11273 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11274 999999) / 1000000) + 1; 11275 11276 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11277 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11278 0xfff8, timeout >> 2); 11279 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11280 0xff9f,timeout << 5); 11281 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11282 11283 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11284 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11285 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11286 11287 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11288 (timeoutref + 1)) - 1; 11289 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11290 0xf0, count >> 8); 11291 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11292 11293 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11294 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11295 while (tmp[1] >= freqref) { 11296 tmp[0]++; 11297 tmp[1] -= freqref; 11298 } 11299 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11300 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11302 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11303 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11304 11305 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11306 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11309 11310 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11311 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11312 11313 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11314 scale = 1; 11315 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11316 } else { 11317 scale = 0; 11318 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11319 } 11320 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11321 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11322 11323 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11324 (scale + 1); 11325 if (tmp[5] > 150) 11326 tmp[5] = 0; 11327 11328 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11329 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11330 11331 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11332 if (freqxtal > 26000000) 11333 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11334 else 11335 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11336 11337 if (val[0] == 45) 11338 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11339 else 11340 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11341 11342 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11343 DELAY(1); 11344 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11345 11346 /* VCO Calibration */ 11347 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11348 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11349 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11350 DELAY(1); 11351 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11352 DELAY(1); 11353 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11354 DELAY(1); 11355 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11356 DELAY(300); 11357 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11358 11359 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11360 return (0); 11361} 11362 11363static int 11364bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11365{ 11366 struct bwn_softc *sc = mac->mac_sc; 11367 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11368 const struct bwn_b206x_chan *bc = NULL; 11369 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11370 uint32_t tmp[9]; 11371 int i; 11372 11373 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11374 if (bwn_b2062_chantable[i].bc_chan == chan) { 11375 bc = &bwn_b2062_chantable[i]; 11376 break; 11377 } 11378 } 11379 11380 if (bc == NULL) 11381 return (EINVAL); 11382 11383 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11384 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11385 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11387 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11388 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11389 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11390 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11391 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11392 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11393 11394 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11395 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11396 bwn_phy_lp_b2062_reset_pllbias(mac); 11397 tmp[0] = freqxtal / 1000; 11398 tmp[1] = plp->plp_div * 1000; 11399 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11400 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11401 tmp[2] *= 2; 11402 tmp[3] = 48 * tmp[0]; 11403 tmp[5] = tmp[2] / tmp[3]; 11404 tmp[6] = tmp[2] % tmp[3]; 11405 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11406 tmp[4] = tmp[6] * 0x100; 11407 tmp[5] = tmp[4] / tmp[3]; 11408 tmp[6] = tmp[4] % tmp[3]; 11409 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11410 tmp[4] = tmp[6] * 0x100; 11411 tmp[5] = tmp[4] / tmp[3]; 11412 tmp[6] = tmp[4] % tmp[3]; 11413 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11414 tmp[4] = tmp[6] * 0x100; 11415 tmp[5] = tmp[4] / tmp[3]; 11416 tmp[6] = tmp[4] % tmp[3]; 11417 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11418 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11419 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11420 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11421 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11422 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11423 11424 bwn_phy_lp_b2062_vco_calib(mac); 11425 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11426 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11427 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11428 bwn_phy_lp_b2062_reset_pllbias(mac); 11429 bwn_phy_lp_b2062_vco_calib(mac); 11430 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11431 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11432 return (EIO); 11433 } 11434 } 11435 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11436 return (0); 11437} 11438 11439static void 11440bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11441{ 11442 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11443 uint16_t tmp = (channel == 14); 11444 11445 if (mac->mac_phy.rev < 2) { 11446 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11447 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11448 bwn_phy_lp_set_rccap(mac); 11449 return; 11450 } 11451 11452 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11453} 11454 11455static void 11456bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11457{ 11458 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11459 struct bwn_softc *sc = mac->mac_sc; 11460 struct ifnet *ifp = sc->sc_ifp; 11461 struct ieee80211com *ic = ifp->if_l2com; 11462 uint16_t iso, tmp[3]; 11463 11464 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11465 11466 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11467 iso = plp->plp_txisoband_m; 11468 else if (freq <= 5320) 11469 iso = plp->plp_txisoband_l; 11470 else if (freq <= 5700) 11471 iso = plp->plp_txisoband_m; 11472 else 11473 iso = plp->plp_txisoband_h; 11474 11475 tmp[0] = ((iso - 26) / 12) << 12; 11476 tmp[1] = tmp[0] + 0x1000; 11477 tmp[2] = tmp[0] + 0x2000; 11478 11479 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11480 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11481} 11482 11483static void 11484bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11485{ 11486 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11487 int i; 11488 static const uint16_t addr[] = { 11489 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11490 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11491 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11492 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11493 BWN_PHY_OFDM(0xcf), 11494 }; 11495 static const uint16_t val[] = { 11496 0xde5e, 0xe832, 0xe331, 0x4d26, 11497 0x0026, 0x1420, 0x0020, 0xfe08, 11498 0x0008, 11499 }; 11500 11501 for (i = 0; i < N(addr); i++) { 11502 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11503 BWN_PHY_WRITE(mac, addr[i], val[i]); 11504 } 11505} 11506 11507static void 11508bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11509{ 11510 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11511 struct bwn_softc *sc = mac->mac_sc; 11512 uint16_t ctl; 11513 11514 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11515 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11516 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11517 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11518 break; 11519 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11520 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11521 break; 11522 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11523 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11524 break; 11525 default: 11526 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11527 device_printf(sc->sc_dev, "unknown command mode\n"); 11528 break; 11529 } 11530} 11531 11532static void 11533bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11534{ 11535 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11536 uint16_t ctl; 11537 uint8_t old; 11538 11539 bwn_phy_lp_get_txpctlmode(mac); 11540 old = plp->plp_txpctlmode; 11541 if (old == mode) 11542 return; 11543 plp->plp_txpctlmode = mode; 11544 11545 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11546 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11547 plp->plp_tssiidx); 11548 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11549 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11550 11551 /* disable TX GAIN override */ 11552 if (mac->mac_phy.rev < 2) 11553 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11554 else { 11555 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11556 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11557 } 11558 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11559 11560 plp->plp_txpwridx = -1; 11561 } 11562 if (mac->mac_phy.rev >= 2) { 11563 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11564 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11565 else 11566 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11567 } 11568 11569 /* writes TX Power Control mode */ 11570 switch (plp->plp_txpctlmode) { 11571 case BWN_PHYLP_TXPCTL_OFF: 11572 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11573 break; 11574 case BWN_PHYLP_TXPCTL_ON_HW: 11575 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11576 break; 11577 case BWN_PHYLP_TXPCTL_ON_SW: 11578 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11579 break; 11580 default: 11581 ctl = 0; 11582 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11583 } 11584 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11585 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11586} 11587 11588static void 11589bwn_phy_lp_bugfix(struct bwn_mac *mac) 11590{ 11591 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11592 struct bwn_softc *sc = mac->mac_sc; 11593 const unsigned int size = 256; 11594 struct bwn_txgain tg; 11595 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11596 uint16_t tssinpt, tssiidx, value[2]; 11597 uint8_t mode; 11598 int8_t txpwridx; 11599 11600 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11601 M_NOWAIT | M_ZERO); 11602 if (tabs == NULL) { 11603 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11604 return; 11605 } 11606 11607 bwn_phy_lp_get_txpctlmode(mac); 11608 mode = plp->plp_txpctlmode; 11609 txpwridx = plp->plp_txpwridx; 11610 tssinpt = plp->plp_tssinpt; 11611 tssiidx = plp->plp_tssiidx; 11612 11613 bwn_tab_read_multi(mac, 11614 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11615 BWN_TAB_4(7, 0x140), size, tabs); 11616 11617 bwn_phy_lp_tblinit(mac); 11618 bwn_phy_lp_bbinit(mac); 11619 bwn_phy_lp_txpctl_init(mac); 11620 bwn_phy_lp_rf_onoff(mac, 1); 11621 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11622 11623 bwn_tab_write_multi(mac, 11624 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11625 BWN_TAB_4(7, 0x140), size, tabs); 11626 11627 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11628 plp->plp_tssinpt = tssinpt; 11629 plp->plp_tssiidx = tssiidx; 11630 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11631 if (txpwridx != -1) { 11632 /* set TX power by index */ 11633 plp->plp_txpwridx = txpwridx; 11634 bwn_phy_lp_get_txpctlmode(mac); 11635 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11636 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11637 if (mac->mac_phy.rev >= 2) { 11638 rxcomp = bwn_tab_read(mac, 11639 BWN_TAB_4(7, txpwridx + 320)); 11640 txgain = bwn_tab_read(mac, 11641 BWN_TAB_4(7, txpwridx + 192)); 11642 tg.tg_pad = (txgain >> 16) & 0xff; 11643 tg.tg_gm = txgain & 0xff; 11644 tg.tg_pga = (txgain >> 8) & 0xff; 11645 tg.tg_dac = (rxcomp >> 28) & 0xff; 11646 bwn_phy_lp_set_txgain(mac, &tg); 11647 } else { 11648 rxcomp = bwn_tab_read(mac, 11649 BWN_TAB_4(10, txpwridx + 320)); 11650 txgain = bwn_tab_read(mac, 11651 BWN_TAB_4(10, txpwridx + 192)); 11652 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11653 0xf800, (txgain >> 4) & 0x7fff); 11654 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11655 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11656 } 11657 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11658 11659 /* set TX IQCC */ 11660 value[0] = (rxcomp >> 10) & 0x3ff; 11661 value[1] = rxcomp & 0x3ff; 11662 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11663 11664 coeff = bwn_tab_read(mac, 11665 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11666 BWN_TAB_4(10, txpwridx + 448)); 11667 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11668 if (mac->mac_phy.rev >= 2) { 11669 rfpwr = bwn_tab_read(mac, 11670 BWN_TAB_4(7, txpwridx + 576)); 11671 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11672 rfpwr & 0xffff); 11673 } 11674 bwn_phy_lp_set_txgain_override(mac); 11675 } 11676 if (plp->plp_rccap) 11677 bwn_phy_lp_set_rccap(mac); 11678 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11679 bwn_phy_lp_set_txpctlmode(mac, mode); 11680 free(tabs, M_DEVBUF); 11681} 11682 11683static void 11684bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11685{ 11686 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11687 int i; 11688 static const uint16_t addr[] = { 11689 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11690 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11691 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11692 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11693 BWN_PHY_OFDM(0xcf), 11694 }; 11695 11696 for (i = 0; i < N(addr); i++) 11697 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11698} 11699 11700static void 11701bwn_phy_lp_tblinit(struct bwn_mac *mac) 11702{ 11703 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11704 11705 if (mac->mac_phy.rev < 2) { 11706 bwn_phy_lp_tblinit_r01(mac); 11707 bwn_phy_lp_tblinit_txgain(mac); 11708 bwn_phy_lp_set_gaintbl(mac, freq); 11709 return; 11710 } 11711 11712 bwn_phy_lp_tblinit_r2(mac); 11713 bwn_phy_lp_tblinit_txgain(mac); 11714} 11715 11716struct bwn_wpair { 11717 uint16_t reg; 11718 uint16_t value; 11719}; 11720 11721struct bwn_smpair { 11722 uint16_t offset; 11723 uint16_t mask; 11724 uint16_t set; 11725}; 11726 11727static void 11728bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11729{ 11730 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11731 struct bwn_softc *sc = mac->mac_sc; 11732 struct ifnet *ifp = sc->sc_ifp; 11733 struct ieee80211com *ic = ifp->if_l2com; 11734 static const struct bwn_wpair v1[] = { 11735 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11736 { BWN_PHY_AFE_CTL, 0x8800 }, 11737 { BWN_PHY_AFE_CTL_OVR, 0 }, 11738 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11739 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11740 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11741 { BWN_PHY_OFDM(0xf9), 0 }, 11742 { BWN_PHY_TR_LOOKUP_1, 0 } 11743 }; 11744 static const struct bwn_smpair v2[] = { 11745 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11746 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11747 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11748 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11749 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11750 }; 11751 static const struct bwn_smpair v3[] = { 11752 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11753 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11754 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11755 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11756 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11757 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11758 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11759 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11760 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11761 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11762 11763 }; 11764 int i; 11765 11766 for (i = 0; i < N(v1); i++) 11767 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11768 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11769 for (i = 0; i < N(v2); i++) 11770 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11771 11772 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11773 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11774 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11775 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11776 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11777 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11778 } else { 11779 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11780 } 11781 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11782 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11783 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11784 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11785 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11786 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11787 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11788 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11789 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11790 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11791 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11792 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11793 (siba_get_chiprev(sc->sc_dev) == 0)) { 11794 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11795 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11796 } else { 11797 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11798 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11799 } 11800 for (i = 0; i < N(v3); i++) 11801 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11802 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11803 (siba_get_chiprev(sc->sc_dev) == 0)) { 11804 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11805 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11806 } 11807 11808 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11809 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11810 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11813 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11814 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11815 } else 11816 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11817 11818 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11819 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11820 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11821 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11822 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11823 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11824 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11825 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11826 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11827 11828 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11829 (siba_get_chiprev(sc->sc_dev) == 0)) { 11830 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11831 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11832 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11833 } 11834 11835 bwn_phy_lp_digflt_save(mac); 11836} 11837 11838static void 11839bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11840{ 11841 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11842 struct bwn_softc *sc = mac->mac_sc; 11843 struct ifnet *ifp = sc->sc_ifp; 11844 struct ieee80211com *ic = ifp->if_l2com; 11845 static const struct bwn_smpair v1[] = { 11846 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11847 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11848 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11849 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11850 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11851 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11852 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11853 }; 11854 static const struct bwn_smpair v2[] = { 11855 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11856 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11857 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11858 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11859 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11860 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11861 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11862 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11863 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11864 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11865 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11866 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11867 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11868 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11869 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11870 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11871 }; 11872 static const struct bwn_smpair v3[] = { 11873 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11874 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11875 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11876 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11877 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11878 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11879 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11880 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11881 }; 11882 static const struct bwn_smpair v4[] = { 11883 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11884 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11885 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11886 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11887 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11888 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11889 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11890 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11891 }; 11892 static const struct bwn_smpair v5[] = { 11893 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11894 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11895 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11896 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11897 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11898 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11899 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11900 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11901 }; 11902 int i; 11903 uint16_t tmp, tmp2; 11904 11905 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11906 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11907 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11908 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11909 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11910 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11911 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11912 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11913 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11914 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11915 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11918 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11919 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11920 for (i = 0; i < N(v1); i++) 11921 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11922 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11923 0xff00, plp->plp_rxpwroffset); 11924 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11925 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11926 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11927 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11928 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11929 if (mac->mac_phy.rev == 0) 11930 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11931 0xffcf, 0x0010); 11932 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11933 } else { 11934 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11935 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11936 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11937 } 11938 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11939 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11940 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11941 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11942 else 11943 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11944 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11945 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11946 0xfff9, (plp->plp_bxarch << 1)); 11947 if (mac->mac_phy.rev == 1 && 11948 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11949 for (i = 0; i < N(v2); i++) 11950 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11951 v2[i].set); 11952 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11953 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11954 ((mac->mac_phy.rev == 0) && 11955 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11956 for (i = 0; i < N(v3); i++) 11957 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11958 v3[i].set); 11959 } else if (mac->mac_phy.rev == 1 || 11960 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11961 for (i = 0; i < N(v4); i++) 11962 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11963 v4[i].set); 11964 } else { 11965 for (i = 0; i < N(v5); i++) 11966 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11967 v5[i].set); 11968 } 11969 if (mac->mac_phy.rev == 1 && 11970 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11971 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11972 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11975 } 11976 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11977 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11978 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11979 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11980 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11981 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11982 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11983 } 11984 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11985 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11986 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11987 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11988 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11989 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11990 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11991 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11992 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11993 } else { 11994 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11995 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11996 } 11997 if (mac->mac_phy.rev == 1) { 11998 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11999 tmp2 = (tmp & 0x03e0) >> 5; 12000 tmp2 |= tmp2 << 5; 12001 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12002 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12003 tmp2 = (tmp & 0x1f00) >> 8; 12004 tmp2 |= tmp2 << 5; 12005 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12006 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12007 tmp2 = tmp & 0x00ff; 12008 tmp2 |= tmp << 8; 12009 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12010 } 12011} 12012 12013struct bwn_b2062_freq { 12014 uint16_t freq; 12015 uint8_t value[6]; 12016}; 12017 12018static void 12019bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12020{ 12021#define CALC_CTL7(freq, div) \ 12022 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12023#define CALC_CTL18(freq, div) \ 12024 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12025#define CALC_CTL19(freq, div) \ 12026 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12027 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12028 struct bwn_softc *sc = mac->mac_sc; 12029 struct ifnet *ifp = sc->sc_ifp; 12030 struct ieee80211com *ic = ifp->if_l2com; 12031 static const struct bwn_b2062_freq freqdata_tab[] = { 12032 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12033 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12034 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12035 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12036 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12037 { 19200, { 1, 1, 1, 1, 14, 9 } } 12038 }; 12039 static const struct bwn_wpair v1[] = { 12040 { BWN_B2062_N_TXCTL3, 0 }, 12041 { BWN_B2062_N_TXCTL4, 0 }, 12042 { BWN_B2062_N_TXCTL5, 0 }, 12043 { BWN_B2062_N_TXCTL6, 0 }, 12044 { BWN_B2062_N_PDNCTL0, 0x40 }, 12045 { BWN_B2062_N_PDNCTL0, 0 }, 12046 { BWN_B2062_N_CALIB_TS, 0x10 }, 12047 { BWN_B2062_N_CALIB_TS, 0 } 12048 }; 12049 const struct bwn_b2062_freq *f = NULL; 12050 uint32_t xtalfreq, ref; 12051 unsigned int i; 12052 12053 bwn_phy_lp_b2062_tblinit(mac); 12054 12055 for (i = 0; i < N(v1); i++) 12056 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12057 if (mac->mac_phy.rev > 0) 12058 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12059 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12060 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12061 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12062 else 12063 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12064 12065 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12066 ("%s:%d: fail", __func__, __LINE__)); 12067 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12068 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12069 12070 if (xtalfreq <= 30000000) { 12071 plp->plp_div = 1; 12072 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12073 } else { 12074 plp->plp_div = 2; 12075 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12076 } 12077 12078 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12079 CALC_CTL7(xtalfreq, plp->plp_div)); 12080 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12081 CALC_CTL18(xtalfreq, plp->plp_div)); 12082 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12083 CALC_CTL19(xtalfreq, plp->plp_div)); 12084 12085 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12086 ref &= 0xffff; 12087 for (i = 0; i < N(freqdata_tab); i++) { 12088 if (ref < freqdata_tab[i].freq) { 12089 f = &freqdata_tab[i]; 12090 break; 12091 } 12092 } 12093 if (f == NULL) 12094 f = &freqdata_tab[N(freqdata_tab) - 1]; 12095 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12096 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12097 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12098 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12099 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12100 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12101#undef CALC_CTL7 12102#undef CALC_CTL18 12103#undef CALC_CTL19 12104} 12105 12106static void 12107bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12108{ 12109 12110 bwn_phy_lp_b2063_tblinit(mac); 12111 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12112 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12113 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12114 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12115 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12116 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12118 if (mac->mac_phy.rev == 2) { 12119 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12122 } else { 12123 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12124 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12125 } 12126} 12127 12128static void 12129bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12130{ 12131 struct bwn_softc *sc = mac->mac_sc; 12132 static const struct bwn_wpair v1[] = { 12133 { BWN_B2063_RX_BB_SP8, 0x0 }, 12134 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12135 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12136 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12137 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12138 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12139 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12140 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12141 }; 12142 static const struct bwn_wpair v2[] = { 12143 { BWN_B2063_TX_BB_SP3, 0x0 }, 12144 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12145 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12146 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12147 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12148 }; 12149 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12150 int i; 12151 uint8_t tmp; 12152 12153 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12154 12155 for (i = 0; i < 2; i++) 12156 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12157 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12158 for (i = 2; i < N(v1); i++) 12159 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12160 for (i = 0; i < 10000; i++) { 12161 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12162 break; 12163 DELAY(1000); 12164 } 12165 12166 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12167 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12168 12169 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12170 12171 for (i = 0; i < N(v2); i++) 12172 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12173 if (freqxtal == 24000000) { 12174 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12175 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12176 } else { 12177 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12178 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12179 } 12180 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12181 for (i = 0; i < 10000; i++) { 12182 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12183 break; 12184 DELAY(1000); 12185 } 12186 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12187 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12188 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12189} 12190 12191static void 12192bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12193{ 12194 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12195 struct bwn_softc *sc = mac->mac_sc; 12196 struct bwn_phy_lp_iq_est ie; 12197 struct bwn_txgain tx_gains; 12198 static const uint32_t pwrtbl[21] = { 12199 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12200 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12201 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12202 0x0004c, 0x0002c, 0x0001a, 12203 }; 12204 uint32_t npwr, ipwr, sqpwr, tmp; 12205 int loopback, i, j, sum, error; 12206 uint16_t save[7]; 12207 uint8_t txo, bbmult, txpctlmode; 12208 12209 error = bwn_phy_lp_switch_channel(mac, 7); 12210 if (error) 12211 device_printf(sc->sc_dev, 12212 "failed to change channel to 7 (%d)\n", error); 12213 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12214 bbmult = bwn_phy_lp_get_bbmult(mac); 12215 if (txo) 12216 tx_gains = bwn_phy_lp_get_txgain(mac); 12217 12218 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12219 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12220 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12221 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12222 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12223 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12224 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12225 12226 bwn_phy_lp_get_txpctlmode(mac); 12227 txpctlmode = plp->plp_txpctlmode; 12228 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12229 12230 /* disable CRS */ 12231 bwn_phy_lp_set_deaf(mac, 1); 12232 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12233 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12234 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12235 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12236 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12239 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12240 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12241 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12242 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12245 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12246 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12247 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12248 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12249 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12251 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12252 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12253 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12254 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12255 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12256 12257 loopback = bwn_phy_lp_loopback(mac); 12258 if (loopback == -1) 12259 goto done; 12260 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12261 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12262 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12263 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12265 12266 tmp = 0; 12267 memset(&ie, 0, sizeof(ie)); 12268 for (i = 128; i <= 159; i++) { 12269 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12270 sum = 0; 12271 for (j = 5; j <= 25; j++) { 12272 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12273 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12274 goto done; 12275 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12276 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12277 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12278 12); 12279 sum += ((ipwr - npwr) * (ipwr - npwr)); 12280 if ((i == 128) || (sum < tmp)) { 12281 plp->plp_rccap = i; 12282 tmp = sum; 12283 } 12284 } 12285 } 12286 bwn_phy_lp_ddfs_turnoff(mac); 12287done: 12288 /* restore CRS */ 12289 bwn_phy_lp_clear_deaf(mac, 1); 12290 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12292 12293 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12294 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12295 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12297 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12298 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12299 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12300 12301 bwn_phy_lp_set_bbmult(mac, bbmult); 12302 if (txo) 12303 bwn_phy_lp_set_txgain(mac, &tx_gains); 12304 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12305 if (plp->plp_rccap) 12306 bwn_phy_lp_set_rccap(mac); 12307} 12308 12309static void 12310bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12311{ 12312 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12313 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12314 12315 if (mac->mac_phy.rev == 1) 12316 rc_cap = MIN(rc_cap + 5, 15); 12317 12318 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12319 MAX(plp->plp_rccap - 4, 0x80)); 12320 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12321 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12322 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12323} 12324 12325static uint32_t 12326bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12327{ 12328 uint32_t i, q, r; 12329 12330 if (div == 0) 12331 return (0); 12332 12333 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12334 q <<= 1; 12335 if (r << 1 >= div) { 12336 q++; 12337 r = (r << 1) - div; 12338 } 12339 } 12340 if (r << 1 >= div) 12341 q++; 12342 return (q); 12343} 12344 12345static void 12346bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12347{ 12348 struct bwn_softc *sc = mac->mac_sc; 12349 12350 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12351 DELAY(20); 12352 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12353 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12354 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12355 } else { 12356 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12357 } 12358 DELAY(5); 12359} 12360 12361static void 12362bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12363{ 12364 12365 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12366 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12367 DELAY(200); 12368} 12369 12370static void 12371bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12372{ 12373#define FLAG_A 0x01 12374#define FLAG_G 0x02 12375 struct bwn_softc *sc = mac->mac_sc; 12376 struct ifnet *ifp = sc->sc_ifp; 12377 struct ieee80211com *ic = ifp->if_l2com; 12378 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12379 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12380 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12381 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12382 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12383 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12384 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12385 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12386 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12387 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12389 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12390 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12391 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12425 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12426 }; 12427 const struct bwn_b206x_rfinit_entry *br; 12428 unsigned int i; 12429 12430 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12431 br = &bwn_b2062_init_tab[i]; 12432 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12433 if (br->br_flags & FLAG_G) 12434 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12435 } else { 12436 if (br->br_flags & FLAG_A) 12437 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12438 } 12439 } 12440#undef FLAG_A 12441#undef FLAG_B 12442} 12443 12444static void 12445bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12446{ 12447#define FLAG_A 0x01 12448#define FLAG_G 0x02 12449 struct bwn_softc *sc = mac->mac_sc; 12450 struct ifnet *ifp = sc->sc_ifp; 12451 struct ieee80211com *ic = ifp->if_l2com; 12452 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12453 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12454 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12455 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12456 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12457 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12462 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12463 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12464 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12465 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12466 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12467 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12468 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12469 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12470 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12471 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12472 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12473 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12474 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12475 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12483 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12486 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12487 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12493 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12494 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12495 }; 12496 const struct bwn_b206x_rfinit_entry *br; 12497 unsigned int i; 12498 12499 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12500 br = &bwn_b2063_init_tab[i]; 12501 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12502 if (br->br_flags & FLAG_G) 12503 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12504 } else { 12505 if (br->br_flags & FLAG_A) 12506 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12507 } 12508 } 12509#undef FLAG_A 12510#undef FLAG_B 12511} 12512 12513static void 12514bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12515 int count, void *_data) 12516{ 12517 unsigned int i; 12518 uint32_t offset, type; 12519 uint8_t *data = _data; 12520 12521 type = BWN_TAB_GETTYPE(typenoffset); 12522 offset = BWN_TAB_GETOFFSET(typenoffset); 12523 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12524 12525 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12526 12527 for (i = 0; i < count; i++) { 12528 switch (type) { 12529 case BWN_TAB_8BIT: 12530 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12531 data++; 12532 break; 12533 case BWN_TAB_16BIT: 12534 *((uint16_t *)data) = BWN_PHY_READ(mac, 12535 BWN_PHY_TABLEDATALO); 12536 data += 2; 12537 break; 12538 case BWN_TAB_32BIT: 12539 *((uint32_t *)data) = BWN_PHY_READ(mac, 12540 BWN_PHY_TABLEDATAHI); 12541 *((uint32_t *)data) <<= 16; 12542 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12543 BWN_PHY_TABLEDATALO); 12544 data += 4; 12545 break; 12546 default: 12547 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12548 } 12549 } 12550} 12551 12552static void 12553bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12554 int count, const void *_data) 12555{ 12556 uint32_t offset, type, value; 12557 const uint8_t *data = _data; 12558 unsigned int i; 12559 12560 type = BWN_TAB_GETTYPE(typenoffset); 12561 offset = BWN_TAB_GETOFFSET(typenoffset); 12562 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12563 12564 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12565 12566 for (i = 0; i < count; i++) { 12567 switch (type) { 12568 case BWN_TAB_8BIT: 12569 value = *data; 12570 data++; 12571 KASSERT(!(value & ~0xff), 12572 ("%s:%d: fail", __func__, __LINE__)); 12573 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12574 break; 12575 case BWN_TAB_16BIT: 12576 value = *((const uint16_t *)data); 12577 data += 2; 12578 KASSERT(!(value & ~0xffff), 12579 ("%s:%d: fail", __func__, __LINE__)); 12580 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12581 break; 12582 case BWN_TAB_32BIT: 12583 value = *((const uint32_t *)data); 12584 data += 4; 12585 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12586 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12587 break; 12588 default: 12589 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12590 } 12591 } 12592} 12593 12594static struct bwn_txgain 12595bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12596{ 12597 struct bwn_txgain tg; 12598 uint16_t tmp; 12599 12600 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12601 if (mac->mac_phy.rev < 2) { 12602 tmp = BWN_PHY_READ(mac, 12603 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12604 tg.tg_gm = tmp & 0x0007; 12605 tg.tg_pga = (tmp & 0x0078) >> 3; 12606 tg.tg_pad = (tmp & 0x780) >> 7; 12607 return (tg); 12608 } 12609 12610 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12611 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12612 tg.tg_gm = tmp & 0xff; 12613 tg.tg_pga = (tmp >> 8) & 0xff; 12614 return (tg); 12615} 12616 12617static uint8_t 12618bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12619{ 12620 12621 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12622} 12623 12624static void 12625bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12626{ 12627 uint16_t pa; 12628 12629 if (mac->mac_phy.rev < 2) { 12630 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12631 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12632 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12633 bwn_phy_lp_set_txgain_override(mac); 12634 return; 12635 } 12636 12637 pa = bwn_phy_lp_get_pa_gain(mac); 12638 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12639 (tg->tg_pga << 8) | tg->tg_gm); 12640 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12641 tg->tg_pad | (pa << 6)); 12642 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12643 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12644 tg->tg_pad | (pa << 8)); 12645 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12646 bwn_phy_lp_set_txgain_override(mac); 12647} 12648 12649static void 12650bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12651{ 12652 12653 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12654} 12655 12656static void 12657bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12658{ 12659 uint16_t trsw = (tx << 1) | rx; 12660 12661 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12662 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12663} 12664 12665static void 12666bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12667{ 12668 struct bwn_softc *sc = mac->mac_sc; 12669 struct ifnet *ifp = sc->sc_ifp; 12670 struct ieee80211com *ic = ifp->if_l2com; 12671 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12672 12673 if (mac->mac_phy.rev < 2) { 12674 trsw = gain & 0x1; 12675 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12676 ext_lna = (gain & 2) >> 1; 12677 12678 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12679 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12680 0xfbff, ext_lna << 10); 12681 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12682 0xf7ff, ext_lna << 11); 12683 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12684 } else { 12685 low_gain = gain & 0xffff; 12686 high_gain = (gain >> 16) & 0xf; 12687 ext_lna = (gain >> 21) & 0x1; 12688 trsw = ~(gain >> 20) & 0x1; 12689 12690 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12691 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12692 0xfdff, ext_lna << 9); 12693 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12694 0xfbff, ext_lna << 10); 12695 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12696 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12697 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12698 tmp = (gain >> 2) & 0x3; 12699 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12700 0xe7ff, tmp<<11); 12701 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12702 tmp << 3); 12703 } 12704 } 12705 12706 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12709 if (mac->mac_phy.rev >= 2) { 12710 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12711 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12712 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12713 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12714 } 12715 return; 12716 } 12717 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12718} 12719 12720static void 12721bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12722{ 12723 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12724 12725 if (user) 12726 plp->plp_crsusr_off = 1; 12727 else 12728 plp->plp_crssys_off = 1; 12729 12730 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12731} 12732 12733static void 12734bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12735{ 12736 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12737 struct bwn_softc *sc = mac->mac_sc; 12738 struct ifnet *ifp = sc->sc_ifp; 12739 struct ieee80211com *ic = ifp->if_l2com; 12740 12741 if (user) 12742 plp->plp_crsusr_off = 0; 12743 else 12744 plp->plp_crssys_off = 0; 12745 12746 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12747 return; 12748 12749 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12750 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12751 else 12752 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12753} 12754 12755static unsigned int 12756bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12757{ 12758 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12759 static uint8_t sqrt_table[256] = { 12760 10, 14, 17, 20, 22, 24, 26, 28, 12761 30, 31, 33, 34, 36, 37, 38, 40, 12762 41, 42, 43, 44, 45, 46, 47, 48, 12763 50, 50, 51, 52, 53, 54, 55, 56, 12764 57, 58, 59, 60, 60, 61, 62, 63, 12765 64, 64, 65, 66, 67, 67, 68, 69, 12766 70, 70, 71, 72, 72, 73, 74, 74, 12767 75, 76, 76, 77, 78, 78, 79, 80, 12768 80, 81, 81, 82, 83, 83, 84, 84, 12769 85, 86, 86, 87, 87, 88, 88, 89, 12770 90, 90, 91, 91, 92, 92, 93, 93, 12771 94, 94, 95, 95, 96, 96, 97, 97, 12772 98, 98, 99, 100, 100, 100, 101, 101, 12773 102, 102, 103, 103, 104, 104, 105, 105, 12774 106, 106, 107, 107, 108, 108, 109, 109, 12775 110, 110, 110, 111, 111, 112, 112, 113, 12776 113, 114, 114, 114, 115, 115, 116, 116, 12777 117, 117, 117, 118, 118, 119, 119, 120, 12778 120, 120, 121, 121, 122, 122, 122, 123, 12779 123, 124, 124, 124, 125, 125, 126, 126, 12780 126, 127, 127, 128, 128, 128, 129, 129, 12781 130, 130, 130, 131, 131, 131, 132, 132, 12782 133, 133, 133, 134, 134, 134, 135, 135, 12783 136, 136, 136, 137, 137, 137, 138, 138, 12784 138, 139, 139, 140, 140, 140, 141, 141, 12785 141, 142, 142, 142, 143, 143, 143, 144, 12786 144, 144, 145, 145, 145, 146, 146, 146, 12787 147, 147, 147, 148, 148, 148, 149, 149, 12788 150, 150, 150, 150, 151, 151, 151, 152, 12789 152, 152, 153, 153, 153, 154, 154, 154, 12790 155, 155, 155, 156, 156, 156, 157, 157, 12791 157, 158, 158, 158, 159, 159, 159, 160 12792 }; 12793 12794 if (x == 0) 12795 return (0); 12796 if (x >= 256) { 12797 unsigned int tmp; 12798 12799 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12800 /* do nothing */ ; 12801 return (tmp); 12802 } 12803 return (sqrt_table[x - 1] / 10); 12804} 12805 12806static int 12807bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12808{ 12809#define CALC_COEFF(_v, _x, _y, _z) do { \ 12810 int _t; \ 12811 _t = _x - 20; \ 12812 if (_t >= 0) { \ 12813 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12814 } else { \ 12815 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12816 } \ 12817} while (0) 12818#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12819 int _t; \ 12820 _t = _x - 11; \ 12821 if (_t >= 0) \ 12822 tmp[3] = (_y << (31 - _x)) / (_z >> _t); \ 12823 else \ 12824 tmp[3] = (_y << (31 - _x)) / (_z << -_t); \ 12825} while (0) 12826 struct bwn_phy_lp_iq_est ie; 12827 uint16_t v0, v1; 12828 int tmp[2], ret; 12829 12830 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12831 v0 = v1 >> 8; 12832 v1 |= 0xff; 12833 12834 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12835 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12836 12837 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12838 if (ret == 0) 12839 goto done; 12840 12841 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12842 ret = 0; 12843 goto done; 12844 } 12845 12846 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12847 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12848 12849 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12850 v0 = tmp[0] >> 3; 12851 v1 = tmp[1] >> 4; 12852done: 12853 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12854 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12855 return ret; 12856#undef CALC_COEFF 12857#undef CALC_COEFF2 12858} 12859 12860static void 12861bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12862{ 12863 static const uint16_t noisescale[] = { 12864 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12865 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12867 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12868 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12869 }; 12870 static const uint16_t crsgainnft[] = { 12871 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12872 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12873 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12874 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12875 0x013d, 12876 }; 12877 static const uint16_t filterctl[] = { 12878 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12879 0xff53, 0x0127, 12880 }; 12881 static const uint32_t psctl[] = { 12882 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12883 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12884 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12885 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12886 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12887 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12888 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12889 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12890 }; 12891 static const uint16_t ofdmcckgain_r0[] = { 12892 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12893 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12894 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12895 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12896 0x755d, 12897 }; 12898 static const uint16_t ofdmcckgain_r1[] = { 12899 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12900 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12901 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12902 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12903 0x755d, 12904 }; 12905 static const uint16_t gaindelta[] = { 12906 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12907 0x0000, 12908 }; 12909 static const uint32_t txpwrctl[] = { 12910 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12911 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12912 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12913 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12914 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12915 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12916 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12917 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12918 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12919 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12920 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12921 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12922 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12923 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12948 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12949 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12950 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12951 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12952 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12953 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12954 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12955 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12956 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12957 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12958 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12959 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12960 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12961 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12962 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12963 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12964 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12965 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12966 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12967 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12968 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12969 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12970 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12971 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12972 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12973 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12974 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12975 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12976 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12977 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12978 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12979 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12980 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12981 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12982 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12983 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12984 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12985 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12986 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12987 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12988 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12989 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12990 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12991 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12992 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12993 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12994 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12995 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12996 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12997 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12998 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12999 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13000 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13001 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13002 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13003 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13004 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13005 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13006 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13007 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13008 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13009 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13010 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13011 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13012 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13013 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13014 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13015 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13016 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13017 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13018 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13019 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13020 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13021 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13022 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13023 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13024 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13025 0x00000702, 13026 }; 13027 13028 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13029 13030 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13031 bwn_tab_sigsq_tbl); 13032 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13033 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13034 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13035 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13036 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13037 bwn_tab_pllfrac_tbl); 13038 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13039 bwn_tabl_iqlocal_tbl); 13040 if (mac->mac_phy.rev == 0) { 13041 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13042 ofdmcckgain_r0); 13043 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13044 ofdmcckgain_r0); 13045 } else { 13046 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13047 ofdmcckgain_r1); 13048 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13049 ofdmcckgain_r1); 13050 } 13051 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13052 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13053} 13054 13055static void 13056bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13057{ 13058 struct bwn_softc *sc = mac->mac_sc; 13059 int i; 13060 static const uint16_t noisescale[] = { 13061 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13065 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13066 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13068 }; 13069 static const uint32_t filterctl[] = { 13070 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13071 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13072 }; 13073 static const uint32_t psctl[] = { 13074 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13075 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13076 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13077 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13078 }; 13079 static const uint32_t gainidx[] = { 13080 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13083 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13084 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13085 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13086 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13087 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13088 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13089 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13090 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13091 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13092 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13093 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13094 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13095 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13098 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13099 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13100 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13101 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13102 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13103 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13104 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13105 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13106 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13107 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13108 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13109 0x0000001a, 0x64ca55ad, 0x0000001a 13110 }; 13111 static const uint16_t auxgainidx[] = { 13112 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13113 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13114 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13115 0x0004, 0x0016 13116 }; 13117 static const uint16_t swctl[] = { 13118 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13119 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13120 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13121 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13122 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13123 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13124 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13125 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13126 }; 13127 static const uint8_t hf[] = { 13128 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13129 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13130 }; 13131 static const uint32_t gainval[] = { 13132 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13133 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13134 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13135 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13136 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13137 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13138 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13140 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13142 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13143 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13144 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13145 0x000000f1, 0x00000000, 0x00000000 13146 }; 13147 static const uint16_t gain[] = { 13148 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13149 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13150 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13151 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13152 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13153 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13154 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13159 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13160 }; 13161 static const uint32_t papdeps[] = { 13162 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13163 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13164 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13165 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13166 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13167 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13168 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13169 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13170 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13171 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13172 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13173 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13174 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13175 }; 13176 static const uint32_t papdmult[] = { 13177 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13178 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13179 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13180 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13181 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13182 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13183 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13184 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13185 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13186 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13187 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13188 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13189 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13190 }; 13191 static const uint32_t gainidx_a0[] = { 13192 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13193 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13194 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13195 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13196 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13197 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13198 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13199 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13200 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13201 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13202 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13203 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13204 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13205 }; 13206 static const uint16_t auxgainidx_a0[] = { 13207 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13208 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13209 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13210 0x0002, 0x0014 13211 }; 13212 static const uint32_t gainval_a0[] = { 13213 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13214 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13215 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13216 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13217 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13218 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13219 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13221 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13223 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13224 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13225 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13226 0x000000f7, 0x00000000, 0x00000000 13227 }; 13228 static const uint16_t gain_a0[] = { 13229 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13230 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13231 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13232 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13233 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13234 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13235 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13240 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13241 }; 13242 13243 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13244 13245 for (i = 0; i < 704; i++) 13246 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13247 13248 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13249 bwn_tab_sigsq_tbl); 13250 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13251 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13252 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13253 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13254 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13255 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13256 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13257 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13258 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13259 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13260 bwn_tab_pllfrac_tbl); 13261 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13262 bwn_tabl_iqlocal_tbl); 13263 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13264 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13265 13266 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13267 (siba_get_chiprev(sc->sc_dev) == 0)) { 13268 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13269 gainidx_a0); 13270 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13271 auxgainidx_a0); 13272 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13273 gainval_a0); 13274 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13275 } 13276} 13277 13278static void 13279bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13280{ 13281 struct bwn_softc *sc = mac->mac_sc; 13282 struct ifnet *ifp = sc->sc_ifp; 13283 struct ieee80211com *ic = ifp->if_l2com; 13284 static struct bwn_txgain_entry txgain_r2[] = { 13285 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13286 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13287 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13288 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13289 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13290 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13291 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13292 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13293 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13294 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13295 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13296 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13297 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13298 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13299 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13300 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13301 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13302 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13303 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13304 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13305 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13306 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13307 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13308 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13309 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13310 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13311 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13312 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13313 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13314 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13315 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13316 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13317 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13318 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13319 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13320 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13321 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13322 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13323 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13324 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13325 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13326 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13327 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13328 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13329 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13330 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13331 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13332 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13333 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13334 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13335 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13336 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13337 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13338 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13339 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13340 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13341 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13342 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13343 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13344 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13345 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13346 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13347 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13348 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13349 }; 13350 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13351 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13352 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13353 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13354 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13355 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13356 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13357 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13358 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13359 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13360 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13361 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13362 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13363 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13364 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13365 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13366 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13367 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13368 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13369 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13370 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13371 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13372 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13373 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13374 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13375 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13376 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13377 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13378 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13379 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13380 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13381 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13382 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13383 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13384 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13385 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13386 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13387 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13388 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13389 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13390 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13391 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13392 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13393 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13394 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13395 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13396 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13397 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13398 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13399 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13400 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13401 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13402 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13403 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13404 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13405 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13406 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13407 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13408 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13409 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13410 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13411 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13412 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13413 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13414 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13415 }; 13416 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13417 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13418 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13419 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13420 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13421 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13422 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13423 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13424 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13425 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13426 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13427 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13428 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13429 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13430 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13431 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13432 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13433 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13434 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13435 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13436 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13437 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13438 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13439 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13440 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13441 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13442 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13443 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13444 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13445 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13446 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13447 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13448 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13449 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13450 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13451 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13452 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13453 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13454 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13455 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13456 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13457 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13458 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13459 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13460 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13461 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13462 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13463 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13464 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13465 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13466 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13467 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13468 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13469 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13470 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13471 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13472 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13473 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13474 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13475 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13476 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13477 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13478 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13479 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13480 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13481 }; 13482 static struct bwn_txgain_entry txgain_r0[] = { 13483 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13484 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13485 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13486 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13487 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13488 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13489 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13490 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13491 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13492 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13493 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13494 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13495 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13496 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13497 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13498 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13499 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13500 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13501 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13502 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13503 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13504 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13505 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13506 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13507 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13508 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13509 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13510 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13511 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13512 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13513 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13514 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13515 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13516 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13517 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13518 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13519 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13520 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13521 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13522 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13523 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13524 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13525 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13526 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13527 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13528 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13529 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13530 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13531 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13532 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13533 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13534 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13535 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13536 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13537 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13538 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13539 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13540 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13541 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13542 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13543 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13544 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13545 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13546 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13547 }; 13548 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13549 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13550 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13551 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13552 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13553 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13554 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13555 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13556 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13557 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13558 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13559 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13560 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13561 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13562 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13563 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13564 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13565 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13566 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13567 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13568 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13569 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13570 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13571 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13572 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13573 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13574 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13575 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13576 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13577 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13578 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13579 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13580 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13581 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13582 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13583 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13584 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13585 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13586 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13587 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13588 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13589 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13590 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13591 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13592 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13593 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13594 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13595 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13596 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13597 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13598 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13599 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13600 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13601 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13602 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13603 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13604 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13605 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13606 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13607 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13608 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13609 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13610 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13611 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13612 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13613 }; 13614 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13615 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13616 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13617 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13618 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13619 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13620 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13621 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13622 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13623 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13624 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13625 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13626 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13627 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13628 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13629 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13630 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13631 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13632 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13633 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13634 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13635 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13636 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13637 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13638 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13639 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13640 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13641 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13642 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13643 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13644 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13645 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13646 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13647 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13648 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13649 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13650 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13651 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13652 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13653 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13654 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13655 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13656 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13657 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13658 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13659 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13660 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13661 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13662 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13663 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13664 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13665 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13666 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13667 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13668 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13669 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13670 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13671 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13672 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13673 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13674 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13675 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13676 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13677 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13678 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13679 }; 13680 static struct bwn_txgain_entry txgain_r1[] = { 13681 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13682 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13683 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13684 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13685 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13686 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13687 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13688 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13689 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13690 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13691 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13692 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13693 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13694 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13695 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13696 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13697 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13698 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13699 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13700 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13701 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13702 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13703 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13704 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13705 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13706 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13707 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13708 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13709 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13710 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13711 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13712 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13713 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13714 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13715 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13716 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13717 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13718 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13719 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13720 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13721 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13722 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13723 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13724 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13725 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13726 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13727 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13728 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13729 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13730 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13731 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13732 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13733 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13734 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13735 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13736 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13737 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13738 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13739 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13740 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13741 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13742 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13743 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13744 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13745 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13746 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13747 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13748 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13749 { 7, 11, 6, 0, 71 } 13750 }; 13751 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13752 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13753 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13754 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13755 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13756 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13757 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13758 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13759 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13760 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13761 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13762 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13763 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13764 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13765 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13766 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13767 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13768 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13769 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13770 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13771 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13772 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13773 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13774 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13775 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13776 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13777 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13778 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13779 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13780 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13781 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13782 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13783 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13784 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13785 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13786 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13787 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13788 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13789 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13790 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13791 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13792 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13793 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13794 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13795 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13796 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13797 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13798 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13799 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13800 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13801 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13802 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13803 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13804 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13805 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13806 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13807 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13808 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13809 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13810 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13811 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13812 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13813 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13814 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13815 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13816 }; 13817 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13818 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13819 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13820 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13821 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13822 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13823 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13824 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13825 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13826 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13827 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13828 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13829 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13830 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13831 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13832 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13833 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13834 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13835 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13836 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13837 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13838 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13839 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13840 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13841 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13842 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13843 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13844 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13845 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13846 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13847 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13848 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13849 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13850 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13851 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13852 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13853 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13854 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13855 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13856 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13857 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13858 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13859 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13860 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13861 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13862 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13863 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13864 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13865 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13866 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13867 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13868 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13869 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13870 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13871 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13872 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13873 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13874 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13875 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13876 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13877 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13878 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13879 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13880 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13881 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13882 }; 13883 13884 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13885 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13886 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13887 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13888 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13889 txgain_2ghz_r2); 13890 else 13891 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13892 txgain_5ghz_r2); 13893 return; 13894 } 13895 13896 if (mac->mac_phy.rev == 0) { 13897 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13898 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13899 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13900 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13901 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13902 txgain_2ghz_r0); 13903 else 13904 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13905 txgain_5ghz_r0); 13906 return; 13907 } 13908 13909 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13910 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13911 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13912 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13913 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13914 else 13915 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13916} 13917 13918static void 13919bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13920{ 13921 uint32_t offset, type; 13922 13923 type = BWN_TAB_GETTYPE(typeoffset); 13924 offset = BWN_TAB_GETOFFSET(typeoffset); 13925 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13926 13927 switch (type) { 13928 case BWN_TAB_8BIT: 13929 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13930 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13931 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13932 break; 13933 case BWN_TAB_16BIT: 13934 KASSERT(!(value & ~0xffff), 13935 ("%s:%d: fail", __func__, __LINE__)); 13936 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13937 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13938 break; 13939 case BWN_TAB_32BIT: 13940 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13943 break; 13944 default: 13945 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13946 } 13947} 13948 13949static int 13950bwn_phy_lp_loopback(struct bwn_mac *mac) 13951{ 13952 struct bwn_phy_lp_iq_est ie; 13953 int i, index = -1; 13954 uint32_t tmp; 13955 13956 memset(&ie, 0, sizeof(ie)); 13957 13958 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13959 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13960 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13961 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13962 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13965 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13966 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13967 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13968 for (i = 0; i < 32; i++) { 13969 bwn_phy_lp_set_rxgain_idx(mac, i); 13970 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13971 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13972 continue; 13973 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13974 if ((tmp > 4000) && (tmp < 10000)) { 13975 index = i; 13976 break; 13977 } 13978 } 13979 bwn_phy_lp_ddfs_turnoff(mac); 13980 return (index); 13981} 13982 13983static void 13984bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13985{ 13986 13987 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13988} 13989 13990static void 13991bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13992 int incr1, int incr2, int scale_idx) 13993{ 13994 13995 bwn_phy_lp_ddfs_turnoff(mac); 13996 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13997 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13998 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14003 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14004 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14005 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14006} 14007 14008static uint8_t 14009bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14010 struct bwn_phy_lp_iq_est *ie) 14011{ 14012 int i; 14013 14014 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14015 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14016 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14017 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14018 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14019 14020 for (i = 0; i < 500; i++) { 14021 if (!(BWN_PHY_READ(mac, 14022 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14023 break; 14024 DELAY(1000); 14025 } 14026 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14027 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14028 return 0; 14029 } 14030 14031 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14032 ie->ie_iqprod <<= 16; 14033 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14034 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14035 ie->ie_ipwr <<= 16; 14036 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14037 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14038 ie->ie_qpwr <<= 16; 14039 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14040 14041 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14042 return 1; 14043} 14044 14045static uint32_t 14046bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14047{ 14048 uint32_t offset, type, value; 14049 14050 type = BWN_TAB_GETTYPE(typeoffset); 14051 offset = BWN_TAB_GETOFFSET(typeoffset); 14052 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14053 14054 switch (type) { 14055 case BWN_TAB_8BIT: 14056 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14057 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14058 break; 14059 case BWN_TAB_16BIT: 14060 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14061 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14062 break; 14063 case BWN_TAB_32BIT: 14064 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14065 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14066 value <<= 16; 14067 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14068 break; 14069 default: 14070 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14071 value = 0; 14072 } 14073 14074 return (value); 14075} 14076 14077static void 14078bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14079{ 14080 14081 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14082 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14083} 14084 14085static void 14086bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14087{ 14088 uint16_t ctl; 14089 14090 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14091 ctl |= dac << 7; 14092 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14093} 14094 14095static void 14096bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14097{ 14098 14099 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14100 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14101} 14102 14103static void 14104bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14105{ 14106 14107 if (mac->mac_phy.rev < 2) 14108 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14109 else { 14110 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14111 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14112 } 14113 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14114} 14115 14116static uint16_t 14117bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14118{ 14119 14120 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14121} 14122 14123static uint8_t 14124bwn_nbits(int32_t val) 14125{ 14126 uint32_t tmp; 14127 uint8_t nbits = 0; 14128 14129 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14130 nbits++; 14131 return (nbits); 14132} 14133 14134static void 14135bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14136 struct bwn_txgain_entry *table) 14137{ 14138 int i; 14139 14140 for (i = offset; i < count; i++) 14141 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14142} 14143 14144static void 14145bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14146 struct bwn_txgain_entry data) 14147{ 14148 14149 if (mac->mac_phy.rev >= 2) 14150 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14151 else 14152 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14153} 14154 14155static void 14156bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14157 struct bwn_txgain_entry te) 14158{ 14159 struct bwn_softc *sc = mac->mac_sc; 14160 struct ifnet *ifp = sc->sc_ifp; 14161 struct ieee80211com *ic = ifp->if_l2com; 14162 uint32_t tmp; 14163 14164 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14165 14166 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14167 if (mac->mac_phy.rev >= 3) { 14168 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14169 (0x10 << 24) : (0x70 << 24)); 14170 } else { 14171 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14172 (0x14 << 24) : (0x7f << 24)); 14173 } 14174 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14175 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14176 te.te_bbmult << 20 | te.te_dac << 28); 14177} 14178 14179static void 14180bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14181 struct bwn_txgain_entry te) 14182{ 14183 14184 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14185 14186 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14187 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14188 te.te_dac); 14189 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14190} 14191 14192static void 14193bwn_sysctl_node(struct bwn_softc *sc) 14194{ 14195 device_t dev = sc->sc_dev; 14196 struct bwn_mac *mac; 14197 struct bwn_stats *stats; 14198 14199 /* XXX assume that count of MAC is only 1. */ 14200 14201 if ((mac = sc->sc_curmac) == NULL) 14202 return; 14203 stats = &mac->mac_stats; 14204 14205 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14206 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14207 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14208 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14209 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14210 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14211 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14212 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14213 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14214 14215#ifdef BWN_DEBUG 14216 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14217 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14218 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14219#endif 14220} 14221 14222static device_method_t bwn_methods[] = { 14223 /* Device interface */ 14224 DEVMETHOD(device_probe, bwn_probe), 14225 DEVMETHOD(device_attach, bwn_attach), 14226 DEVMETHOD(device_detach, bwn_detach), 14227 DEVMETHOD(device_suspend, bwn_suspend), 14228 DEVMETHOD(device_resume, bwn_resume), 14229 KOBJMETHOD_END 14230}; 14231static driver_t bwn_driver = { 14232 "bwn", 14233 bwn_methods, 14234 sizeof(struct bwn_softc) 14235}; 14236static devclass_t bwn_devclass; 14237DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14238MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14239MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14240MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14241MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14242