if_bwn.c revision 283537
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 283537 2015-05-25 18:50:26Z glebius $"); 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_var.h> 56#include <net/if_arp.h> 57#include <net/if_dl.h> 58#include <net/if_llc.h> 59#include <net/if_media.h> 60#include <net/if_types.h> 61 62#include <dev/pci/pcivar.h> 63#include <dev/pci/pcireg.h> 64#include <dev/siba/siba_ids.h> 65#include <dev/siba/sibareg.h> 66#include <dev/siba/sibavar.h> 67 68#include <net80211/ieee80211_var.h> 69#include <net80211/ieee80211_radiotap.h> 70#include <net80211/ieee80211_regdomain.h> 71#include <net80211/ieee80211_phy.h> 72#include <net80211/ieee80211_ratectl.h> 73 74#include <dev/bwn/if_bwnreg.h> 75#include <dev/bwn/if_bwnvar.h> 76 77static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 78 "Broadcom driver parameters"); 79 80/* 81 * Tunable & sysctl variables. 82 */ 83 84#ifdef BWN_DEBUG 85static int bwn_debug = 0; 86SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0, 87 "Broadcom debugging printfs"); 88enum { 89 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 90 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 91 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 92 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 93 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 94 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 95 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 96 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 97 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 98 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 99 BWN_DEBUG_NODE = 0x00000400, /* node management */ 100 BWN_DEBUG_LED = 0x00000800, /* led management */ 101 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 102 BWN_DEBUG_LO = 0x00002000, /* LO */ 103 BWN_DEBUG_FW = 0x00004000, /* firmware */ 104 BWN_DEBUG_WME = 0x00008000, /* WME */ 105 BWN_DEBUG_RF = 0x00010000, /* RF */ 106 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 107 BWN_DEBUG_ANY = 0xffffffff 108}; 109#define DPRINTF(sc, m, fmt, ...) do { \ 110 if (sc->sc_debug & (m)) \ 111 printf(fmt, __VA_ARGS__); \ 112} while (0) 113#else 114#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 115#endif 116 117static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 118SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 119 "uses Bad Frames Preemption"); 120static int bwn_bluetooth = 1; 121SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 122 "turns on Bluetooth Coexistence"); 123static int bwn_hwpctl = 0; 124SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 125 "uses H/W power control"); 126static int bwn_msi_disable = 0; /* MSI disabled */ 127TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 128static int bwn_usedma = 1; 129SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 130 "uses DMA"); 131TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 132static int bwn_wme = 1; 133SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 134 "uses WME support"); 135 136static int bwn_attach_pre(struct bwn_softc *); 137static int bwn_attach_post(struct bwn_softc *); 138static void bwn_sprom_bugfixes(device_t); 139static void bwn_init(void *); 140static int bwn_init_locked(struct bwn_softc *); 141static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 142static void bwn_start(struct ifnet *); 143static int bwn_attach_core(struct bwn_mac *); 144static void bwn_reset_core(struct bwn_mac *, uint32_t); 145static int bwn_phy_getinfo(struct bwn_mac *, int); 146static int bwn_chiptest(struct bwn_mac *); 147static int bwn_setup_channels(struct bwn_mac *, int, int); 148static int bwn_phy_g_attach(struct bwn_mac *); 149static void bwn_phy_g_detach(struct bwn_mac *); 150static void bwn_phy_g_init_pre(struct bwn_mac *); 151static int bwn_phy_g_prepare_hw(struct bwn_mac *); 152static int bwn_phy_g_init(struct bwn_mac *); 153static void bwn_phy_g_exit(struct bwn_mac *); 154static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 155static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 156 uint16_t); 157static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 158static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 159 uint16_t); 160static int bwn_phy_g_hwpctl(struct bwn_mac *); 161static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 162static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 163static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 164static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 165static int bwn_phy_g_im(struct bwn_mac *, int); 166static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 167static void bwn_phy_g_set_txpwr(struct bwn_mac *); 168static void bwn_phy_g_task_15s(struct bwn_mac *); 169static void bwn_phy_g_task_60s(struct bwn_mac *); 170static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 171static void bwn_phy_switch_analog(struct bwn_mac *, int); 172static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 173static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 174 uint16_t); 175static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 176static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 177 uint32_t); 178static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 179 uint16_t); 180static void bwn_addchannels(struct ieee80211_channel [], int, int *, 181 const struct bwn_channelinfo *, int); 182static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 183 const struct ieee80211_bpf_params *); 184static void bwn_updateslot(struct ifnet *); 185static void bwn_update_promisc(struct ifnet *); 186static void bwn_wme_init(struct bwn_mac *); 187static int bwn_wme_update(struct ieee80211com *); 188static void bwn_wme_clear(struct bwn_softc *); 189static void bwn_wme_load(struct bwn_mac *); 190static void bwn_wme_loadparams(struct bwn_mac *, 191 const struct wmeParams *, uint16_t); 192static void bwn_scan_start(struct ieee80211com *); 193static void bwn_scan_end(struct ieee80211com *); 194static void bwn_set_channel(struct ieee80211com *); 195static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 196 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 197 const uint8_t [IEEE80211_ADDR_LEN], 198 const uint8_t [IEEE80211_ADDR_LEN]); 199static void bwn_vap_delete(struct ieee80211vap *); 200static void bwn_stop(struct bwn_softc *, int); 201static void bwn_stop_locked(struct bwn_softc *, int); 202static int bwn_core_init(struct bwn_mac *); 203static void bwn_core_start(struct bwn_mac *); 204static void bwn_core_exit(struct bwn_mac *); 205static void bwn_bt_disable(struct bwn_mac *); 206static int bwn_chip_init(struct bwn_mac *); 207static uint64_t bwn_hf_read(struct bwn_mac *); 208static void bwn_hf_write(struct bwn_mac *, uint64_t); 209static void bwn_set_txretry(struct bwn_mac *, int, int); 210static void bwn_rate_init(struct bwn_mac *); 211static void bwn_set_phytxctl(struct bwn_mac *); 212static void bwn_spu_setdelay(struct bwn_mac *, int); 213static void bwn_bt_enable(struct bwn_mac *); 214static void bwn_set_macaddr(struct bwn_mac *); 215static void bwn_crypt_init(struct bwn_mac *); 216static void bwn_chip_exit(struct bwn_mac *); 217static int bwn_fw_fillinfo(struct bwn_mac *); 218static int bwn_fw_loaducode(struct bwn_mac *); 219static int bwn_gpio_init(struct bwn_mac *); 220static int bwn_fw_loadinitvals(struct bwn_mac *); 221static int bwn_phy_init(struct bwn_mac *); 222static void bwn_set_txantenna(struct bwn_mac *, int); 223static void bwn_set_opmode(struct bwn_mac *); 224static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 225static uint8_t bwn_plcp_getcck(const uint8_t); 226static uint8_t bwn_plcp_getofdm(const uint8_t); 227static void bwn_pio_init(struct bwn_mac *); 228static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 229static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 230 int); 231static void bwn_pio_setupqueue_rx(struct bwn_mac *, 232 struct bwn_pio_rxqueue *, int); 233static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 234static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 235 uint16_t); 236static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 237static int bwn_pio_rx(struct bwn_pio_rxqueue *); 238static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 239static void bwn_pio_handle_txeof(struct bwn_mac *, 240 const struct bwn_txstatus *); 241static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 242static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 243static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 244 uint16_t); 245static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 246 uint32_t); 247static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 248 struct mbuf *); 249static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 250static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 251 struct bwn_pio_txqueue *, uint32_t, const void *, int); 252static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 253 uint16_t, uint32_t); 254static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 255 struct bwn_pio_txqueue *, uint16_t, const void *, int); 256static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 257 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 258static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 259 uint16_t, struct bwn_pio_txpkt **); 260static void bwn_dma_init(struct bwn_mac *); 261static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 262static int bwn_dma_mask2type(uint64_t); 263static uint64_t bwn_dma_mask(struct bwn_mac *); 264static uint16_t bwn_dma_base(int, int); 265static void bwn_dma_ringfree(struct bwn_dma_ring **); 266static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 267 int, struct bwn_dmadesc_generic **, 268 struct bwn_dmadesc_meta **); 269static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 270 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 271 int, int); 272static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 273static void bwn_dma_32_suspend(struct bwn_dma_ring *); 274static void bwn_dma_32_resume(struct bwn_dma_ring *); 275static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 276static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 277static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 278 int, struct bwn_dmadesc_generic **, 279 struct bwn_dmadesc_meta **); 280static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 281 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 282 int, int); 283static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 284static void bwn_dma_64_suspend(struct bwn_dma_ring *); 285static void bwn_dma_64_resume(struct bwn_dma_ring *); 286static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 287static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 288static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 289static void bwn_dma_setup(struct bwn_dma_ring *); 290static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 291static void bwn_dma_cleanup(struct bwn_dma_ring *); 292static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 293static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 294static void bwn_dma_rx(struct bwn_dma_ring *); 295static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 296static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 297 struct bwn_dmadesc_meta *); 298static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 299static int bwn_dma_gettype(struct bwn_mac *); 300static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 301static int bwn_dma_freeslot(struct bwn_dma_ring *); 302static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 303static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 304static int bwn_dma_newbuf(struct bwn_dma_ring *, 305 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 306 int); 307static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 308 bus_size_t, int); 309static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 310static void bwn_dma_handle_txeof(struct bwn_mac *, 311 const struct bwn_txstatus *); 312static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 313 struct mbuf *); 314static int bwn_dma_getslot(struct bwn_dma_ring *); 315static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 316 uint8_t); 317static int bwn_dma_attach(struct bwn_mac *); 318static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 319 int, int, int); 320static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 321 const struct bwn_txstatus *, uint16_t, int *); 322static void bwn_dma_free(struct bwn_mac *); 323static void bwn_phy_g_init_sub(struct bwn_mac *); 324static uint8_t bwn_has_hwpctl(struct bwn_mac *); 325static void bwn_phy_init_b5(struct bwn_mac *); 326static void bwn_phy_init_b6(struct bwn_mac *); 327static void bwn_phy_init_a(struct bwn_mac *); 328static void bwn_loopback_calcgain(struct bwn_mac *); 329static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 330static void bwn_lo_g_init(struct bwn_mac *); 331static void bwn_lo_g_adjust(struct bwn_mac *); 332static void bwn_lo_get_powervector(struct bwn_mac *); 333static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 334 const struct bwn_bbatt *, const struct bwn_rfatt *); 335static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 336static void bwn_phy_hwpctl_init(struct bwn_mac *); 337static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 338static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 339 const struct bwn_bbatt *, const struct bwn_rfatt *, 340 uint8_t); 341static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 342static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 343static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 344static void bwn_wa_init(struct bwn_mac *); 345static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 346 uint16_t); 347static void bwn_dummy_transmission(struct bwn_mac *, int, int); 348static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 349 uint32_t); 350static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 351 uint16_t); 352static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 353static void bwn_mac_suspend(struct bwn_mac *); 354static void bwn_mac_enable(struct bwn_mac *); 355static void bwn_psctl(struct bwn_mac *, uint32_t); 356static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 357static void bwn_nrssi_offset(struct bwn_mac *); 358static void bwn_nrssi_threshold(struct bwn_mac *); 359static void bwn_nrssi_slope_11g(struct bwn_mac *); 360static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 361 int16_t); 362static void bwn_set_original_gains(struct bwn_mac *); 363static void bwn_hwpctl_early_init(struct bwn_mac *); 364static void bwn_hwpctl_init_gphy(struct bwn_mac *); 365static uint16_t bwn_phy_g_chan2freq(uint8_t); 366static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 367static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 368 const char *, struct bwn_fwfile *); 369static void bwn_release_firmware(struct bwn_mac *); 370static void bwn_do_release_fw(struct bwn_fwfile *); 371static uint16_t bwn_fwcaps_read(struct bwn_mac *); 372static int bwn_fwinitvals_write(struct bwn_mac *, 373 const struct bwn_fwinitvals *, size_t, size_t); 374static int bwn_switch_channel(struct bwn_mac *, int); 375static uint16_t bwn_ant2phy(int); 376static void bwn_mac_write_bssid(struct bwn_mac *); 377static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 378 const uint8_t *); 379static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 380 const uint8_t *, size_t, const uint8_t *); 381static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 382 const uint8_t *); 383static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 384 const uint8_t *); 385static void bwn_phy_exit(struct bwn_mac *); 386static void bwn_core_stop(struct bwn_mac *); 387static int bwn_switch_band(struct bwn_softc *, 388 struct ieee80211_channel *); 389static void bwn_phy_reset(struct bwn_mac *); 390static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 391static void bwn_set_pretbtt(struct bwn_mac *); 392static int bwn_intr(void *); 393static void bwn_intrtask(void *, int); 394static void bwn_restart(struct bwn_mac *, const char *); 395static void bwn_intr_ucode_debug(struct bwn_mac *); 396static void bwn_intr_tbtt_indication(struct bwn_mac *); 397static void bwn_intr_atim_end(struct bwn_mac *); 398static void bwn_intr_beacon(struct bwn_mac *); 399static void bwn_intr_pmq(struct bwn_mac *); 400static void bwn_intr_noise(struct bwn_mac *); 401static void bwn_intr_txeof(struct bwn_mac *); 402static void bwn_hwreset(void *, int); 403static void bwn_handle_fwpanic(struct bwn_mac *); 404static void bwn_load_beacon0(struct bwn_mac *); 405static void bwn_load_beacon1(struct bwn_mac *); 406static uint32_t bwn_jssi_read(struct bwn_mac *); 407static void bwn_noise_gensample(struct bwn_mac *); 408static void bwn_handle_txeof(struct bwn_mac *, 409 const struct bwn_txstatus *); 410static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 411static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 412static void bwn_start_locked(struct ifnet *); 413static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 414 struct mbuf *); 415static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 416static int bwn_set_txhdr(struct bwn_mac *, 417 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 418 uint16_t); 419static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 420 const uint8_t); 421static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 422static uint8_t bwn_get_fbrate(uint8_t); 423static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 424static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 425static void bwn_phy_lock(struct bwn_mac *); 426static void bwn_phy_unlock(struct bwn_mac *); 427static void bwn_rf_lock(struct bwn_mac *); 428static void bwn_rf_unlock(struct bwn_mac *); 429static void bwn_txpwr(void *, int); 430static void bwn_tasks(void *); 431static void bwn_task_15s(struct bwn_mac *); 432static void bwn_task_30s(struct bwn_mac *); 433static void bwn_task_60s(struct bwn_mac *); 434static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 435 uint8_t); 436static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 437static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 438 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 439 int, int); 440static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 441static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 442static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 443static void bwn_watchdog(void *); 444static void bwn_dma_stop(struct bwn_mac *); 445static void bwn_pio_stop(struct bwn_mac *); 446static void bwn_dma_ringstop(struct bwn_dma_ring **); 447static void bwn_led_attach(struct bwn_mac *); 448static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 449static void bwn_led_event(struct bwn_mac *, int); 450static void bwn_led_blink_start(struct bwn_mac *, int, int); 451static void bwn_led_blink_next(void *); 452static void bwn_led_blink_end(void *); 453static void bwn_rfswitch(void *); 454static void bwn_rf_turnon(struct bwn_mac *); 455static void bwn_rf_turnoff(struct bwn_mac *); 456static void bwn_phy_lp_init_pre(struct bwn_mac *); 457static int bwn_phy_lp_init(struct bwn_mac *); 458static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 459static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 460static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 461 uint16_t); 462static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 463static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 464static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 465static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 466static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 467static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 468static void bwn_phy_lp_task_60s(struct bwn_mac *); 469static void bwn_phy_lp_readsprom(struct bwn_mac *); 470static void bwn_phy_lp_bbinit(struct bwn_mac *); 471static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 472static void bwn_phy_lp_calib(struct bwn_mac *); 473static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 474static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 475static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 476static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 477static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 478static void bwn_phy_lp_digflt_save(struct bwn_mac *); 479static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 480static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 481static void bwn_phy_lp_bugfix(struct bwn_mac *); 482static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 483static void bwn_phy_lp_tblinit(struct bwn_mac *); 484static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 485static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 486static void bwn_phy_lp_b2062_init(struct bwn_mac *); 487static void bwn_phy_lp_b2063_init(struct bwn_mac *); 488static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 489static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 490static void bwn_phy_lp_set_rccap(struct bwn_mac *); 491static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 492static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 493static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 494static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 495 const void *); 496static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 497static struct bwn_txgain 498 bwn_phy_lp_get_txgain(struct bwn_mac *); 499static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 500static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 501static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 502static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 503static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 504static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 505static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 506static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 507static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 508static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 509static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 510static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 511static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 512static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 513static int bwn_phy_lp_loopback(struct bwn_mac *); 514static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 515static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 516 int); 517static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 518 struct bwn_phy_lp_iq_est *); 519static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 520static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 521static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 522static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 523static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 524static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 525static uint8_t bwn_nbits(int32_t); 526static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 527 struct bwn_txgain_entry *); 528static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 529 struct bwn_txgain_entry); 530static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 531 struct bwn_txgain_entry); 532static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 533 struct bwn_txgain_entry); 534static void bwn_sysctl_node(struct bwn_softc *); 535 536static struct resource_spec bwn_res_spec_legacy[] = { 537 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 538 { -1, 0, 0 } 539}; 540 541static struct resource_spec bwn_res_spec_msi[] = { 542 { SYS_RES_IRQ, 1, RF_ACTIVE }, 543 { -1, 0, 0 } 544}; 545 546static const struct bwn_channelinfo bwn_chantable_bg = { 547 .channels = { 548 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 549 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 550 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 551 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 552 { 2472, 13, 30 }, { 2484, 14, 30 } }, 553 .nchannels = 14 554}; 555 556static const struct bwn_channelinfo bwn_chantable_a = { 557 .channels = { 558 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 559 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 560 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 561 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 562 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 563 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 564 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 565 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 566 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 567 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 568 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 569 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 570 { 6080, 216, 30 } }, 571 .nchannels = 37 572}; 573 574static const struct bwn_channelinfo bwn_chantable_n = { 575 .channels = { 576 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 577 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 578 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 579 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 580 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 581 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 582 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 583 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 584 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 585 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 586 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 587 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 588 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 589 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 590 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 591 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 592 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 593 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 594 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 595 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 596 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 597 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 598 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 599 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 600 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 601 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 602 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 603 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 604 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 605 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 606 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 607 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 608 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 609 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 610 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 611 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 612 { 6130, 226, 30 }, { 6140, 228, 30 } }, 613 .nchannels = 110 614}; 615 616static const uint8_t bwn_b2063_chantable_data[33][12] = { 617 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 622 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 624 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 629 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 630 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 631 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 632 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 634 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 635 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 636 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 638 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 643 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 649 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 650}; 651 652static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 653 { 1, 2412, bwn_b2063_chantable_data[0] }, 654 { 2, 2417, bwn_b2063_chantable_data[0] }, 655 { 3, 2422, bwn_b2063_chantable_data[0] }, 656 { 4, 2427, bwn_b2063_chantable_data[1] }, 657 { 5, 2432, bwn_b2063_chantable_data[1] }, 658 { 6, 2437, bwn_b2063_chantable_data[1] }, 659 { 7, 2442, bwn_b2063_chantable_data[1] }, 660 { 8, 2447, bwn_b2063_chantable_data[1] }, 661 { 9, 2452, bwn_b2063_chantable_data[2] }, 662 { 10, 2457, bwn_b2063_chantable_data[2] }, 663 { 11, 2462, bwn_b2063_chantable_data[3] }, 664 { 12, 2467, bwn_b2063_chantable_data[3] }, 665 { 13, 2472, bwn_b2063_chantable_data[3] }, 666 { 14, 2484, bwn_b2063_chantable_data[4] }, 667 { 34, 5170, bwn_b2063_chantable_data[5] }, 668 { 36, 5180, bwn_b2063_chantable_data[6] }, 669 { 38, 5190, bwn_b2063_chantable_data[7] }, 670 { 40, 5200, bwn_b2063_chantable_data[8] }, 671 { 42, 5210, bwn_b2063_chantable_data[9] }, 672 { 44, 5220, bwn_b2063_chantable_data[10] }, 673 { 46, 5230, bwn_b2063_chantable_data[11] }, 674 { 48, 5240, bwn_b2063_chantable_data[12] }, 675 { 52, 5260, bwn_b2063_chantable_data[13] }, 676 { 56, 5280, bwn_b2063_chantable_data[14] }, 677 { 60, 5300, bwn_b2063_chantable_data[14] }, 678 { 64, 5320, bwn_b2063_chantable_data[15] }, 679 { 100, 5500, bwn_b2063_chantable_data[16] }, 680 { 104, 5520, bwn_b2063_chantable_data[17] }, 681 { 108, 5540, bwn_b2063_chantable_data[18] }, 682 { 112, 5560, bwn_b2063_chantable_data[19] }, 683 { 116, 5580, bwn_b2063_chantable_data[20] }, 684 { 120, 5600, bwn_b2063_chantable_data[21] }, 685 { 124, 5620, bwn_b2063_chantable_data[21] }, 686 { 128, 5640, bwn_b2063_chantable_data[22] }, 687 { 132, 5660, bwn_b2063_chantable_data[22] }, 688 { 136, 5680, bwn_b2063_chantable_data[22] }, 689 { 140, 5700, bwn_b2063_chantable_data[23] }, 690 { 149, 5745, bwn_b2063_chantable_data[23] }, 691 { 153, 5765, bwn_b2063_chantable_data[23] }, 692 { 157, 5785, bwn_b2063_chantable_data[23] }, 693 { 161, 5805, bwn_b2063_chantable_data[23] }, 694 { 165, 5825, bwn_b2063_chantable_data[23] }, 695 { 184, 4920, bwn_b2063_chantable_data[24] }, 696 { 188, 4940, bwn_b2063_chantable_data[25] }, 697 { 192, 4960, bwn_b2063_chantable_data[26] }, 698 { 196, 4980, bwn_b2063_chantable_data[27] }, 699 { 200, 5000, bwn_b2063_chantable_data[28] }, 700 { 204, 5020, bwn_b2063_chantable_data[29] }, 701 { 208, 5040, bwn_b2063_chantable_data[30] }, 702 { 212, 5060, bwn_b2063_chantable_data[31] }, 703 { 216, 5080, bwn_b2063_chantable_data[32] } 704}; 705 706static const uint8_t bwn_b2062_chantable_data[22][12] = { 707 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 708 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 720 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 727 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 728 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 729}; 730 731static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 732 { 1, 2412, bwn_b2062_chantable_data[0] }, 733 { 2, 2417, bwn_b2062_chantable_data[0] }, 734 { 3, 2422, bwn_b2062_chantable_data[0] }, 735 { 4, 2427, bwn_b2062_chantable_data[0] }, 736 { 5, 2432, bwn_b2062_chantable_data[0] }, 737 { 6, 2437, bwn_b2062_chantable_data[0] }, 738 { 7, 2442, bwn_b2062_chantable_data[0] }, 739 { 8, 2447, bwn_b2062_chantable_data[0] }, 740 { 9, 2452, bwn_b2062_chantable_data[0] }, 741 { 10, 2457, bwn_b2062_chantable_data[0] }, 742 { 11, 2462, bwn_b2062_chantable_data[0] }, 743 { 12, 2467, bwn_b2062_chantable_data[0] }, 744 { 13, 2472, bwn_b2062_chantable_data[0] }, 745 { 14, 2484, bwn_b2062_chantable_data[0] }, 746 { 34, 5170, bwn_b2062_chantable_data[1] }, 747 { 38, 5190, bwn_b2062_chantable_data[2] }, 748 { 42, 5210, bwn_b2062_chantable_data[2] }, 749 { 46, 5230, bwn_b2062_chantable_data[3] }, 750 { 36, 5180, bwn_b2062_chantable_data[4] }, 751 { 40, 5200, bwn_b2062_chantable_data[5] }, 752 { 44, 5220, bwn_b2062_chantable_data[6] }, 753 { 48, 5240, bwn_b2062_chantable_data[3] }, 754 { 52, 5260, bwn_b2062_chantable_data[3] }, 755 { 56, 5280, bwn_b2062_chantable_data[3] }, 756 { 60, 5300, bwn_b2062_chantable_data[7] }, 757 { 64, 5320, bwn_b2062_chantable_data[8] }, 758 { 100, 5500, bwn_b2062_chantable_data[9] }, 759 { 104, 5520, bwn_b2062_chantable_data[10] }, 760 { 108, 5540, bwn_b2062_chantable_data[10] }, 761 { 112, 5560, bwn_b2062_chantable_data[10] }, 762 { 116, 5580, bwn_b2062_chantable_data[11] }, 763 { 120, 5600, bwn_b2062_chantable_data[12] }, 764 { 124, 5620, bwn_b2062_chantable_data[12] }, 765 { 128, 5640, bwn_b2062_chantable_data[12] }, 766 { 132, 5660, bwn_b2062_chantable_data[12] }, 767 { 136, 5680, bwn_b2062_chantable_data[12] }, 768 { 140, 5700, bwn_b2062_chantable_data[12] }, 769 { 149, 5745, bwn_b2062_chantable_data[12] }, 770 { 153, 5765, bwn_b2062_chantable_data[12] }, 771 { 157, 5785, bwn_b2062_chantable_data[12] }, 772 { 161, 5805, bwn_b2062_chantable_data[12] }, 773 { 165, 5825, bwn_b2062_chantable_data[12] }, 774 { 184, 4920, bwn_b2062_chantable_data[13] }, 775 { 188, 4940, bwn_b2062_chantable_data[14] }, 776 { 192, 4960, bwn_b2062_chantable_data[15] }, 777 { 196, 4980, bwn_b2062_chantable_data[16] }, 778 { 200, 5000, bwn_b2062_chantable_data[17] }, 779 { 204, 5020, bwn_b2062_chantable_data[18] }, 780 { 208, 5040, bwn_b2062_chantable_data[19] }, 781 { 212, 5060, bwn_b2062_chantable_data[20] }, 782 { 216, 5080, bwn_b2062_chantable_data[21] } 783}; 784 785/* for LP PHY */ 786static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 787 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 788 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 789 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 790 { 13, -66, 13 }, { 14, -66, 13 }, 791}; 792 793/* for LP PHY */ 794static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 795 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 796 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 797 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 798 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 799 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 800 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 801 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 802 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 803 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 804 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 805 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 806 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 807 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 808}; 809 810static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 811 812static const uint8_t bwn_tab_sigsq_tbl[] = { 813 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 814 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 817 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 818 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 819}; 820 821static const uint8_t bwn_tab_pllfrac_tbl[] = { 822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 823 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 824}; 825 826static const uint16_t bwn_tabl_iqlocal_tbl[] = { 827 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 828 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 831 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 832 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 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, 0x0000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 839}; 840 841static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 842static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 843static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 844static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 845static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 846const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 847 848#define VENDOR_LED_ACT(vendor) \ 849{ \ 850 .vid = PCI_VENDOR_##vendor, \ 851 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 852} 853 854static const struct { 855 uint16_t vid; 856 uint8_t led_act[BWN_LED_MAX]; 857} bwn_vendor_led_act[] = { 858 VENDOR_LED_ACT(COMPAQ), 859 VENDOR_LED_ACT(ASUSTEK) 860}; 861 862static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 863 { BWN_VENDOR_LED_ACT_DEFAULT }; 864 865#undef VENDOR_LED_ACT 866 867static const struct { 868 int on_dur; 869 int off_dur; 870} bwn_led_duration[109] = { 871 [0] = { 400, 100 }, 872 [2] = { 150, 75 }, 873 [4] = { 90, 45 }, 874 [11] = { 66, 34 }, 875 [12] = { 53, 26 }, 876 [18] = { 42, 21 }, 877 [22] = { 35, 17 }, 878 [24] = { 32, 16 }, 879 [36] = { 21, 10 }, 880 [48] = { 16, 8 }, 881 [72] = { 11, 5 }, 882 [96] = { 9, 4 }, 883 [108] = { 7, 3 } 884}; 885 886static const uint16_t bwn_wme_shm_offsets[] = { 887 [0] = BWN_WME_BESTEFFORT, 888 [1] = BWN_WME_BACKGROUND, 889 [2] = BWN_WME_VOICE, 890 [3] = BWN_WME_VIDEO, 891}; 892 893static const struct siba_devid bwn_devs[] = { 894 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 895 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 896 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 897 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 898 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 899 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 900 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 901 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 902 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 903}; 904 905static int 906bwn_probe(device_t dev) 907{ 908 int i; 909 910 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 911 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 912 siba_get_device(dev) == bwn_devs[i].sd_device && 913 siba_get_revid(dev) == bwn_devs[i].sd_rev) 914 return (BUS_PROBE_DEFAULT); 915 } 916 917 return (ENXIO); 918} 919 920static int 921bwn_attach(device_t dev) 922{ 923 struct bwn_mac *mac; 924 struct bwn_softc *sc = device_get_softc(dev); 925 int error, i, msic, reg; 926 927 sc->sc_dev = dev; 928#ifdef BWN_DEBUG 929 sc->sc_debug = bwn_debug; 930#endif 931 932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 933 error = bwn_attach_pre(sc); 934 if (error != 0) 935 return (error); 936 bwn_sprom_bugfixes(dev); 937 sc->sc_flags |= BWN_FLAG_ATTACHED; 938 } 939 940 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 941 if (siba_get_pci_device(dev) != 0x4313 && 942 siba_get_pci_device(dev) != 0x431a && 943 siba_get_pci_device(dev) != 0x4321) { 944 device_printf(sc->sc_dev, 945 "skip 802.11 cores\n"); 946 return (ENODEV); 947 } 948 } 949 950 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 951 M_NOWAIT | M_ZERO); 952 if (mac == NULL) 953 return (ENOMEM); 954 mac->mac_sc = sc; 955 mac->mac_status = BWN_MAC_STATUS_UNINIT; 956 if (bwn_bfp != 0) 957 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 958 959 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 960 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 961 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 962 963 error = bwn_attach_core(mac); 964 if (error) 965 goto fail0; 966 bwn_led_attach(mac); 967 968 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 969 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 970 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 971 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 972 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 973 mac->mac_phy.rf_rev); 974 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 975 device_printf(sc->sc_dev, "DMA (%d bits)\n", 976 mac->mac_method.dma.dmatype); 977 else 978 device_printf(sc->sc_dev, "PIO\n"); 979 980 /* 981 * setup PCI resources and interrupt. 982 */ 983 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 984 msic = pci_msi_count(dev); 985 if (bootverbose) 986 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 987 } else 988 msic = 0; 989 990 mac->mac_intr_spec = bwn_res_spec_legacy; 991 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 992 if (pci_alloc_msi(dev, &msic) == 0) { 993 device_printf(sc->sc_dev, 994 "Using %d MSI messages\n", msic); 995 mac->mac_intr_spec = bwn_res_spec_msi; 996 mac->mac_msi = 1; 997 } 998 } 999 1000 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1001 mac->mac_res_irq); 1002 if (error) { 1003 device_printf(sc->sc_dev, 1004 "couldn't allocate IRQ resources (%d)\n", error); 1005 goto fail1; 1006 } 1007 1008 if (mac->mac_msi == 0) 1009 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1010 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1011 &mac->mac_intrhand[0]); 1012 else { 1013 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1014 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1015 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1016 &mac->mac_intrhand[i]); 1017 if (error != 0) { 1018 device_printf(sc->sc_dev, 1019 "couldn't setup interrupt (%d)\n", error); 1020 break; 1021 } 1022 } 1023 } 1024 1025 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1026 1027 /* 1028 * calls attach-post routine 1029 */ 1030 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1031 bwn_attach_post(sc); 1032 1033 return (0); 1034fail1: 1035 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1036 pci_release_msi(dev); 1037fail0: 1038 free(mac, M_DEVBUF); 1039 return (error); 1040} 1041 1042static int 1043bwn_is_valid_ether_addr(uint8_t *addr) 1044{ 1045 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1046 1047 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1048 return (FALSE); 1049 1050 return (TRUE); 1051} 1052 1053static int 1054bwn_attach_post(struct bwn_softc *sc) 1055{ 1056 struct ieee80211com *ic; 1057 struct ifnet *ifp = sc->sc_ifp; 1058 1059 ic = ifp->if_l2com; 1060 ic->ic_ifp = ifp; 1061 ic->ic_softc = sc; 1062 ic->ic_name = device_get_nameunit(sc->sc_dev); 1063 /* XXX not right but it's not used anywhere important */ 1064 ic->ic_phytype = IEEE80211_T_OFDM; 1065 ic->ic_opmode = IEEE80211_M_STA; 1066 ic->ic_caps = 1067 IEEE80211_C_STA /* station mode supported */ 1068 | IEEE80211_C_MONITOR /* monitor mode */ 1069 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1070 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1071 | IEEE80211_C_SHSLOT /* short slot time supported */ 1072 | IEEE80211_C_WME /* WME/WMM supported */ 1073 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1074 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1075 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1076 ; 1077 1078 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1079 1080 /* call MI attach routine. */ 1081 ieee80211_ifattach(ic, 1082 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1083 siba_sprom_get_mac_80211a(sc->sc_dev) : 1084 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1085 1086 ic->ic_headroom = sizeof(struct bwn_txhdr); 1087 1088 /* override default methods */ 1089 ic->ic_raw_xmit = bwn_raw_xmit; 1090 ic->ic_updateslot = bwn_updateslot; 1091 ic->ic_update_promisc = bwn_update_promisc; 1092 ic->ic_wme.wme_update = bwn_wme_update; 1093 1094 ic->ic_scan_start = bwn_scan_start; 1095 ic->ic_scan_end = bwn_scan_end; 1096 ic->ic_set_channel = bwn_set_channel; 1097 1098 ic->ic_vap_create = bwn_vap_create; 1099 ic->ic_vap_delete = bwn_vap_delete; 1100 1101 ieee80211_radiotap_attach(ic, 1102 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1103 BWN_TX_RADIOTAP_PRESENT, 1104 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1105 BWN_RX_RADIOTAP_PRESENT); 1106 1107 bwn_sysctl_node(sc); 1108 1109 if (bootverbose) 1110 ieee80211_announce(ic); 1111 return (0); 1112} 1113 1114static void 1115bwn_phy_detach(struct bwn_mac *mac) 1116{ 1117 1118 if (mac->mac_phy.detach != NULL) 1119 mac->mac_phy.detach(mac); 1120} 1121 1122static int 1123bwn_detach(device_t dev) 1124{ 1125 struct bwn_softc *sc = device_get_softc(dev); 1126 struct bwn_mac *mac = sc->sc_curmac; 1127 struct ifnet *ifp = sc->sc_ifp; 1128 struct ieee80211com *ic = ifp->if_l2com; 1129 int i; 1130 1131 sc->sc_flags |= BWN_FLAG_INVALID; 1132 1133 if (device_is_attached(sc->sc_dev)) { 1134 bwn_stop(sc, 1); 1135 bwn_dma_free(mac); 1136 callout_drain(&sc->sc_led_blink_ch); 1137 callout_drain(&sc->sc_rfswitch_ch); 1138 callout_drain(&sc->sc_task_ch); 1139 callout_drain(&sc->sc_watchdog_ch); 1140 bwn_phy_detach(mac); 1141 if (ifp != NULL) { 1142 ieee80211_draintask(ic, &mac->mac_hwreset); 1143 ieee80211_draintask(ic, &mac->mac_txpower); 1144 ieee80211_ifdetach(ic); 1145 if_free(ifp); 1146 } 1147 } 1148 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1149 taskqueue_free(sc->sc_tq); 1150 1151 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1152 if (mac->mac_intrhand[i] != NULL) { 1153 bus_teardown_intr(dev, mac->mac_res_irq[i], 1154 mac->mac_intrhand[i]); 1155 mac->mac_intrhand[i] = NULL; 1156 } 1157 } 1158 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1159 if (mac->mac_msi != 0) 1160 pci_release_msi(dev); 1161 1162 BWN_LOCK_DESTROY(sc); 1163 return (0); 1164} 1165 1166static int 1167bwn_attach_pre(struct bwn_softc *sc) 1168{ 1169 struct ifnet *ifp; 1170 int error = 0; 1171 1172 BWN_LOCK_INIT(sc); 1173 TAILQ_INIT(&sc->sc_maclist); 1174 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1175 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1176 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1177 1178 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1179 taskqueue_thread_enqueue, &sc->sc_tq); 1180 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1181 "%s taskq", device_get_nameunit(sc->sc_dev)); 1182 1183 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1184 if (ifp == NULL) { 1185 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1186 error = ENOSPC; 1187 goto fail; 1188 } 1189 1190 /* set these up early for if_printf use */ 1191 if_initname(ifp, device_get_name(sc->sc_dev), 1192 device_get_unit(sc->sc_dev)); 1193 1194 ifp->if_softc = sc; 1195 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1196 ifp->if_init = bwn_init; 1197 ifp->if_ioctl = bwn_ioctl; 1198 ifp->if_start = bwn_start; 1199 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1200 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1201 IFQ_SET_READY(&ifp->if_snd); 1202 1203 return (0); 1204 1205fail: BWN_LOCK_DESTROY(sc); 1206 return (error); 1207} 1208 1209static void 1210bwn_sprom_bugfixes(device_t dev) 1211{ 1212#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1213 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1214 (siba_get_pci_device(dev) == _device) && \ 1215 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1216 (siba_get_pci_subdevice(dev) == _subdevice)) 1217 1218 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1219 siba_get_pci_subdevice(dev) == 0x4e && 1220 siba_get_pci_revid(dev) > 0x40) 1221 siba_sprom_set_bf_lo(dev, 1222 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1223 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1224 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1225 siba_sprom_set_bf_lo(dev, 1226 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1227 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1228 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1229 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1230 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1232 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1233 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1234 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1235 siba_sprom_set_bf_lo(dev, 1236 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1237 } 1238#undef BWN_ISDEV 1239} 1240 1241static int 1242bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1243{ 1244#define IS_RUNNING(ifp) \ 1245 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1246 struct bwn_softc *sc = ifp->if_softc; 1247 struct ieee80211com *ic = ifp->if_l2com; 1248 struct ifreq *ifr = (struct ifreq *)data; 1249 int error = 0, startall; 1250 1251 switch (cmd) { 1252 case SIOCSIFFLAGS: 1253 startall = 0; 1254 if (IS_RUNNING(ifp)) { 1255 bwn_update_promisc(ifp); 1256 } else if (ifp->if_flags & IFF_UP) { 1257 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1258 bwn_init(sc); 1259 startall = 1; 1260 } 1261 } else 1262 bwn_stop(sc, 1); 1263 if (startall) 1264 ieee80211_start_all(ic); 1265 break; 1266 case SIOCGIFMEDIA: 1267 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1268 break; 1269 case SIOCGIFADDR: 1270 error = ether_ioctl(ifp, cmd, data); 1271 break; 1272 default: 1273 error = EINVAL; 1274 break; 1275 } 1276 return (error); 1277} 1278 1279static void 1280bwn_start(struct ifnet *ifp) 1281{ 1282 struct bwn_softc *sc = ifp->if_softc; 1283 1284 BWN_LOCK(sc); 1285 bwn_start_locked(ifp); 1286 BWN_UNLOCK(sc); 1287} 1288 1289static void 1290bwn_start_locked(struct ifnet *ifp) 1291{ 1292 struct bwn_softc *sc = ifp->if_softc; 1293 struct bwn_mac *mac = sc->sc_curmac; 1294 struct ieee80211_frame *wh; 1295 struct ieee80211_node *ni; 1296 struct ieee80211_key *k; 1297 struct mbuf *m; 1298 1299 BWN_ASSERT_LOCKED(sc); 1300 1301 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1302 mac->mac_status < BWN_MAC_STATUS_STARTED) 1303 return; 1304 1305 for (;;) { 1306 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1307 if (m == NULL) 1308 break; 1309 1310 if (bwn_tx_isfull(sc, m)) 1311 break; 1312 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1313 if (ni == NULL) { 1314 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1315 m_freem(m); 1316 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1317 continue; 1318 } 1319 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1320 wh = mtod(m, struct ieee80211_frame *); 1321 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1322 k = ieee80211_crypto_encap(ni, m); 1323 if (k == NULL) { 1324 ieee80211_free_node(ni); 1325 m_freem(m); 1326 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1327 continue; 1328 } 1329 } 1330 wh = NULL; /* Catch any invalid use */ 1331 1332 if (bwn_tx_start(sc, ni, m) != 0) { 1333 if (ni != NULL) 1334 ieee80211_free_node(ni); 1335 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1336 continue; 1337 } 1338 1339 sc->sc_watchdog_timer = 5; 1340 } 1341} 1342 1343static int 1344bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1345{ 1346 struct bwn_dma_ring *dr; 1347 struct bwn_mac *mac = sc->sc_curmac; 1348 struct bwn_pio_txqueue *tq; 1349 struct ifnet *ifp = sc->sc_ifp; 1350 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1351 1352 BWN_ASSERT_LOCKED(sc); 1353 1354 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1355 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1356 if (dr->dr_stop == 1 || 1357 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1358 dr->dr_stop = 1; 1359 goto full; 1360 } 1361 } else { 1362 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1363 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1364 pktlen > (tq->tq_size - tq->tq_used)) { 1365 tq->tq_stop = 1; 1366 goto full; 1367 } 1368 } 1369 return (0); 1370full: 1371 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1372 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1373 return (1); 1374} 1375 1376static int 1377bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1378{ 1379 struct bwn_mac *mac = sc->sc_curmac; 1380 int error; 1381 1382 BWN_ASSERT_LOCKED(sc); 1383 1384 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1385 m_freem(m); 1386 return (ENXIO); 1387 } 1388 1389 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1390 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1391 if (error) { 1392 m_freem(m); 1393 return (error); 1394 } 1395 return (0); 1396} 1397 1398static int 1399bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1400{ 1401 struct bwn_pio_txpkt *tp; 1402 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1403 struct bwn_softc *sc = mac->mac_sc; 1404 struct bwn_txhdr txhdr; 1405 struct mbuf *m_new; 1406 uint32_t ctl32; 1407 int error; 1408 uint16_t ctl16; 1409 1410 BWN_ASSERT_LOCKED(sc); 1411 1412 /* XXX TODO send packets after DTIM */ 1413 1414 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1415 tp = TAILQ_FIRST(&tq->tq_pktlist); 1416 tp->tp_ni = ni; 1417 tp->tp_m = m; 1418 1419 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1420 if (error) { 1421 device_printf(sc->sc_dev, "tx fail\n"); 1422 return (error); 1423 } 1424 1425 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1426 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1427 tq->tq_free--; 1428 1429 if (siba_get_revid(sc->sc_dev) >= 8) { 1430 /* 1431 * XXX please removes m_defrag(9) 1432 */ 1433 m_new = m_defrag(m, M_NOWAIT); 1434 if (m_new == NULL) { 1435 device_printf(sc->sc_dev, 1436 "%s: can't defrag TX buffer\n", 1437 __func__); 1438 return (ENOBUFS); 1439 } 1440 if (m_new->m_next != NULL) 1441 device_printf(sc->sc_dev, 1442 "TODO: fragmented packets for PIO\n"); 1443 tp->tp_m = m_new; 1444 1445 /* send HEADER */ 1446 ctl32 = bwn_pio_write_multi_4(mac, tq, 1447 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1448 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1449 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1450 /* send BODY */ 1451 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1452 mtod(m_new, const void *), m_new->m_pkthdr.len); 1453 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1454 ctl32 | BWN_PIO8_TXCTL_EOF); 1455 } else { 1456 ctl16 = bwn_pio_write_multi_2(mac, tq, 1457 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1458 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1459 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1460 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1461 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1462 ctl16 | BWN_PIO_TXCTL_EOF); 1463 } 1464 1465 return (0); 1466} 1467 1468static struct bwn_pio_txqueue * 1469bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1470{ 1471 1472 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1473 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1474 1475 switch (prio) { 1476 case 0: 1477 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1478 case 1: 1479 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1480 case 2: 1481 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1482 case 3: 1483 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1484 } 1485 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1486 return (NULL); 1487} 1488 1489static int 1490bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1491{ 1492#define BWN_GET_TXHDRCACHE(slot) \ 1493 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1494 struct bwn_dma *dma = &mac->mac_method.dma; 1495 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1496 struct bwn_dmadesc_generic *desc; 1497 struct bwn_dmadesc_meta *mt; 1498 struct bwn_softc *sc = mac->mac_sc; 1499 struct ifnet *ifp = sc->sc_ifp; 1500 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1501 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1502 1503 BWN_ASSERT_LOCKED(sc); 1504 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1505 1506 /* XXX send after DTIM */ 1507 1508 slot = bwn_dma_getslot(dr); 1509 dr->getdesc(dr, slot, &desc, &mt); 1510 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1511 ("%s:%d: fail", __func__, __LINE__)); 1512 1513 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1514 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1515 BWN_DMA_COOKIE(dr, slot)); 1516 if (error) 1517 goto fail; 1518 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1519 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1520 &mt->mt_paddr, BUS_DMA_NOWAIT); 1521 if (error) { 1522 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1523 __func__, error); 1524 goto fail; 1525 } 1526 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1527 BUS_DMASYNC_PREWRITE); 1528 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1529 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1530 BUS_DMASYNC_PREWRITE); 1531 1532 slot = bwn_dma_getslot(dr); 1533 dr->getdesc(dr, slot, &desc, &mt); 1534 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1535 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1536 mt->mt_m = m; 1537 mt->mt_ni = ni; 1538 1539 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1540 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1541 if (error && error != EFBIG) { 1542 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1543 __func__, error); 1544 goto fail; 1545 } 1546 if (error) { /* error == EFBIG */ 1547 struct mbuf *m_new; 1548 1549 m_new = m_defrag(m, M_NOWAIT); 1550 if (m_new == NULL) { 1551 if_printf(ifp, "%s: can't defrag TX buffer\n", 1552 __func__); 1553 error = ENOBUFS; 1554 goto fail; 1555 } else { 1556 m = m_new; 1557 } 1558 1559 mt->mt_m = m; 1560 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1561 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1562 if (error) { 1563 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1564 __func__, error); 1565 goto fail; 1566 } 1567 } 1568 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1569 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1570 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1571 BUS_DMASYNC_PREWRITE); 1572 1573 /* XXX send after DTIM */ 1574 1575 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1576 return (0); 1577fail: 1578 dr->dr_curslot = backup[0]; 1579 dr->dr_usedslot = backup[1]; 1580 return (error); 1581#undef BWN_GET_TXHDRCACHE 1582} 1583 1584static void 1585bwn_watchdog(void *arg) 1586{ 1587 struct bwn_softc *sc = arg; 1588 struct ifnet *ifp = sc->sc_ifp; 1589 1590 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1591 if_printf(ifp, "device timeout\n"); 1592 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1593 } 1594 callout_schedule(&sc->sc_watchdog_ch, hz); 1595} 1596 1597static int 1598bwn_attach_core(struct bwn_mac *mac) 1599{ 1600 struct bwn_softc *sc = mac->mac_sc; 1601 int error, have_bg = 0, have_a = 0; 1602 uint32_t high; 1603 1604 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1605 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1606 1607 siba_powerup(sc->sc_dev, 0); 1608 1609 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1610 bwn_reset_core(mac, 1611 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1612 error = bwn_phy_getinfo(mac, high); 1613 if (error) 1614 goto fail; 1615 1616 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1617 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1618 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1619 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1620 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1621 have_a = have_bg = 0; 1622 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1623 have_a = 1; 1624 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1625 mac->mac_phy.type == BWN_PHYTYPE_N || 1626 mac->mac_phy.type == BWN_PHYTYPE_LP) 1627 have_bg = 1; 1628 else 1629 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1630 mac->mac_phy.type)); 1631 } 1632 /* XXX turns off PHY A because it's not supported */ 1633 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1634 mac->mac_phy.type != BWN_PHYTYPE_N) { 1635 have_a = 0; 1636 have_bg = 1; 1637 } 1638 1639 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1640 mac->mac_phy.attach = bwn_phy_g_attach; 1641 mac->mac_phy.detach = bwn_phy_g_detach; 1642 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1643 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1644 mac->mac_phy.init = bwn_phy_g_init; 1645 mac->mac_phy.exit = bwn_phy_g_exit; 1646 mac->mac_phy.phy_read = bwn_phy_g_read; 1647 mac->mac_phy.phy_write = bwn_phy_g_write; 1648 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1649 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1650 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1651 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1652 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1653 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1654 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1655 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1656 mac->mac_phy.set_im = bwn_phy_g_im; 1657 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1658 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1659 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1660 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1661 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1662 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1663 mac->mac_phy.init = bwn_phy_lp_init; 1664 mac->mac_phy.phy_read = bwn_phy_lp_read; 1665 mac->mac_phy.phy_write = bwn_phy_lp_write; 1666 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1667 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1668 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1669 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1670 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1671 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1672 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1673 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1674 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1675 } else { 1676 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1677 mac->mac_phy.type); 1678 error = ENXIO; 1679 goto fail; 1680 } 1681 1682 mac->mac_phy.gmode = have_bg; 1683 if (mac->mac_phy.attach != NULL) { 1684 error = mac->mac_phy.attach(mac); 1685 if (error) { 1686 device_printf(sc->sc_dev, "failed\n"); 1687 goto fail; 1688 } 1689 } 1690 1691 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1692 1693 error = bwn_chiptest(mac); 1694 if (error) 1695 goto fail; 1696 error = bwn_setup_channels(mac, have_bg, have_a); 1697 if (error) { 1698 device_printf(sc->sc_dev, "failed to setup channels\n"); 1699 goto fail; 1700 } 1701 1702 if (sc->sc_curmac == NULL) 1703 sc->sc_curmac = mac; 1704 1705 error = bwn_dma_attach(mac); 1706 if (error != 0) { 1707 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1708 goto fail; 1709 } 1710 1711 mac->mac_phy.switch_analog(mac, 0); 1712 1713 siba_dev_down(sc->sc_dev, 0); 1714fail: 1715 siba_powerdown(sc->sc_dev); 1716 return (error); 1717} 1718 1719static void 1720bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1721{ 1722 struct bwn_softc *sc = mac->mac_sc; 1723 uint32_t low, ctl; 1724 1725 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1726 1727 siba_dev_up(sc->sc_dev, flags); 1728 DELAY(2000); 1729 1730 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1731 ~BWN_TGSLOW_PHYRESET; 1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1734 DELAY(1000); 1735 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1736 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1737 DELAY(1000); 1738 1739 if (mac->mac_phy.switch_analog != NULL) 1740 mac->mac_phy.switch_analog(mac, 1); 1741 1742 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1743 if (flags & BWN_TGSLOW_SUPPORT_G) 1744 ctl |= BWN_MACCTL_GMODE; 1745 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1746} 1747 1748static int 1749bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1750{ 1751 struct bwn_phy *phy = &mac->mac_phy; 1752 struct bwn_softc *sc = mac->mac_sc; 1753 uint32_t tmp; 1754 1755 /* PHY */ 1756 tmp = BWN_READ_2(mac, BWN_PHYVER); 1757 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1758 phy->rf_on = 1; 1759 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1760 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1761 phy->rev = (tmp & BWN_PHYVER_VERSION); 1762 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1763 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1764 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1765 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1766 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1767 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1768 goto unsupphy; 1769 1770 /* RADIO */ 1771 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1772 if (siba_get_chiprev(sc->sc_dev) == 0) 1773 tmp = 0x3205017f; 1774 else if (siba_get_chiprev(sc->sc_dev) == 1) 1775 tmp = 0x4205017f; 1776 else 1777 tmp = 0x5205017f; 1778 } else { 1779 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1780 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1781 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1782 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1783 } 1784 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1785 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1786 phy->rf_manuf = (tmp & 0x00000fff); 1787 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1788 goto unsupradio; 1789 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1790 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1791 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1792 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1793 (phy->type == BWN_PHYTYPE_N && 1794 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1795 (phy->type == BWN_PHYTYPE_LP && 1796 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1797 goto unsupradio; 1798 1799 return (0); 1800unsupphy: 1801 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1802 "analog %#x)\n", 1803 phy->type, phy->rev, phy->analog); 1804 return (ENXIO); 1805unsupradio: 1806 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1807 "rev %#x)\n", 1808 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1809 return (ENXIO); 1810} 1811 1812static int 1813bwn_chiptest(struct bwn_mac *mac) 1814{ 1815#define TESTVAL0 0x55aaaa55 1816#define TESTVAL1 0xaa5555aa 1817 struct bwn_softc *sc = mac->mac_sc; 1818 uint32_t v, backup; 1819 1820 BWN_LOCK(sc); 1821 1822 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1823 1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1826 goto error; 1827 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1828 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1829 goto error; 1830 1831 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1832 1833 if ((siba_get_revid(sc->sc_dev) >= 3) && 1834 (siba_get_revid(sc->sc_dev) <= 10)) { 1835 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1836 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1837 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1838 goto error; 1839 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1840 goto error; 1841 } 1842 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1843 1844 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1845 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1846 goto error; 1847 1848 BWN_UNLOCK(sc); 1849 return (0); 1850error: 1851 BWN_UNLOCK(sc); 1852 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1853 return (ENODEV); 1854} 1855 1856#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1857#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1858 1859static int 1860bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1861{ 1862 struct bwn_softc *sc = mac->mac_sc; 1863 struct ifnet *ifp = sc->sc_ifp; 1864 struct ieee80211com *ic = ifp->if_l2com; 1865 1866 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1867 ic->ic_nchans = 0; 1868 1869 if (have_bg) 1870 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1871 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1872 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1873 if (have_a) 1874 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1875 &ic->ic_nchans, &bwn_chantable_n, 1876 IEEE80211_CHAN_HTA); 1877 } else { 1878 if (have_a) 1879 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1880 &ic->ic_nchans, &bwn_chantable_a, 1881 IEEE80211_CHAN_A); 1882 } 1883 1884 mac->mac_phy.supports_2ghz = have_bg; 1885 mac->mac_phy.supports_5ghz = have_a; 1886 1887 return (ic->ic_nchans == 0 ? ENXIO : 0); 1888} 1889 1890static uint32_t 1891bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1892{ 1893 uint32_t ret; 1894 1895 BWN_ASSERT_LOCKED(mac->mac_sc); 1896 1897 if (way == BWN_SHARED) { 1898 KASSERT((offset & 0x0001) == 0, 1899 ("%s:%d warn", __func__, __LINE__)); 1900 if (offset & 0x0003) { 1901 bwn_shm_ctlword(mac, way, offset >> 2); 1902 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1903 ret <<= 16; 1904 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1905 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1906 goto out; 1907 } 1908 offset >>= 2; 1909 } 1910 bwn_shm_ctlword(mac, way, offset); 1911 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1912out: 1913 return (ret); 1914} 1915 1916static uint16_t 1917bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1918{ 1919 uint16_t ret; 1920 1921 BWN_ASSERT_LOCKED(mac->mac_sc); 1922 1923 if (way == BWN_SHARED) { 1924 KASSERT((offset & 0x0001) == 0, 1925 ("%s:%d warn", __func__, __LINE__)); 1926 if (offset & 0x0003) { 1927 bwn_shm_ctlword(mac, way, offset >> 2); 1928 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1929 goto out; 1930 } 1931 offset >>= 2; 1932 } 1933 bwn_shm_ctlword(mac, way, offset); 1934 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1935out: 1936 1937 return (ret); 1938} 1939 1940static void 1941bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1942 uint16_t offset) 1943{ 1944 uint32_t control; 1945 1946 control = way; 1947 control <<= 16; 1948 control |= offset; 1949 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1950} 1951 1952static void 1953bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1954 uint32_t value) 1955{ 1956 BWN_ASSERT_LOCKED(mac->mac_sc); 1957 1958 if (way == BWN_SHARED) { 1959 KASSERT((offset & 0x0001) == 0, 1960 ("%s:%d warn", __func__, __LINE__)); 1961 if (offset & 0x0003) { 1962 bwn_shm_ctlword(mac, way, offset >> 2); 1963 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1964 (value >> 16) & 0xffff); 1965 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1966 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1967 return; 1968 } 1969 offset >>= 2; 1970 } 1971 bwn_shm_ctlword(mac, way, offset); 1972 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1973} 1974 1975static void 1976bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1977 uint16_t value) 1978{ 1979 BWN_ASSERT_LOCKED(mac->mac_sc); 1980 1981 if (way == BWN_SHARED) { 1982 KASSERT((offset & 0x0001) == 0, 1983 ("%s:%d warn", __func__, __LINE__)); 1984 if (offset & 0x0003) { 1985 bwn_shm_ctlword(mac, way, offset >> 2); 1986 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1987 return; 1988 } 1989 offset >>= 2; 1990 } 1991 bwn_shm_ctlword(mac, way, offset); 1992 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1993} 1994 1995static void 1996bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1997 int txpow) 1998{ 1999 2000 c->ic_freq = freq; 2001 c->ic_flags = flags; 2002 c->ic_ieee = ieee; 2003 c->ic_minpower = 0; 2004 c->ic_maxpower = 2 * txpow; 2005 c->ic_maxregpower = txpow; 2006} 2007 2008static void 2009bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2010 const struct bwn_channelinfo *ci, int flags) 2011{ 2012 struct ieee80211_channel *c; 2013 int i; 2014 2015 c = &chans[*nchans]; 2016 2017 for (i = 0; i < ci->nchannels; i++) { 2018 const struct bwn_channel *hc; 2019 2020 hc = &ci->channels[i]; 2021 if (*nchans >= maxchans) 2022 break; 2023 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2024 c++, (*nchans)++; 2025 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2026 /* g channel have a separate b-only entry */ 2027 if (*nchans >= maxchans) 2028 break; 2029 c[0] = c[-1]; 2030 c[-1].ic_flags = IEEE80211_CHAN_B; 2031 c++, (*nchans)++; 2032 } 2033 if (flags == IEEE80211_CHAN_HTG) { 2034 /* HT g channel have a separate g-only entry */ 2035 if (*nchans >= maxchans) 2036 break; 2037 c[-1].ic_flags = IEEE80211_CHAN_G; 2038 c[0] = c[-1]; 2039 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2040 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2041 c++, (*nchans)++; 2042 } 2043 if (flags == IEEE80211_CHAN_HTA) { 2044 /* HT a channel have a separate a-only entry */ 2045 if (*nchans >= maxchans) 2046 break; 2047 c[-1].ic_flags = IEEE80211_CHAN_A; 2048 c[0] = c[-1]; 2049 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2050 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2051 c++, (*nchans)++; 2052 } 2053 } 2054} 2055 2056static int 2057bwn_phy_g_attach(struct bwn_mac *mac) 2058{ 2059 struct bwn_softc *sc = mac->mac_sc; 2060 struct bwn_phy *phy = &mac->mac_phy; 2061 struct bwn_phy_g *pg = &phy->phy_g; 2062 unsigned int i; 2063 int16_t pab0, pab1, pab2; 2064 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2065 int8_t bg; 2066 2067 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2068 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2069 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2070 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2071 2072 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2073 device_printf(sc->sc_dev, "not supported anymore\n"); 2074 2075 pg->pg_flags = 0; 2076 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2077 pab2 == -1) { 2078 pg->pg_idletssi = 52; 2079 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2080 return (0); 2081 } 2082 2083 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2084 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2085 if (pg->pg_tssi2dbm == NULL) { 2086 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2087 return (ENOMEM); 2088 } 2089 for (i = 0; i < 64; i++) { 2090 int32_t m1, m2, f, q, delta; 2091 int8_t j = 0; 2092 2093 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2094 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2095 f = 256; 2096 2097 do { 2098 if (j > 15) { 2099 device_printf(sc->sc_dev, 2100 "failed to generate tssi2dBm\n"); 2101 free(pg->pg_tssi2dbm, M_DEVBUF); 2102 return (ENOMEM); 2103 } 2104 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2105 f, 2048); 2106 delta = abs(q - f); 2107 f = q; 2108 j++; 2109 } while (delta >= 2); 2110 2111 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2112 128); 2113 } 2114 2115 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2116 return (0); 2117} 2118 2119static void 2120bwn_phy_g_detach(struct bwn_mac *mac) 2121{ 2122 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2123 2124 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2125 free(pg->pg_tssi2dbm, M_DEVBUF); 2126 pg->pg_tssi2dbm = NULL; 2127 } 2128 pg->pg_flags = 0; 2129} 2130 2131static void 2132bwn_phy_g_init_pre(struct bwn_mac *mac) 2133{ 2134 struct bwn_phy *phy = &mac->mac_phy; 2135 struct bwn_phy_g *pg = &phy->phy_g; 2136 void *tssi2dbm; 2137 int idletssi; 2138 unsigned int i; 2139 2140 tssi2dbm = pg->pg_tssi2dbm; 2141 idletssi = pg->pg_idletssi; 2142 2143 memset(pg, 0, sizeof(*pg)); 2144 2145 pg->pg_tssi2dbm = tssi2dbm; 2146 pg->pg_idletssi = idletssi; 2147 2148 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2149 2150 for (i = 0; i < N(pg->pg_nrssi); i++) 2151 pg->pg_nrssi[i] = -1000; 2152 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2153 pg->pg_nrssi_lt[i] = i; 2154 pg->pg_lofcal = 0xffff; 2155 pg->pg_initval = 0xffff; 2156 pg->pg_immode = BWN_IMMODE_NONE; 2157 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2158 pg->pg_avgtssi = 0xff; 2159 2160 pg->pg_loctl.tx_bias = 0xff; 2161 TAILQ_INIT(&pg->pg_loctl.calib_list); 2162} 2163 2164static int 2165bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2166{ 2167 struct bwn_phy *phy = &mac->mac_phy; 2168 struct bwn_phy_g *pg = &phy->phy_g; 2169 struct bwn_softc *sc = mac->mac_sc; 2170 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2171 static const struct bwn_rfatt rfatt0[] = { 2172 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2173 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2174 { 3, 1 }, { 4, 1 } 2175 }; 2176 static const struct bwn_rfatt rfatt1[] = { 2177 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2178 { 14, 1 } 2179 }; 2180 static const struct bwn_rfatt rfatt2[] = { 2181 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2182 { 9, 1 } 2183 }; 2184 static const struct bwn_bbatt bbatt_0[] = { 2185 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2186 }; 2187 2188 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2189 2190 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2191 pg->pg_bbatt.att = 0; 2192 else 2193 pg->pg_bbatt.att = 2; 2194 2195 /* prepare Radio Attenuation */ 2196 pg->pg_rfatt.padmix = 0; 2197 2198 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2199 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2200 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2201 pg->pg_rfatt.att = 2; 2202 goto done; 2203 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2204 pg->pg_rfatt.att = 3; 2205 goto done; 2206 } 2207 } 2208 2209 if (phy->type == BWN_PHYTYPE_A) { 2210 pg->pg_rfatt.att = 0x60; 2211 goto done; 2212 } 2213 2214 switch (phy->rf_ver) { 2215 case 0x2050: 2216 switch (phy->rf_rev) { 2217 case 0: 2218 pg->pg_rfatt.att = 5; 2219 goto done; 2220 case 1: 2221 if (phy->type == BWN_PHYTYPE_G) { 2222 if (siba_get_pci_subvendor(sc->sc_dev) == 2223 SIBA_BOARDVENDOR_BCM && 2224 siba_get_pci_subdevice(sc->sc_dev) == 2225 SIBA_BOARD_BCM4309G && 2226 siba_get_pci_revid(sc->sc_dev) >= 30) 2227 pg->pg_rfatt.att = 3; 2228 else if (siba_get_pci_subvendor(sc->sc_dev) == 2229 SIBA_BOARDVENDOR_BCM && 2230 siba_get_pci_subdevice(sc->sc_dev) == 2231 SIBA_BOARD_BU4306) 2232 pg->pg_rfatt.att = 3; 2233 else 2234 pg->pg_rfatt.att = 1; 2235 } else { 2236 if (siba_get_pci_subvendor(sc->sc_dev) == 2237 SIBA_BOARDVENDOR_BCM && 2238 siba_get_pci_subdevice(sc->sc_dev) == 2239 SIBA_BOARD_BCM4309G && 2240 siba_get_pci_revid(sc->sc_dev) >= 30) 2241 pg->pg_rfatt.att = 7; 2242 else 2243 pg->pg_rfatt.att = 6; 2244 } 2245 goto done; 2246 case 2: 2247 if (phy->type == BWN_PHYTYPE_G) { 2248 if (siba_get_pci_subvendor(sc->sc_dev) == 2249 SIBA_BOARDVENDOR_BCM && 2250 siba_get_pci_subdevice(sc->sc_dev) == 2251 SIBA_BOARD_BCM4309G && 2252 siba_get_pci_revid(sc->sc_dev) >= 30) 2253 pg->pg_rfatt.att = 3; 2254 else if (siba_get_pci_subvendor(sc->sc_dev) == 2255 SIBA_BOARDVENDOR_BCM && 2256 siba_get_pci_subdevice(sc->sc_dev) == 2257 SIBA_BOARD_BU4306) 2258 pg->pg_rfatt.att = 5; 2259 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2260 pg->pg_rfatt.att = 4; 2261 else 2262 pg->pg_rfatt.att = 3; 2263 } else 2264 pg->pg_rfatt.att = 6; 2265 goto done; 2266 case 3: 2267 pg->pg_rfatt.att = 5; 2268 goto done; 2269 case 4: 2270 case 5: 2271 pg->pg_rfatt.att = 1; 2272 goto done; 2273 case 6: 2274 case 7: 2275 pg->pg_rfatt.att = 5; 2276 goto done; 2277 case 8: 2278 pg->pg_rfatt.att = 0xa; 2279 pg->pg_rfatt.padmix = 1; 2280 goto done; 2281 case 9: 2282 default: 2283 pg->pg_rfatt.att = 5; 2284 goto done; 2285 } 2286 break; 2287 case 0x2053: 2288 switch (phy->rf_rev) { 2289 case 1: 2290 pg->pg_rfatt.att = 6; 2291 goto done; 2292 } 2293 break; 2294 } 2295 pg->pg_rfatt.att = 5; 2296done: 2297 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2298 2299 if (!bwn_has_hwpctl(mac)) { 2300 lo->rfatt.array = rfatt0; 2301 lo->rfatt.len = N(rfatt0); 2302 lo->rfatt.min = 0; 2303 lo->rfatt.max = 9; 2304 goto genbbatt; 2305 } 2306 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2307 lo->rfatt.array = rfatt1; 2308 lo->rfatt.len = N(rfatt1); 2309 lo->rfatt.min = 0; 2310 lo->rfatt.max = 14; 2311 goto genbbatt; 2312 } 2313 lo->rfatt.array = rfatt2; 2314 lo->rfatt.len = N(rfatt2); 2315 lo->rfatt.min = 0; 2316 lo->rfatt.max = 9; 2317genbbatt: 2318 lo->bbatt.array = bbatt_0; 2319 lo->bbatt.len = N(bbatt_0); 2320 lo->bbatt.min = 0; 2321 lo->bbatt.max = 8; 2322 2323 BWN_READ_4(mac, BWN_MACCTL); 2324 if (phy->rev == 1) { 2325 phy->gmode = 0; 2326 bwn_reset_core(mac, 0); 2327 bwn_phy_g_init_sub(mac); 2328 phy->gmode = 1; 2329 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2330 } 2331 return (0); 2332} 2333 2334static uint16_t 2335bwn_phy_g_txctl(struct bwn_mac *mac) 2336{ 2337 struct bwn_phy *phy = &mac->mac_phy; 2338 2339 if (phy->rf_ver != 0x2050) 2340 return (0); 2341 if (phy->rf_rev == 1) 2342 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2343 if (phy->rf_rev < 6) 2344 return (BWN_TXCTL_PA2DB); 2345 if (phy->rf_rev == 8) 2346 return (BWN_TXCTL_TXMIX); 2347 return (0); 2348} 2349 2350static int 2351bwn_phy_g_init(struct bwn_mac *mac) 2352{ 2353 2354 bwn_phy_g_init_sub(mac); 2355 return (0); 2356} 2357 2358static void 2359bwn_phy_g_exit(struct bwn_mac *mac) 2360{ 2361 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2362 struct bwn_lo_calib *cal, *tmp; 2363 2364 if (lo == NULL) 2365 return; 2366 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2367 TAILQ_REMOVE(&lo->calib_list, cal, list); 2368 free(cal, M_DEVBUF); 2369 } 2370} 2371 2372static uint16_t 2373bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2374{ 2375 2376 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2377 return (BWN_READ_2(mac, BWN_PHYDATA)); 2378} 2379 2380static void 2381bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2382{ 2383 2384 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2385 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2386} 2387 2388static uint16_t 2389bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2390{ 2391 2392 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2393 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2394 return (BWN_READ_2(mac, BWN_RFDATALO)); 2395} 2396 2397static void 2398bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2399{ 2400 2401 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2402 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2403 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2404} 2405 2406static int 2407bwn_phy_g_hwpctl(struct bwn_mac *mac) 2408{ 2409 2410 return (mac->mac_phy.rev >= 6); 2411} 2412 2413static void 2414bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2415{ 2416 struct bwn_phy *phy = &mac->mac_phy; 2417 struct bwn_phy_g *pg = &phy->phy_g; 2418 unsigned int channel; 2419 uint16_t rfover, rfoverval; 2420 2421 if (on) { 2422 if (phy->rf_on) 2423 return; 2424 2425 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2426 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2427 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2428 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2429 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2430 pg->pg_radioctx_over); 2431 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2432 pg->pg_radioctx_overval); 2433 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2434 } 2435 channel = phy->chan; 2436 bwn_phy_g_switch_chan(mac, 6, 1); 2437 bwn_phy_g_switch_chan(mac, channel, 0); 2438 return; 2439 } 2440 2441 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2442 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2443 pg->pg_radioctx_over = rfover; 2444 pg->pg_radioctx_overval = rfoverval; 2445 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2446 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2447 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2448} 2449 2450static int 2451bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2452{ 2453 2454 if ((newchan < 1) || (newchan > 14)) 2455 return (EINVAL); 2456 bwn_phy_g_switch_chan(mac, newchan, 0); 2457 2458 return (0); 2459} 2460 2461static uint32_t 2462bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2463{ 2464 2465 return (1); 2466} 2467 2468static void 2469bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2470{ 2471 struct bwn_phy *phy = &mac->mac_phy; 2472 uint64_t hf; 2473 int autodiv = 0; 2474 uint16_t tmp; 2475 2476 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2477 autodiv = 1; 2478 2479 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2480 bwn_hf_write(mac, hf); 2481 2482 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2483 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2484 ((autodiv ? BWN_ANTAUTO1 : antenna) 2485 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2486 2487 if (autodiv) { 2488 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2489 if (antenna == BWN_ANTAUTO1) 2490 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2491 else 2492 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2493 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2494 } 2495 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2496 if (autodiv) 2497 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2498 else 2499 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2500 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2501 if (phy->rev >= 2) { 2502 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2503 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2504 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2505 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2506 0x15); 2507 if (phy->rev == 2) 2508 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2509 else 2510 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2511 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2512 8); 2513 } 2514 if (phy->rev >= 6) 2515 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2516 2517 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2518 bwn_hf_write(mac, hf); 2519} 2520 2521static int 2522bwn_phy_g_im(struct bwn_mac *mac, int mode) 2523{ 2524 struct bwn_phy *phy = &mac->mac_phy; 2525 struct bwn_phy_g *pg = &phy->phy_g; 2526 2527 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2528 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2529 2530 if (phy->rev == 0 || !phy->gmode) 2531 return (ENODEV); 2532 2533 pg->pg_aci_wlan_automatic = 0; 2534 return (0); 2535} 2536 2537static int 2538bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2539{ 2540 struct bwn_phy *phy = &mac->mac_phy; 2541 struct bwn_phy_g *pg = &phy->phy_g; 2542 struct bwn_softc *sc = mac->mac_sc; 2543 unsigned int tssi; 2544 int cck, ofdm; 2545 int power; 2546 int rfatt, bbatt; 2547 unsigned int max; 2548 2549 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2550 2551 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2552 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2553 if (cck < 0 && ofdm < 0) { 2554 if (ignore_tssi == 0) 2555 return (BWN_TXPWR_RES_DONE); 2556 cck = 0; 2557 ofdm = 0; 2558 } 2559 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2560 if (pg->pg_avgtssi != 0xff) 2561 tssi = (tssi + pg->pg_avgtssi) / 2; 2562 pg->pg_avgtssi = tssi; 2563 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2564 2565 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2566 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2567 max -= 3; 2568 if (max >= 120) { 2569 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2570 max = 80; 2571 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2572 } 2573 2574 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2575 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2576 tssi, 0x00), 0x3f)]); 2577 if (power == 0) 2578 return (BWN_TXPWR_RES_DONE); 2579 2580 rfatt = -((power + 7) / 8); 2581 bbatt = (-(power / 2)) - (4 * rfatt); 2582 if ((rfatt == 0) && (bbatt == 0)) 2583 return (BWN_TXPWR_RES_DONE); 2584 pg->pg_bbatt_delta = bbatt; 2585 pg->pg_rfatt_delta = rfatt; 2586 return (BWN_TXPWR_RES_NEED_ADJUST); 2587} 2588 2589static void 2590bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2591{ 2592 struct bwn_phy *phy = &mac->mac_phy; 2593 struct bwn_phy_g *pg = &phy->phy_g; 2594 struct bwn_softc *sc = mac->mac_sc; 2595 int rfatt, bbatt; 2596 uint8_t txctl; 2597 2598 bwn_mac_suspend(mac); 2599 2600 BWN_ASSERT_LOCKED(sc); 2601 2602 bbatt = pg->pg_bbatt.att; 2603 bbatt += pg->pg_bbatt_delta; 2604 rfatt = pg->pg_rfatt.att; 2605 rfatt += pg->pg_rfatt_delta; 2606 2607 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2608 txctl = pg->pg_txctl; 2609 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2610 if (rfatt <= 1) { 2611 if (txctl == 0) { 2612 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2613 rfatt += 2; 2614 bbatt += 2; 2615 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2616 BWN_BFL_PACTRL) { 2617 bbatt += 4 * (rfatt - 2); 2618 rfatt = 2; 2619 } 2620 } else if (rfatt > 4 && txctl) { 2621 txctl = 0; 2622 if (bbatt < 3) { 2623 rfatt -= 3; 2624 bbatt += 2; 2625 } else { 2626 rfatt -= 2; 2627 bbatt -= 2; 2628 } 2629 } 2630 } 2631 pg->pg_txctl = txctl; 2632 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2633 pg->pg_rfatt.att = rfatt; 2634 pg->pg_bbatt.att = bbatt; 2635 2636 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2637 2638 bwn_phy_lock(mac); 2639 bwn_rf_lock(mac); 2640 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2641 pg->pg_txctl); 2642 bwn_rf_unlock(mac); 2643 bwn_phy_unlock(mac); 2644 2645 bwn_mac_enable(mac); 2646} 2647 2648static void 2649bwn_phy_g_task_15s(struct bwn_mac *mac) 2650{ 2651 struct bwn_phy *phy = &mac->mac_phy; 2652 struct bwn_phy_g *pg = &phy->phy_g; 2653 struct bwn_softc *sc = mac->mac_sc; 2654 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2655 unsigned long expire, now; 2656 struct bwn_lo_calib *cal, *tmp; 2657 uint8_t expired = 0; 2658 2659 bwn_mac_suspend(mac); 2660 2661 if (lo == NULL) 2662 goto fail; 2663 2664 BWN_GETTIME(now); 2665 if (bwn_has_hwpctl(mac)) { 2666 expire = now - BWN_LO_PWRVEC_EXPIRE; 2667 if (time_before(lo->pwr_vec_read_time, expire)) { 2668 bwn_lo_get_powervector(mac); 2669 bwn_phy_g_dc_lookup_init(mac, 0); 2670 } 2671 goto fail; 2672 } 2673 2674 expire = now - BWN_LO_CALIB_EXPIRE; 2675 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2676 if (!time_before(cal->calib_time, expire)) 2677 continue; 2678 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2679 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2680 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2681 expired = 1; 2682 } 2683 2684 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2685 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2686 cal->ctl.i, cal->ctl.q); 2687 2688 TAILQ_REMOVE(&lo->calib_list, cal, list); 2689 free(cal, M_DEVBUF); 2690 } 2691 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2692 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2693 &pg->pg_rfatt); 2694 if (cal == NULL) { 2695 device_printf(sc->sc_dev, 2696 "failed to recalibrate LO\n"); 2697 goto fail; 2698 } 2699 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2700 bwn_lo_write(mac, &cal->ctl); 2701 } 2702 2703fail: 2704 bwn_mac_enable(mac); 2705} 2706 2707static void 2708bwn_phy_g_task_60s(struct bwn_mac *mac) 2709{ 2710 struct bwn_phy *phy = &mac->mac_phy; 2711 struct bwn_softc *sc = mac->mac_sc; 2712 uint8_t old = phy->chan; 2713 2714 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2715 return; 2716 2717 bwn_mac_suspend(mac); 2718 bwn_nrssi_slope_11g(mac); 2719 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2720 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2721 bwn_switch_channel(mac, old); 2722 } 2723 bwn_mac_enable(mac); 2724} 2725 2726static void 2727bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2728{ 2729 2730 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2731} 2732 2733static int 2734bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2735 const struct ieee80211_bpf_params *params) 2736{ 2737 struct ieee80211com *ic = ni->ni_ic; 2738 struct ifnet *ifp = ic->ic_ifp; 2739 struct bwn_softc *sc = ifp->if_softc; 2740 struct bwn_mac *mac = sc->sc_curmac; 2741 2742 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2743 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2744 ieee80211_free_node(ni); 2745 m_freem(m); 2746 return (ENETDOWN); 2747 } 2748 2749 BWN_LOCK(sc); 2750 if (bwn_tx_isfull(sc, m)) { 2751 ieee80211_free_node(ni); 2752 m_freem(m); 2753 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2754 BWN_UNLOCK(sc); 2755 return (ENOBUFS); 2756 } 2757 2758 if (bwn_tx_start(sc, ni, m) != 0) { 2759 if (ni != NULL) 2760 ieee80211_free_node(ni); 2761 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2762 } 2763 sc->sc_watchdog_timer = 5; 2764 BWN_UNLOCK(sc); 2765 return (0); 2766} 2767 2768/* 2769 * Callback from the 802.11 layer to update the slot time 2770 * based on the current setting. We use it to notify the 2771 * firmware of ERP changes and the f/w takes care of things 2772 * like slot time and preamble. 2773 */ 2774static void 2775bwn_updateslot(struct ifnet *ifp) 2776{ 2777 struct bwn_softc *sc = ifp->if_softc; 2778 struct ieee80211com *ic = ifp->if_l2com; 2779 struct bwn_mac *mac; 2780 2781 BWN_LOCK(sc); 2782 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2783 mac = (struct bwn_mac *)sc->sc_curmac; 2784 bwn_set_slot_time(mac, 2785 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2786 } 2787 BWN_UNLOCK(sc); 2788} 2789 2790/* 2791 * Callback from the 802.11 layer after a promiscuous mode change. 2792 * Note this interface does not check the operating mode as this 2793 * is an internal callback and we are expected to honor the current 2794 * state (e.g. this is used for setting the interface in promiscuous 2795 * mode when operating in hostap mode to do ACS). 2796 */ 2797static void 2798bwn_update_promisc(struct ifnet *ifp) 2799{ 2800 struct bwn_softc *sc = ifp->if_softc; 2801 struct bwn_mac *mac = sc->sc_curmac; 2802 2803 BWN_LOCK(sc); 2804 mac = sc->sc_curmac; 2805 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2806 if (ifp->if_flags & IFF_PROMISC) 2807 sc->sc_filters |= BWN_MACCTL_PROMISC; 2808 else 2809 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2810 bwn_set_opmode(mac); 2811 } 2812 BWN_UNLOCK(sc); 2813} 2814 2815/* 2816 * Callback from the 802.11 layer to update WME parameters. 2817 */ 2818static int 2819bwn_wme_update(struct ieee80211com *ic) 2820{ 2821 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2822 struct bwn_mac *mac = sc->sc_curmac; 2823 struct wmeParams *wmep; 2824 int i; 2825 2826 BWN_LOCK(sc); 2827 mac = sc->sc_curmac; 2828 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2829 bwn_mac_suspend(mac); 2830 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2831 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2832 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2833 } 2834 bwn_mac_enable(mac); 2835 } 2836 BWN_UNLOCK(sc); 2837 return (0); 2838} 2839 2840static void 2841bwn_scan_start(struct ieee80211com *ic) 2842{ 2843 struct ifnet *ifp = ic->ic_ifp; 2844 struct bwn_softc *sc = ifp->if_softc; 2845 struct bwn_mac *mac; 2846 2847 BWN_LOCK(sc); 2848 mac = sc->sc_curmac; 2849 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2850 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2851 bwn_set_opmode(mac); 2852 /* disable CFP update during scan */ 2853 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2854 } 2855 BWN_UNLOCK(sc); 2856} 2857 2858static void 2859bwn_scan_end(struct ieee80211com *ic) 2860{ 2861 struct ifnet *ifp = ic->ic_ifp; 2862 struct bwn_softc *sc = ifp->if_softc; 2863 struct bwn_mac *mac; 2864 2865 BWN_LOCK(sc); 2866 mac = sc->sc_curmac; 2867 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2868 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2869 bwn_set_opmode(mac); 2870 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2871 } 2872 BWN_UNLOCK(sc); 2873} 2874 2875static void 2876bwn_set_channel(struct ieee80211com *ic) 2877{ 2878 struct ifnet *ifp = ic->ic_ifp; 2879 struct bwn_softc *sc = ifp->if_softc; 2880 struct bwn_mac *mac = sc->sc_curmac; 2881 struct bwn_phy *phy = &mac->mac_phy; 2882 int chan, error; 2883 2884 BWN_LOCK(sc); 2885 2886 error = bwn_switch_band(sc, ic->ic_curchan); 2887 if (error) 2888 goto fail; 2889 bwn_mac_suspend(mac); 2890 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2891 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2892 if (chan != phy->chan) 2893 bwn_switch_channel(mac, chan); 2894 2895 /* TX power level */ 2896 if (ic->ic_curchan->ic_maxpower != 0 && 2897 ic->ic_curchan->ic_maxpower != phy->txpower) { 2898 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2899 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2900 BWN_TXPWR_IGNORE_TSSI); 2901 } 2902 2903 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2904 if (phy->set_antenna) 2905 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2906 2907 if (sc->sc_rf_enabled != phy->rf_on) { 2908 if (sc->sc_rf_enabled) { 2909 bwn_rf_turnon(mac); 2910 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2911 device_printf(sc->sc_dev, 2912 "please turn on the RF switch\n"); 2913 } else 2914 bwn_rf_turnoff(mac); 2915 } 2916 2917 bwn_mac_enable(mac); 2918 2919fail: 2920 /* 2921 * Setup radio tap channel freq and flags 2922 */ 2923 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2924 htole16(ic->ic_curchan->ic_freq); 2925 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2926 htole16(ic->ic_curchan->ic_flags & 0xffff); 2927 2928 BWN_UNLOCK(sc); 2929} 2930 2931static struct ieee80211vap * 2932bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2933 enum ieee80211_opmode opmode, int flags, 2934 const uint8_t bssid[IEEE80211_ADDR_LEN], 2935 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2936{ 2937 struct ifnet *ifp = ic->ic_ifp; 2938 struct bwn_softc *sc = ifp->if_softc; 2939 struct ieee80211vap *vap; 2940 struct bwn_vap *bvp; 2941 uint8_t mac[IEEE80211_ADDR_LEN]; 2942 2943 IEEE80211_ADDR_COPY(mac, mac0); 2944 switch (opmode) { 2945 case IEEE80211_M_HOSTAP: 2946 case IEEE80211_M_MBSS: 2947 case IEEE80211_M_STA: 2948 case IEEE80211_M_WDS: 2949 case IEEE80211_M_MONITOR: 2950 case IEEE80211_M_IBSS: 2951 case IEEE80211_M_AHDEMO: 2952 break; 2953 default: 2954 return (NULL); 2955 } 2956 2957 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2958 2959 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2960 M_80211_VAP, M_NOWAIT | M_ZERO); 2961 if (bvp == NULL) { 2962 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2963 return (NULL); 2964 } 2965 vap = &bvp->bv_vap; 2966 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2967 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2968 /* override with driver methods */ 2969 bvp->bv_newstate = vap->iv_newstate; 2970 vap->iv_newstate = bwn_newstate; 2971 2972 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2973 vap->iv_max_aid = BWN_STAID_MAX; 2974 2975 ieee80211_ratectl_init(vap); 2976 2977 /* complete setup */ 2978 ieee80211_vap_attach(vap, ieee80211_media_change, 2979 ieee80211_media_status); 2980 return (vap); 2981} 2982 2983static void 2984bwn_vap_delete(struct ieee80211vap *vap) 2985{ 2986 struct bwn_vap *bvp = BWN_VAP(vap); 2987 2988 ieee80211_ratectl_deinit(vap); 2989 ieee80211_vap_detach(vap); 2990 free(bvp, M_80211_VAP); 2991} 2992 2993static void 2994bwn_init(void *arg) 2995{ 2996 struct bwn_softc *sc = arg; 2997 struct ifnet *ifp = sc->sc_ifp; 2998 struct ieee80211com *ic = ifp->if_l2com; 2999 int error = 0; 3000 3001 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3002 __func__, ifp->if_flags); 3003 3004 BWN_LOCK(sc); 3005 error = bwn_init_locked(sc); 3006 BWN_UNLOCK(sc); 3007 3008 if (error == 0) 3009 ieee80211_start_all(ic); /* start all vap's */ 3010} 3011 3012static int 3013bwn_init_locked(struct bwn_softc *sc) 3014{ 3015 struct bwn_mac *mac; 3016 struct ifnet *ifp = sc->sc_ifp; 3017 int error; 3018 3019 BWN_ASSERT_LOCKED(sc); 3020 3021 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3022 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3023 sc->sc_filters = 0; 3024 bwn_wme_clear(sc); 3025 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3026 sc->sc_rf_enabled = 1; 3027 3028 mac = sc->sc_curmac; 3029 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3030 error = bwn_core_init(mac); 3031 if (error != 0) 3032 return (error); 3033 } 3034 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3035 bwn_core_start(mac); 3036 3037 bwn_set_opmode(mac); 3038 bwn_set_pretbtt(mac); 3039 bwn_spu_setdelay(mac, 0); 3040 bwn_set_macaddr(mac); 3041 3042 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3043 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3044 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3045 3046 return (0); 3047} 3048 3049static void 3050bwn_stop(struct bwn_softc *sc, int statechg) 3051{ 3052 3053 BWN_LOCK(sc); 3054 bwn_stop_locked(sc, statechg); 3055 BWN_UNLOCK(sc); 3056} 3057 3058static void 3059bwn_stop_locked(struct bwn_softc *sc, int statechg) 3060{ 3061 struct bwn_mac *mac = sc->sc_curmac; 3062 struct ifnet *ifp = sc->sc_ifp; 3063 3064 BWN_ASSERT_LOCKED(sc); 3065 3066 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3067 /* XXX FIXME opmode not based on VAP */ 3068 bwn_set_opmode(mac); 3069 bwn_set_macaddr(mac); 3070 } 3071 3072 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3073 bwn_core_stop(mac); 3074 3075 callout_stop(&sc->sc_led_blink_ch); 3076 sc->sc_led_blinking = 0; 3077 3078 bwn_core_exit(mac); 3079 sc->sc_rf_enabled = 0; 3080 3081 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3082} 3083 3084static void 3085bwn_wme_clear(struct bwn_softc *sc) 3086{ 3087#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3088 struct wmeParams *p; 3089 unsigned int i; 3090 3091 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3092 ("%s:%d: fail", __func__, __LINE__)); 3093 3094 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3095 p = &(sc->sc_wmeParams[i]); 3096 3097 switch (bwn_wme_shm_offsets[i]) { 3098 case BWN_WME_VOICE: 3099 p->wmep_txopLimit = 0; 3100 p->wmep_aifsn = 2; 3101 /* XXX FIXME: log2(cwmin) */ 3102 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3103 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3104 break; 3105 case BWN_WME_VIDEO: 3106 p->wmep_txopLimit = 0; 3107 p->wmep_aifsn = 2; 3108 /* XXX FIXME: log2(cwmin) */ 3109 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3110 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3111 break; 3112 case BWN_WME_BESTEFFORT: 3113 p->wmep_txopLimit = 0; 3114 p->wmep_aifsn = 3; 3115 /* XXX FIXME: log2(cwmin) */ 3116 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3117 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3118 break; 3119 case BWN_WME_BACKGROUND: 3120 p->wmep_txopLimit = 0; 3121 p->wmep_aifsn = 7; 3122 /* XXX FIXME: log2(cwmin) */ 3123 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3124 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3125 break; 3126 default: 3127 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3128 } 3129 } 3130} 3131 3132static int 3133bwn_core_init(struct bwn_mac *mac) 3134{ 3135 struct bwn_softc *sc = mac->mac_sc; 3136 uint64_t hf; 3137 int error; 3138 3139 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3140 ("%s:%d: fail", __func__, __LINE__)); 3141 3142 siba_powerup(sc->sc_dev, 0); 3143 if (!siba_dev_isup(sc->sc_dev)) 3144 bwn_reset_core(mac, 3145 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3146 3147 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3148 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3149 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3150 BWN_GETTIME(mac->mac_phy.nexttime); 3151 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3152 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3153 mac->mac_stats.link_noise = -95; 3154 mac->mac_reason_intr = 0; 3155 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3156 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3157#ifdef BWN_DEBUG 3158 if (sc->sc_debug & BWN_DEBUG_XMIT) 3159 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3160#endif 3161 mac->mac_suspended = 1; 3162 mac->mac_task_state = 0; 3163 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3164 3165 mac->mac_phy.init_pre(mac); 3166 3167 siba_pcicore_intr(sc->sc_dev); 3168 3169 siba_fix_imcfglobug(sc->sc_dev); 3170 bwn_bt_disable(mac); 3171 if (mac->mac_phy.prepare_hw) { 3172 error = mac->mac_phy.prepare_hw(mac); 3173 if (error) 3174 goto fail0; 3175 } 3176 error = bwn_chip_init(mac); 3177 if (error) 3178 goto fail0; 3179 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3180 siba_get_revid(sc->sc_dev)); 3181 hf = bwn_hf_read(mac); 3182 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3183 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3184 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3185 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3186 if (mac->mac_phy.rev == 1) 3187 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3188 } 3189 if (mac->mac_phy.rf_ver == 0x2050) { 3190 if (mac->mac_phy.rf_rev < 6) 3191 hf |= BWN_HF_FORCE_VCO_RECALC; 3192 if (mac->mac_phy.rf_rev == 6) 3193 hf |= BWN_HF_4318_TSSI; 3194 } 3195 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3196 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3197 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3198 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3199 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3200 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3201 bwn_hf_write(mac, hf); 3202 3203 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3205 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3206 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3207 3208 bwn_rate_init(mac); 3209 bwn_set_phytxctl(mac); 3210 3211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3212 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3213 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3214 3215 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3216 bwn_pio_init(mac); 3217 else 3218 bwn_dma_init(mac); 3219 bwn_wme_init(mac); 3220 bwn_spu_setdelay(mac, 1); 3221 bwn_bt_enable(mac); 3222 3223 siba_powerup(sc->sc_dev, 3224 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3225 bwn_set_macaddr(mac); 3226 bwn_crypt_init(mac); 3227 3228 /* XXX LED initializatin */ 3229 3230 mac->mac_status = BWN_MAC_STATUS_INITED; 3231 3232 return (error); 3233 3234fail0: 3235 siba_powerdown(sc->sc_dev); 3236 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3237 ("%s:%d: fail", __func__, __LINE__)); 3238 return (error); 3239} 3240 3241static void 3242bwn_core_start(struct bwn_mac *mac) 3243{ 3244 struct bwn_softc *sc = mac->mac_sc; 3245 uint32_t tmp; 3246 3247 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3248 ("%s:%d: fail", __func__, __LINE__)); 3249 3250 if (siba_get_revid(sc->sc_dev) < 5) 3251 return; 3252 3253 while (1) { 3254 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3255 if (!(tmp & 0x00000001)) 3256 break; 3257 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3258 } 3259 3260 bwn_mac_enable(mac); 3261 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3262 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3263 3264 mac->mac_status = BWN_MAC_STATUS_STARTED; 3265} 3266 3267static void 3268bwn_core_exit(struct bwn_mac *mac) 3269{ 3270 struct bwn_softc *sc = mac->mac_sc; 3271 uint32_t macctl; 3272 3273 BWN_ASSERT_LOCKED(mac->mac_sc); 3274 3275 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3276 ("%s:%d: fail", __func__, __LINE__)); 3277 3278 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3279 return; 3280 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3281 3282 macctl = BWN_READ_4(mac, BWN_MACCTL); 3283 macctl &= ~BWN_MACCTL_MCODE_RUN; 3284 macctl |= BWN_MACCTL_MCODE_JMP0; 3285 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3286 3287 bwn_dma_stop(mac); 3288 bwn_pio_stop(mac); 3289 bwn_chip_exit(mac); 3290 mac->mac_phy.switch_analog(mac, 0); 3291 siba_dev_down(sc->sc_dev, 0); 3292 siba_powerdown(sc->sc_dev); 3293} 3294 3295static void 3296bwn_bt_disable(struct bwn_mac *mac) 3297{ 3298 struct bwn_softc *sc = mac->mac_sc; 3299 3300 (void)sc; 3301 /* XXX do nothing yet */ 3302} 3303 3304static int 3305bwn_chip_init(struct bwn_mac *mac) 3306{ 3307 struct bwn_softc *sc = mac->mac_sc; 3308 struct bwn_phy *phy = &mac->mac_phy; 3309 uint32_t macctl; 3310 int error; 3311 3312 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3313 if (phy->gmode) 3314 macctl |= BWN_MACCTL_GMODE; 3315 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3316 3317 error = bwn_fw_fillinfo(mac); 3318 if (error) 3319 return (error); 3320 error = bwn_fw_loaducode(mac); 3321 if (error) 3322 return (error); 3323 3324 error = bwn_gpio_init(mac); 3325 if (error) 3326 return (error); 3327 3328 error = bwn_fw_loadinitvals(mac); 3329 if (error) { 3330 siba_gpio_set(sc->sc_dev, 0); 3331 return (error); 3332 } 3333 phy->switch_analog(mac, 1); 3334 error = bwn_phy_init(mac); 3335 if (error) { 3336 siba_gpio_set(sc->sc_dev, 0); 3337 return (error); 3338 } 3339 if (phy->set_im) 3340 phy->set_im(mac, BWN_IMMODE_NONE); 3341 if (phy->set_antenna) 3342 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3343 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3344 3345 if (phy->type == BWN_PHYTYPE_B) 3346 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3347 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3348 if (siba_get_revid(sc->sc_dev) < 5) 3349 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3350 3351 BWN_WRITE_4(mac, BWN_MACCTL, 3352 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3353 BWN_WRITE_4(mac, BWN_MACCTL, 3354 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3355 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3356 3357 bwn_set_opmode(mac); 3358 if (siba_get_revid(sc->sc_dev) < 3) { 3359 BWN_WRITE_2(mac, 0x060e, 0x0000); 3360 BWN_WRITE_2(mac, 0x0610, 0x8000); 3361 BWN_WRITE_2(mac, 0x0604, 0x0000); 3362 BWN_WRITE_2(mac, 0x0606, 0x0200); 3363 } else { 3364 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3365 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3366 } 3367 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3368 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3369 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3370 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3371 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3372 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3373 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3374 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3375 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3376 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3377 return (error); 3378} 3379 3380/* read hostflags */ 3381static uint64_t 3382bwn_hf_read(struct bwn_mac *mac) 3383{ 3384 uint64_t ret; 3385 3386 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3387 ret <<= 16; 3388 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3389 ret <<= 16; 3390 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3391 return (ret); 3392} 3393 3394static void 3395bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3396{ 3397 3398 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3399 (value & 0x00000000ffffull)); 3400 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3401 (value & 0x0000ffff0000ull) >> 16); 3402 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3403 (value & 0xffff00000000ULL) >> 32); 3404} 3405 3406static void 3407bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3408{ 3409 3410 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3411 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3412} 3413 3414static void 3415bwn_rate_init(struct bwn_mac *mac) 3416{ 3417 3418 switch (mac->mac_phy.type) { 3419 case BWN_PHYTYPE_A: 3420 case BWN_PHYTYPE_G: 3421 case BWN_PHYTYPE_LP: 3422 case BWN_PHYTYPE_N: 3423 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3424 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3425 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3427 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3428 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3429 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3430 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3431 break; 3432 /* FALLTHROUGH */ 3433 case BWN_PHYTYPE_B: 3434 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3435 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3436 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3437 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3438 break; 3439 default: 3440 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3441 } 3442} 3443 3444static void 3445bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3446{ 3447 uint16_t offset; 3448 3449 if (ofdm) { 3450 offset = 0x480; 3451 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3452 } else { 3453 offset = 0x4c0; 3454 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3455 } 3456 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3457 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3458} 3459 3460static uint8_t 3461bwn_plcp_getcck(const uint8_t bitrate) 3462{ 3463 3464 switch (bitrate) { 3465 case BWN_CCK_RATE_1MB: 3466 return (0x0a); 3467 case BWN_CCK_RATE_2MB: 3468 return (0x14); 3469 case BWN_CCK_RATE_5MB: 3470 return (0x37); 3471 case BWN_CCK_RATE_11MB: 3472 return (0x6e); 3473 } 3474 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3475 return (0); 3476} 3477 3478static uint8_t 3479bwn_plcp_getofdm(const uint8_t bitrate) 3480{ 3481 3482 switch (bitrate) { 3483 case BWN_OFDM_RATE_6MB: 3484 return (0xb); 3485 case BWN_OFDM_RATE_9MB: 3486 return (0xf); 3487 case BWN_OFDM_RATE_12MB: 3488 return (0xa); 3489 case BWN_OFDM_RATE_18MB: 3490 return (0xe); 3491 case BWN_OFDM_RATE_24MB: 3492 return (0x9); 3493 case BWN_OFDM_RATE_36MB: 3494 return (0xd); 3495 case BWN_OFDM_RATE_48MB: 3496 return (0x8); 3497 case BWN_OFDM_RATE_54MB: 3498 return (0xc); 3499 } 3500 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3501 return (0); 3502} 3503 3504static void 3505bwn_set_phytxctl(struct bwn_mac *mac) 3506{ 3507 uint16_t ctl; 3508 3509 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3510 BWN_TX_PHY_TXPWR); 3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3513 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3514} 3515 3516static void 3517bwn_pio_init(struct bwn_mac *mac) 3518{ 3519 struct bwn_pio *pio = &mac->mac_method.pio; 3520 3521 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3522 & ~BWN_MACCTL_BIGENDIAN); 3523 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3524 3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3528 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3529 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3530 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3531} 3532 3533static void 3534bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3535 int index) 3536{ 3537 struct bwn_pio_txpkt *tp; 3538 struct bwn_softc *sc = mac->mac_sc; 3539 unsigned int i; 3540 3541 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3542 tq->tq_index = index; 3543 3544 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3545 if (siba_get_revid(sc->sc_dev) >= 8) 3546 tq->tq_size = 1920; 3547 else { 3548 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3549 tq->tq_size -= 80; 3550 } 3551 3552 TAILQ_INIT(&tq->tq_pktlist); 3553 for (i = 0; i < N(tq->tq_pkts); i++) { 3554 tp = &(tq->tq_pkts[i]); 3555 tp->tp_index = i; 3556 tp->tp_queue = tq; 3557 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3558 } 3559} 3560 3561static uint16_t 3562bwn_pio_idx2base(struct bwn_mac *mac, int index) 3563{ 3564 struct bwn_softc *sc = mac->mac_sc; 3565 static const uint16_t bases[] = { 3566 BWN_PIO_BASE0, 3567 BWN_PIO_BASE1, 3568 BWN_PIO_BASE2, 3569 BWN_PIO_BASE3, 3570 BWN_PIO_BASE4, 3571 BWN_PIO_BASE5, 3572 BWN_PIO_BASE6, 3573 BWN_PIO_BASE7, 3574 }; 3575 static const uint16_t bases_rev11[] = { 3576 BWN_PIO11_BASE0, 3577 BWN_PIO11_BASE1, 3578 BWN_PIO11_BASE2, 3579 BWN_PIO11_BASE3, 3580 BWN_PIO11_BASE4, 3581 BWN_PIO11_BASE5, 3582 }; 3583 3584 if (siba_get_revid(sc->sc_dev) >= 11) { 3585 if (index >= N(bases_rev11)) 3586 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3587 return (bases_rev11[index]); 3588 } 3589 if (index >= N(bases)) 3590 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3591 return (bases[index]); 3592} 3593 3594static void 3595bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3596 int index) 3597{ 3598 struct bwn_softc *sc = mac->mac_sc; 3599 3600 prq->prq_mac = mac; 3601 prq->prq_rev = siba_get_revid(sc->sc_dev); 3602 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3603 bwn_dma_rxdirectfifo(mac, index, 1); 3604} 3605 3606static void 3607bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3608{ 3609 if (tq == NULL) 3610 return; 3611 bwn_pio_cancel_tx_packets(tq); 3612} 3613 3614static void 3615bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3616{ 3617 3618 bwn_destroy_pioqueue_tx(pio); 3619} 3620 3621static uint16_t 3622bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3623 uint16_t offset) 3624{ 3625 3626 return (BWN_READ_2(mac, tq->tq_base + offset)); 3627} 3628 3629static void 3630bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3631{ 3632 uint32_t ctl; 3633 int type; 3634 uint16_t base; 3635 3636 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3637 base = bwn_dma_base(type, idx); 3638 if (type == BWN_DMA_64BIT) { 3639 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3640 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3641 if (enable) 3642 ctl |= BWN_DMA64_RXDIRECTFIFO; 3643 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3644 } else { 3645 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3646 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3647 if (enable) 3648 ctl |= BWN_DMA32_RXDIRECTFIFO; 3649 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3650 } 3651} 3652 3653static uint64_t 3654bwn_dma_mask(struct bwn_mac *mac) 3655{ 3656 uint32_t tmp; 3657 uint16_t base; 3658 3659 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3660 if (tmp & SIBA_TGSHIGH_DMA64) 3661 return (BWN_DMA_BIT_MASK(64)); 3662 base = bwn_dma_base(0, 0); 3663 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3664 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3665 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3666 return (BWN_DMA_BIT_MASK(32)); 3667 3668 return (BWN_DMA_BIT_MASK(30)); 3669} 3670 3671static int 3672bwn_dma_mask2type(uint64_t dmamask) 3673{ 3674 3675 if (dmamask == BWN_DMA_BIT_MASK(30)) 3676 return (BWN_DMA_30BIT); 3677 if (dmamask == BWN_DMA_BIT_MASK(32)) 3678 return (BWN_DMA_32BIT); 3679 if (dmamask == BWN_DMA_BIT_MASK(64)) 3680 return (BWN_DMA_64BIT); 3681 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3682 return (BWN_DMA_30BIT); 3683} 3684 3685static void 3686bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3687{ 3688 struct bwn_pio_txpkt *tp; 3689 unsigned int i; 3690 3691 for (i = 0; i < N(tq->tq_pkts); i++) { 3692 tp = &(tq->tq_pkts[i]); 3693 if (tp->tp_m) { 3694 m_freem(tp->tp_m); 3695 tp->tp_m = NULL; 3696 } 3697 } 3698} 3699 3700static uint16_t 3701bwn_dma_base(int type, int controller_idx) 3702{ 3703 static const uint16_t map64[] = { 3704 BWN_DMA64_BASE0, 3705 BWN_DMA64_BASE1, 3706 BWN_DMA64_BASE2, 3707 BWN_DMA64_BASE3, 3708 BWN_DMA64_BASE4, 3709 BWN_DMA64_BASE5, 3710 }; 3711 static const uint16_t map32[] = { 3712 BWN_DMA32_BASE0, 3713 BWN_DMA32_BASE1, 3714 BWN_DMA32_BASE2, 3715 BWN_DMA32_BASE3, 3716 BWN_DMA32_BASE4, 3717 BWN_DMA32_BASE5, 3718 }; 3719 3720 if (type == BWN_DMA_64BIT) { 3721 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3722 ("%s:%d: fail", __func__, __LINE__)); 3723 return (map64[controller_idx]); 3724 } 3725 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3726 ("%s:%d: fail", __func__, __LINE__)); 3727 return (map32[controller_idx]); 3728} 3729 3730static void 3731bwn_dma_init(struct bwn_mac *mac) 3732{ 3733 struct bwn_dma *dma = &mac->mac_method.dma; 3734 3735 /* setup TX DMA channels. */ 3736 bwn_dma_setup(dma->wme[WME_AC_BK]); 3737 bwn_dma_setup(dma->wme[WME_AC_BE]); 3738 bwn_dma_setup(dma->wme[WME_AC_VI]); 3739 bwn_dma_setup(dma->wme[WME_AC_VO]); 3740 bwn_dma_setup(dma->mcast); 3741 /* setup RX DMA channel. */ 3742 bwn_dma_setup(dma->rx); 3743} 3744 3745static struct bwn_dma_ring * 3746bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3747 int for_tx, int type) 3748{ 3749 struct bwn_dma *dma = &mac->mac_method.dma; 3750 struct bwn_dma_ring *dr; 3751 struct bwn_dmadesc_generic *desc; 3752 struct bwn_dmadesc_meta *mt; 3753 struct bwn_softc *sc = mac->mac_sc; 3754 int error, i; 3755 3756 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3757 if (dr == NULL) 3758 goto out; 3759 dr->dr_numslots = BWN_RXRING_SLOTS; 3760 if (for_tx) 3761 dr->dr_numslots = BWN_TXRING_SLOTS; 3762 3763 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3764 M_DEVBUF, M_NOWAIT | M_ZERO); 3765 if (dr->dr_meta == NULL) 3766 goto fail0; 3767 3768 dr->dr_type = type; 3769 dr->dr_mac = mac; 3770 dr->dr_base = bwn_dma_base(type, controller_index); 3771 dr->dr_index = controller_index; 3772 if (type == BWN_DMA_64BIT) { 3773 dr->getdesc = bwn_dma_64_getdesc; 3774 dr->setdesc = bwn_dma_64_setdesc; 3775 dr->start_transfer = bwn_dma_64_start_transfer; 3776 dr->suspend = bwn_dma_64_suspend; 3777 dr->resume = bwn_dma_64_resume; 3778 dr->get_curslot = bwn_dma_64_get_curslot; 3779 dr->set_curslot = bwn_dma_64_set_curslot; 3780 } else { 3781 dr->getdesc = bwn_dma_32_getdesc; 3782 dr->setdesc = bwn_dma_32_setdesc; 3783 dr->start_transfer = bwn_dma_32_start_transfer; 3784 dr->suspend = bwn_dma_32_suspend; 3785 dr->resume = bwn_dma_32_resume; 3786 dr->get_curslot = bwn_dma_32_get_curslot; 3787 dr->set_curslot = bwn_dma_32_set_curslot; 3788 } 3789 if (for_tx) { 3790 dr->dr_tx = 1; 3791 dr->dr_curslot = -1; 3792 } else { 3793 if (dr->dr_index == 0) { 3794 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3795 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3796 } else 3797 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3798 } 3799 3800 error = bwn_dma_allocringmemory(dr); 3801 if (error) 3802 goto fail2; 3803 3804 if (for_tx) { 3805 /* 3806 * Assumption: BWN_TXRING_SLOTS can be divided by 3807 * BWN_TX_SLOTS_PER_FRAME 3808 */ 3809 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3810 ("%s:%d: fail", __func__, __LINE__)); 3811 3812 dr->dr_txhdr_cache = 3813 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3814 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3815 KASSERT(dr->dr_txhdr_cache != NULL, 3816 ("%s:%d: fail", __func__, __LINE__)); 3817 3818 /* 3819 * Create TX ring DMA stuffs 3820 */ 3821 error = bus_dma_tag_create(dma->parent_dtag, 3822 BWN_ALIGN, 0, 3823 BUS_SPACE_MAXADDR, 3824 BUS_SPACE_MAXADDR, 3825 NULL, NULL, 3826 BWN_HDRSIZE(mac), 3827 1, 3828 BUS_SPACE_MAXSIZE_32BIT, 3829 0, 3830 NULL, NULL, 3831 &dr->dr_txring_dtag); 3832 if (error) { 3833 device_printf(sc->sc_dev, 3834 "can't create TX ring DMA tag: TODO frees\n"); 3835 goto fail1; 3836 } 3837 3838 for (i = 0; i < dr->dr_numslots; i += 2) { 3839 dr->getdesc(dr, i, &desc, &mt); 3840 3841 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3842 mt->mt_m = NULL; 3843 mt->mt_ni = NULL; 3844 mt->mt_islast = 0; 3845 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3846 &mt->mt_dmap); 3847 if (error) { 3848 device_printf(sc->sc_dev, 3849 "can't create RX buf DMA map\n"); 3850 goto fail1; 3851 } 3852 3853 dr->getdesc(dr, i + 1, &desc, &mt); 3854 3855 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3856 mt->mt_m = NULL; 3857 mt->mt_ni = NULL; 3858 mt->mt_islast = 1; 3859 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3860 &mt->mt_dmap); 3861 if (error) { 3862 device_printf(sc->sc_dev, 3863 "can't create RX buf DMA map\n"); 3864 goto fail1; 3865 } 3866 } 3867 } else { 3868 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3869 &dr->dr_spare_dmap); 3870 if (error) { 3871 device_printf(sc->sc_dev, 3872 "can't create RX buf DMA map\n"); 3873 goto out; /* XXX wrong! */ 3874 } 3875 3876 for (i = 0; i < dr->dr_numslots; i++) { 3877 dr->getdesc(dr, i, &desc, &mt); 3878 3879 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3880 &mt->mt_dmap); 3881 if (error) { 3882 device_printf(sc->sc_dev, 3883 "can't create RX buf DMA map\n"); 3884 goto out; /* XXX wrong! */ 3885 } 3886 error = bwn_dma_newbuf(dr, desc, mt, 1); 3887 if (error) { 3888 device_printf(sc->sc_dev, 3889 "failed to allocate RX buf\n"); 3890 goto out; /* XXX wrong! */ 3891 } 3892 } 3893 3894 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3895 BUS_DMASYNC_PREWRITE); 3896 3897 dr->dr_usedslot = dr->dr_numslots; 3898 } 3899 3900 out: 3901 return (dr); 3902 3903fail2: 3904 free(dr->dr_txhdr_cache, M_DEVBUF); 3905fail1: 3906 free(dr->dr_meta, M_DEVBUF); 3907fail0: 3908 free(dr, M_DEVBUF); 3909 return (NULL); 3910} 3911 3912static void 3913bwn_dma_ringfree(struct bwn_dma_ring **dr) 3914{ 3915 3916 if (dr == NULL) 3917 return; 3918 3919 bwn_dma_free_descbufs(*dr); 3920 bwn_dma_free_ringmemory(*dr); 3921 3922 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3923 free((*dr)->dr_meta, M_DEVBUF); 3924 free(*dr, M_DEVBUF); 3925 3926 *dr = NULL; 3927} 3928 3929static void 3930bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3931 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3932{ 3933 struct bwn_dmadesc32 *desc; 3934 3935 *meta = &(dr->dr_meta[slot]); 3936 desc = dr->dr_ring_descbase; 3937 desc = &(desc[slot]); 3938 3939 *gdesc = (struct bwn_dmadesc_generic *)desc; 3940} 3941 3942static void 3943bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3944 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3945 int start, int end, int irq) 3946{ 3947 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3948 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3949 uint32_t addr, addrext, ctl; 3950 int slot; 3951 3952 slot = (int)(&(desc->dma.dma32) - descbase); 3953 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3954 ("%s:%d: fail", __func__, __LINE__)); 3955 3956 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3957 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3958 addr |= siba_dma_translation(sc->sc_dev); 3959 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3960 if (slot == dr->dr_numslots - 1) 3961 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3962 if (start) 3963 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3964 if (end) 3965 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3966 if (irq) 3967 ctl |= BWN_DMA32_DCTL_IRQ; 3968 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3969 & BWN_DMA32_DCTL_ADDREXT_MASK; 3970 3971 desc->dma.dma32.control = htole32(ctl); 3972 desc->dma.dma32.address = htole32(addr); 3973} 3974 3975static void 3976bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3977{ 3978 3979 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3980 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3981} 3982 3983static void 3984bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3985{ 3986 3987 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3988 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3989} 3990 3991static void 3992bwn_dma_32_resume(struct bwn_dma_ring *dr) 3993{ 3994 3995 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3996 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3997} 3998 3999static int 4000bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4001{ 4002 uint32_t val; 4003 4004 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4005 val &= BWN_DMA32_RXDPTR; 4006 4007 return (val / sizeof(struct bwn_dmadesc32)); 4008} 4009 4010static void 4011bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4012{ 4013 4014 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4015 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4016} 4017 4018static void 4019bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4020 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4021{ 4022 struct bwn_dmadesc64 *desc; 4023 4024 *meta = &(dr->dr_meta[slot]); 4025 desc = dr->dr_ring_descbase; 4026 desc = &(desc[slot]); 4027 4028 *gdesc = (struct bwn_dmadesc_generic *)desc; 4029} 4030 4031static void 4032bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4033 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4034 int start, int end, int irq) 4035{ 4036 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4037 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4038 int slot; 4039 uint32_t ctl0 = 0, ctl1 = 0; 4040 uint32_t addrlo, addrhi; 4041 uint32_t addrext; 4042 4043 slot = (int)(&(desc->dma.dma64) - descbase); 4044 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4045 ("%s:%d: fail", __func__, __LINE__)); 4046 4047 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4048 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4049 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4050 30; 4051 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4052 if (slot == dr->dr_numslots - 1) 4053 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4054 if (start) 4055 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4056 if (end) 4057 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4058 if (irq) 4059 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4060 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4061 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4062 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4063 4064 desc->dma.dma64.control0 = htole32(ctl0); 4065 desc->dma.dma64.control1 = htole32(ctl1); 4066 desc->dma.dma64.address_low = htole32(addrlo); 4067 desc->dma.dma64.address_high = htole32(addrhi); 4068} 4069 4070static void 4071bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4072{ 4073 4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4075 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4076} 4077 4078static void 4079bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4080{ 4081 4082 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4083 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4084} 4085 4086static void 4087bwn_dma_64_resume(struct bwn_dma_ring *dr) 4088{ 4089 4090 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4091 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4092} 4093 4094static int 4095bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4096{ 4097 uint32_t val; 4098 4099 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4100 val &= BWN_DMA64_RXSTATDPTR; 4101 4102 return (val / sizeof(struct bwn_dmadesc64)); 4103} 4104 4105static void 4106bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4107{ 4108 4109 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4110 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4111} 4112 4113static int 4114bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4115{ 4116 struct bwn_mac *mac = dr->dr_mac; 4117 struct bwn_dma *dma = &mac->mac_method.dma; 4118 struct bwn_softc *sc = mac->mac_sc; 4119 int error; 4120 4121 error = bus_dma_tag_create(dma->parent_dtag, 4122 BWN_ALIGN, 0, 4123 BUS_SPACE_MAXADDR, 4124 BUS_SPACE_MAXADDR, 4125 NULL, NULL, 4126 BWN_DMA_RINGMEMSIZE, 4127 1, 4128 BUS_SPACE_MAXSIZE_32BIT, 4129 0, 4130 NULL, NULL, 4131 &dr->dr_ring_dtag); 4132 if (error) { 4133 device_printf(sc->sc_dev, 4134 "can't create TX ring DMA tag: TODO frees\n"); 4135 return (-1); 4136 } 4137 4138 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4139 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4140 &dr->dr_ring_dmap); 4141 if (error) { 4142 device_printf(sc->sc_dev, 4143 "can't allocate DMA mem: TODO frees\n"); 4144 return (-1); 4145 } 4146 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4147 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4148 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4149 if (error) { 4150 device_printf(sc->sc_dev, 4151 "can't load DMA mem: TODO free\n"); 4152 return (-1); 4153 } 4154 4155 return (0); 4156} 4157 4158static void 4159bwn_dma_setup(struct bwn_dma_ring *dr) 4160{ 4161 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4162 uint64_t ring64; 4163 uint32_t addrext, ring32, value; 4164 uint32_t trans = siba_dma_translation(sc->sc_dev); 4165 4166 if (dr->dr_tx) { 4167 dr->dr_curslot = -1; 4168 4169 if (dr->dr_type == BWN_DMA_64BIT) { 4170 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4171 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4172 >> 30; 4173 value = BWN_DMA64_TXENABLE; 4174 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4175 & BWN_DMA64_TXADDREXT_MASK; 4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4177 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4178 (ring64 & 0xffffffff)); 4179 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4180 ((ring64 >> 32) & 4181 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4182 } else { 4183 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4184 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4185 value = BWN_DMA32_TXENABLE; 4186 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4187 & BWN_DMA32_TXADDREXT_MASK; 4188 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4189 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4190 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4191 } 4192 return; 4193 } 4194 4195 /* 4196 * set for RX 4197 */ 4198 dr->dr_usedslot = dr->dr_numslots; 4199 4200 if (dr->dr_type == BWN_DMA_64BIT) { 4201 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4202 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4203 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4204 value |= BWN_DMA64_RXENABLE; 4205 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4206 & BWN_DMA64_RXADDREXT_MASK; 4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4210 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4211 | (trans << 1)); 4212 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4213 sizeof(struct bwn_dmadesc64)); 4214 } else { 4215 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4216 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4217 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4218 value |= BWN_DMA32_RXENABLE; 4219 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4220 & BWN_DMA32_RXADDREXT_MASK; 4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4222 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4223 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4224 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4225 sizeof(struct bwn_dmadesc32)); 4226 } 4227} 4228 4229static void 4230bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4231{ 4232 4233 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4234 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4235 dr->dr_ring_dmap); 4236} 4237 4238static void 4239bwn_dma_cleanup(struct bwn_dma_ring *dr) 4240{ 4241 4242 if (dr->dr_tx) { 4243 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4244 if (dr->dr_type == BWN_DMA_64BIT) { 4245 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4246 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4247 } else 4248 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4249 } else { 4250 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4251 if (dr->dr_type == BWN_DMA_64BIT) { 4252 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4253 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4254 } else 4255 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4256 } 4257} 4258 4259static void 4260bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4261{ 4262 struct bwn_dmadesc_generic *desc; 4263 struct bwn_dmadesc_meta *meta; 4264 struct bwn_mac *mac = dr->dr_mac; 4265 struct bwn_dma *dma = &mac->mac_method.dma; 4266 struct bwn_softc *sc = mac->mac_sc; 4267 int i; 4268 4269 if (!dr->dr_usedslot) 4270 return; 4271 for (i = 0; i < dr->dr_numslots; i++) { 4272 dr->getdesc(dr, i, &desc, &meta); 4273 4274 if (meta->mt_m == NULL) { 4275 if (!dr->dr_tx) 4276 device_printf(sc->sc_dev, "%s: not TX?\n", 4277 __func__); 4278 continue; 4279 } 4280 if (dr->dr_tx) { 4281 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4282 bus_dmamap_unload(dr->dr_txring_dtag, 4283 meta->mt_dmap); 4284 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4285 bus_dmamap_unload(dma->txbuf_dtag, 4286 meta->mt_dmap); 4287 } else 4288 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4289 bwn_dma_free_descbuf(dr, meta); 4290 } 4291} 4292 4293static int 4294bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4295 int type) 4296{ 4297 struct bwn_softc *sc = mac->mac_sc; 4298 uint32_t value; 4299 int i; 4300 uint16_t offset; 4301 4302 for (i = 0; i < 10; i++) { 4303 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4304 BWN_DMA32_TXSTATUS; 4305 value = BWN_READ_4(mac, base + offset); 4306 if (type == BWN_DMA_64BIT) { 4307 value &= BWN_DMA64_TXSTAT; 4308 if (value == BWN_DMA64_TXSTAT_DISABLED || 4309 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4310 value == BWN_DMA64_TXSTAT_STOPPED) 4311 break; 4312 } else { 4313 value &= BWN_DMA32_TXSTATE; 4314 if (value == BWN_DMA32_TXSTAT_DISABLED || 4315 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4316 value == BWN_DMA32_TXSTAT_STOPPED) 4317 break; 4318 } 4319 DELAY(1000); 4320 } 4321 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4322 BWN_WRITE_4(mac, base + offset, 0); 4323 for (i = 0; i < 10; i++) { 4324 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4325 BWN_DMA32_TXSTATUS; 4326 value = BWN_READ_4(mac, base + offset); 4327 if (type == BWN_DMA_64BIT) { 4328 value &= BWN_DMA64_TXSTAT; 4329 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4330 i = -1; 4331 break; 4332 } 4333 } else { 4334 value &= BWN_DMA32_TXSTATE; 4335 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4336 i = -1; 4337 break; 4338 } 4339 } 4340 DELAY(1000); 4341 } 4342 if (i != -1) { 4343 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4344 return (ENODEV); 4345 } 4346 DELAY(1000); 4347 4348 return (0); 4349} 4350 4351static int 4352bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4353 int type) 4354{ 4355 struct bwn_softc *sc = mac->mac_sc; 4356 uint32_t value; 4357 int i; 4358 uint16_t offset; 4359 4360 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4361 BWN_WRITE_4(mac, base + offset, 0); 4362 for (i = 0; i < 10; i++) { 4363 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4364 BWN_DMA32_RXSTATUS; 4365 value = BWN_READ_4(mac, base + offset); 4366 if (type == BWN_DMA_64BIT) { 4367 value &= BWN_DMA64_RXSTAT; 4368 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4369 i = -1; 4370 break; 4371 } 4372 } else { 4373 value &= BWN_DMA32_RXSTATE; 4374 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4375 i = -1; 4376 break; 4377 } 4378 } 4379 DELAY(1000); 4380 } 4381 if (i != -1) { 4382 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4383 return (ENODEV); 4384 } 4385 4386 return (0); 4387} 4388 4389static void 4390bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4391 struct bwn_dmadesc_meta *meta) 4392{ 4393 4394 if (meta->mt_m != NULL) { 4395 m_freem(meta->mt_m); 4396 meta->mt_m = NULL; 4397 } 4398 if (meta->mt_ni != NULL) { 4399 ieee80211_free_node(meta->mt_ni); 4400 meta->mt_ni = NULL; 4401 } 4402} 4403 4404static void 4405bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4406{ 4407 struct bwn_rxhdr4 *rxhdr; 4408 unsigned char *frame; 4409 4410 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4411 rxhdr->frame_len = 0; 4412 4413 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4414 sizeof(struct bwn_plcp6) + 2, 4415 ("%s:%d: fail", __func__, __LINE__)); 4416 frame = mtod(m, char *) + dr->dr_frameoffset; 4417 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4418} 4419 4420static uint8_t 4421bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4422{ 4423 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4424 4425 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4426 == 0xff); 4427} 4428 4429static void 4430bwn_wme_init(struct bwn_mac *mac) 4431{ 4432 4433 bwn_wme_load(mac); 4434 4435 /* enable WME support. */ 4436 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4437 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4438 BWN_IFSCTL_USE_EDCF); 4439} 4440 4441static void 4442bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4443{ 4444 struct bwn_softc *sc = mac->mac_sc; 4445 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4446 uint16_t delay; /* microsec */ 4447 4448 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4449 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4450 delay = 500; 4451 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4452 delay = max(delay, (uint16_t)2400); 4453 4454 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4455} 4456 4457static void 4458bwn_bt_enable(struct bwn_mac *mac) 4459{ 4460 struct bwn_softc *sc = mac->mac_sc; 4461 uint64_t hf; 4462 4463 if (bwn_bluetooth == 0) 4464 return; 4465 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4466 return; 4467 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4468 return; 4469 4470 hf = bwn_hf_read(mac); 4471 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4472 hf |= BWN_HF_BT_COEXISTALT; 4473 else 4474 hf |= BWN_HF_BT_COEXIST; 4475 bwn_hf_write(mac, hf); 4476} 4477 4478static void 4479bwn_set_macaddr(struct bwn_mac *mac) 4480{ 4481 4482 bwn_mac_write_bssid(mac); 4483 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4484} 4485 4486static void 4487bwn_clear_keys(struct bwn_mac *mac) 4488{ 4489 int i; 4490 4491 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4492 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4493 ("%s:%d: fail", __func__, __LINE__)); 4494 4495 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4496 NULL, BWN_SEC_KEYSIZE, NULL); 4497 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4498 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4499 NULL, BWN_SEC_KEYSIZE, NULL); 4500 } 4501 mac->mac_key[i].keyconf = NULL; 4502 } 4503} 4504 4505static void 4506bwn_crypt_init(struct bwn_mac *mac) 4507{ 4508 struct bwn_softc *sc = mac->mac_sc; 4509 4510 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4511 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4512 ("%s:%d: fail", __func__, __LINE__)); 4513 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4514 mac->mac_ktp *= 2; 4515 if (siba_get_revid(sc->sc_dev) >= 5) 4516 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4517 bwn_clear_keys(mac); 4518} 4519 4520static void 4521bwn_chip_exit(struct bwn_mac *mac) 4522{ 4523 struct bwn_softc *sc = mac->mac_sc; 4524 4525 bwn_phy_exit(mac); 4526 siba_gpio_set(sc->sc_dev, 0); 4527} 4528 4529static int 4530bwn_fw_fillinfo(struct bwn_mac *mac) 4531{ 4532 int error; 4533 4534 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4535 if (error == 0) 4536 return (0); 4537 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4538 if (error == 0) 4539 return (0); 4540 return (error); 4541} 4542 4543static int 4544bwn_gpio_init(struct bwn_mac *mac) 4545{ 4546 struct bwn_softc *sc = mac->mac_sc; 4547 uint32_t mask = 0x1f, set = 0xf, value; 4548 4549 BWN_WRITE_4(mac, BWN_MACCTL, 4550 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4551 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4552 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4553 4554 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4555 mask |= 0x0060; 4556 set |= 0x0060; 4557 } 4558 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4559 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4560 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4561 mask |= 0x0200; 4562 set |= 0x0200; 4563 } 4564 if (siba_get_revid(sc->sc_dev) >= 2) 4565 mask |= 0x0010; 4566 4567 value = siba_gpio_get(sc->sc_dev); 4568 if (value == -1) 4569 return (0); 4570 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4571 4572 return (0); 4573} 4574 4575static int 4576bwn_fw_loadinitvals(struct bwn_mac *mac) 4577{ 4578#define GETFWOFFSET(fwp, offset) \ 4579 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4580 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4581 const struct bwn_fwhdr *hdr; 4582 struct bwn_fw *fw = &mac->mac_fw; 4583 int error; 4584 4585 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4586 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4587 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4588 if (error) 4589 return (error); 4590 if (fw->initvals_band.fw) { 4591 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4592 error = bwn_fwinitvals_write(mac, 4593 GETFWOFFSET(fw->initvals_band, hdr_len), 4594 be32toh(hdr->size), 4595 fw->initvals_band.fw->datasize - hdr_len); 4596 } 4597 return (error); 4598#undef GETFWOFFSET 4599} 4600 4601static int 4602bwn_phy_init(struct bwn_mac *mac) 4603{ 4604 struct bwn_softc *sc = mac->mac_sc; 4605 int error; 4606 4607 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4608 mac->mac_phy.rf_onoff(mac, 1); 4609 error = mac->mac_phy.init(mac); 4610 if (error) { 4611 device_printf(sc->sc_dev, "PHY init failed\n"); 4612 goto fail0; 4613 } 4614 error = bwn_switch_channel(mac, 4615 mac->mac_phy.get_default_chan(mac)); 4616 if (error) { 4617 device_printf(sc->sc_dev, 4618 "failed to switch default channel\n"); 4619 goto fail1; 4620 } 4621 return (0); 4622fail1: 4623 if (mac->mac_phy.exit) 4624 mac->mac_phy.exit(mac); 4625fail0: 4626 mac->mac_phy.rf_onoff(mac, 0); 4627 4628 return (error); 4629} 4630 4631static void 4632bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4633{ 4634 uint16_t ant; 4635 uint16_t tmp; 4636 4637 ant = bwn_ant2phy(antenna); 4638 4639 /* For ACK/CTS */ 4640 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4641 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4642 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4643 /* For Probe Resposes */ 4644 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4645 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4646 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4647} 4648 4649static void 4650bwn_set_opmode(struct bwn_mac *mac) 4651{ 4652 struct bwn_softc *sc = mac->mac_sc; 4653 struct ifnet *ifp = sc->sc_ifp; 4654 struct ieee80211com *ic = ifp->if_l2com; 4655 uint32_t ctl; 4656 uint16_t cfp_pretbtt; 4657 4658 ctl = BWN_READ_4(mac, BWN_MACCTL); 4659 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4660 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4661 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4662 ctl |= BWN_MACCTL_STA; 4663 4664 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4665 ic->ic_opmode == IEEE80211_M_MBSS) 4666 ctl |= BWN_MACCTL_HOSTAP; 4667 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4668 ctl &= ~BWN_MACCTL_STA; 4669 ctl |= sc->sc_filters; 4670 4671 if (siba_get_revid(sc->sc_dev) <= 4) 4672 ctl |= BWN_MACCTL_PROMISC; 4673 4674 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4675 4676 cfp_pretbtt = 2; 4677 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4678 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4679 siba_get_chiprev(sc->sc_dev) == 3) 4680 cfp_pretbtt = 100; 4681 else 4682 cfp_pretbtt = 50; 4683 } 4684 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4685} 4686 4687static int 4688bwn_dma_gettype(struct bwn_mac *mac) 4689{ 4690 uint32_t tmp; 4691 uint16_t base; 4692 4693 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4694 if (tmp & SIBA_TGSHIGH_DMA64) 4695 return (BWN_DMA_64BIT); 4696 base = bwn_dma_base(0, 0); 4697 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4698 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4699 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4700 return (BWN_DMA_32BIT); 4701 4702 return (BWN_DMA_30BIT); 4703} 4704 4705static void 4706bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4707{ 4708 if (!error) { 4709 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4710 *((bus_addr_t *)arg) = seg->ds_addr; 4711 } 4712} 4713 4714static void 4715bwn_phy_g_init_sub(struct bwn_mac *mac) 4716{ 4717 struct bwn_phy *phy = &mac->mac_phy; 4718 struct bwn_phy_g *pg = &phy->phy_g; 4719 struct bwn_softc *sc = mac->mac_sc; 4720 uint16_t i, tmp; 4721 4722 if (phy->rev == 1) 4723 bwn_phy_init_b5(mac); 4724 else 4725 bwn_phy_init_b6(mac); 4726 4727 if (phy->rev >= 2 || phy->gmode) 4728 bwn_phy_init_a(mac); 4729 4730 if (phy->rev >= 2) { 4731 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4732 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4733 } 4734 if (phy->rev == 2) { 4735 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4736 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4737 } 4738 if (phy->rev > 5) { 4739 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4740 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4741 } 4742 if (phy->gmode || phy->rev >= 2) { 4743 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4744 tmp &= BWN_PHYVER_VERSION; 4745 if (tmp == 3 || tmp == 5) { 4746 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4747 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4748 } 4749 if (tmp == 5) { 4750 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4751 0x1f00); 4752 } 4753 } 4754 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4755 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4756 if (phy->rf_rev == 8) { 4757 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4758 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4759 } 4760 if (BWN_HAS_LOOPBACK(phy)) 4761 bwn_loopback_calcgain(mac); 4762 4763 if (phy->rf_rev != 8) { 4764 if (pg->pg_initval == 0xffff) 4765 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4766 else 4767 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4768 } 4769 bwn_lo_g_init(mac); 4770 if (BWN_HAS_TXMAG(phy)) { 4771 BWN_RF_WRITE(mac, 0x52, 4772 (BWN_RF_READ(mac, 0x52) & 0xff00) 4773 | pg->pg_loctl.tx_bias | 4774 pg->pg_loctl.tx_magn); 4775 } else { 4776 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4777 } 4778 if (phy->rev >= 6) { 4779 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4780 (pg->pg_loctl.tx_bias << 12)); 4781 } 4782 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4783 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4784 else 4785 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4786 if (phy->rev < 2) 4787 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4788 else 4789 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4790 if (phy->gmode || phy->rev >= 2) { 4791 bwn_lo_g_adjust(mac); 4792 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4793 } 4794 4795 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4796 for (i = 0; i < 64; i++) { 4797 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4798 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4799 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4800 -32), 31)); 4801 } 4802 bwn_nrssi_threshold(mac); 4803 } else if (phy->gmode || phy->rev >= 2) { 4804 if (pg->pg_nrssi[0] == -1000) { 4805 KASSERT(pg->pg_nrssi[1] == -1000, 4806 ("%s:%d: fail", __func__, __LINE__)); 4807 bwn_nrssi_slope_11g(mac); 4808 } else 4809 bwn_nrssi_threshold(mac); 4810 } 4811 if (phy->rf_rev == 8) 4812 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4813 bwn_phy_hwpctl_init(mac); 4814 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4815 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4816 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4817 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4818 } 4819} 4820 4821static uint8_t 4822bwn_has_hwpctl(struct bwn_mac *mac) 4823{ 4824 4825 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4826 return (0); 4827 return (mac->mac_phy.use_hwpctl(mac)); 4828} 4829 4830static void 4831bwn_phy_init_b5(struct bwn_mac *mac) 4832{ 4833 struct bwn_phy *phy = &mac->mac_phy; 4834 struct bwn_phy_g *pg = &phy->phy_g; 4835 struct bwn_softc *sc = mac->mac_sc; 4836 uint16_t offset, value; 4837 uint8_t old_channel; 4838 4839 if (phy->analog == 1) 4840 BWN_RF_SET(mac, 0x007a, 0x0050); 4841 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4842 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4843 value = 0x2120; 4844 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4845 BWN_PHY_WRITE(mac, offset, value); 4846 value += 0x202; 4847 } 4848 } 4849 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4850 if (phy->rf_ver == 0x2050) 4851 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4852 4853 if (phy->gmode || phy->rev >= 2) { 4854 if (phy->rf_ver == 0x2050) { 4855 BWN_RF_SET(mac, 0x007a, 0x0020); 4856 BWN_RF_SET(mac, 0x0051, 0x0004); 4857 } 4858 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4859 4860 BWN_PHY_SET(mac, 0x0802, 0x0100); 4861 BWN_PHY_SET(mac, 0x042b, 0x2000); 4862 4863 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4864 4865 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4866 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4867 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4868 } 4869 4870 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4871 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4872 4873 if (phy->analog == 1) { 4874 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4875 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4876 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4877 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4878 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4879 } else 4880 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4881 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4882 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4883 4884 if (phy->analog == 1) 4885 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4886 else 4887 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4888 4889 if (phy->analog == 0) 4890 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4891 4892 old_channel = phy->chan; 4893 bwn_phy_g_switch_chan(mac, 7, 0); 4894 4895 if (phy->rf_ver != 0x2050) { 4896 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4897 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4898 } 4899 4900 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4901 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4902 4903 if (phy->rf_ver == 0x2050) { 4904 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4905 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4906 } 4907 4908 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4909 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4910 BWN_RF_SET(mac, 0x007a, 0x0007); 4911 4912 bwn_phy_g_switch_chan(mac, old_channel, 0); 4913 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4914 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4915 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4916 4917 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4918 pg->pg_txctl); 4919 4920 if (phy->rf_ver == 0x2050) 4921 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4922 4923 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4924} 4925 4926static void 4927bwn_loopback_calcgain(struct bwn_mac *mac) 4928{ 4929 struct bwn_phy *phy = &mac->mac_phy; 4930 struct bwn_phy_g *pg = &phy->phy_g; 4931 struct bwn_softc *sc = mac->mac_sc; 4932 uint16_t backup_phy[16] = { 0 }; 4933 uint16_t backup_radio[3]; 4934 uint16_t backup_bband; 4935 uint16_t i, j, loop_i_max; 4936 uint16_t trsw_rx; 4937 uint16_t loop1_outer_done, loop1_inner_done; 4938 4939 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4940 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4941 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4942 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4943 if (phy->rev != 1) { 4944 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4945 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4946 } 4947 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4948 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4949 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4950 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4951 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4952 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4953 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4954 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4955 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4956 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4957 backup_bband = pg->pg_bbatt.att; 4958 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4959 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4960 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4961 4962 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4963 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4964 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4965 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4966 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4967 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4968 if (phy->rev != 1) { 4969 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4970 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4971 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4972 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4973 } 4974 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4975 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4976 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4977 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4978 4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4981 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4982 4983 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4984 if (phy->rev != 1) { 4985 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4986 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4987 } 4988 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4989 4990 if (phy->rf_rev == 8) 4991 BWN_RF_WRITE(mac, 0x43, 0x000f); 4992 else { 4993 BWN_RF_WRITE(mac, 0x52, 0); 4994 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4995 } 4996 bwn_phy_g_set_bbatt(mac, 11); 4997 4998 if (phy->rev >= 3) 4999 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5000 else 5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5002 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5003 5004 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5005 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5006 5007 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5008 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5009 5010 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5011 if (phy->rev >= 7) { 5012 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5013 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5014 } 5015 } 5016 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5017 5018 j = 0; 5019 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5020 for (i = 0; i < loop_i_max; i++) { 5021 for (j = 0; j < 16; j++) { 5022 BWN_RF_WRITE(mac, 0x43, i); 5023 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5024 (j << 8)); 5025 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5026 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5027 DELAY(20); 5028 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5029 goto done0; 5030 } 5031 } 5032done0: 5033 loop1_outer_done = i; 5034 loop1_inner_done = j; 5035 if (j >= 8) { 5036 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5037 trsw_rx = 0x1b; 5038 for (j = j - 8; j < 16; j++) { 5039 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5040 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5041 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5042 DELAY(20); 5043 trsw_rx -= 3; 5044 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5045 goto done1; 5046 } 5047 } else 5048 trsw_rx = 0x18; 5049done1: 5050 5051 if (phy->rev != 1) { 5052 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5053 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5054 } 5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5061 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5062 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5063 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5064 5065 bwn_phy_g_set_bbatt(mac, backup_bband); 5066 5067 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5068 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5069 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5070 5071 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5072 DELAY(10); 5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5074 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5075 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5076 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5077 5078 pg->pg_max_lb_gain = 5079 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5080 pg->pg_trsw_rx_gain = trsw_rx * 2; 5081} 5082 5083static uint16_t 5084bwn_rf_init_bcm2050(struct bwn_mac *mac) 5085{ 5086 struct bwn_phy *phy = &mac->mac_phy; 5087 uint32_t tmp1 = 0, tmp2 = 0; 5088 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5089 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5090 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5091 static const uint8_t rcc_table[] = { 5092 0x02, 0x03, 0x01, 0x0f, 5093 0x06, 0x07, 0x05, 0x0f, 5094 0x0a, 0x0b, 0x09, 0x0f, 5095 0x0e, 0x0f, 0x0d, 0x0f, 5096 }; 5097 5098 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5099 rfoverval = rfover = cck3 = 0; 5100 radio0 = BWN_RF_READ(mac, 0x43); 5101 radio1 = BWN_RF_READ(mac, 0x51); 5102 radio2 = BWN_RF_READ(mac, 0x52); 5103 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5104 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5105 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5106 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5107 5108 if (phy->type == BWN_PHYTYPE_B) { 5109 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5110 reg0 = BWN_READ_2(mac, 0x3ec); 5111 5112 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5113 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5114 } else if (phy->gmode || phy->rev >= 2) { 5115 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5116 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5117 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5118 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5119 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5120 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5121 5122 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5123 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5124 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5125 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5126 if (BWN_HAS_LOOPBACK(phy)) { 5127 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5128 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5129 if (phy->rev >= 3) 5130 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5131 else 5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5133 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5134 } 5135 5136 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5137 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5138 BWN_LPD(0, 1, 1))); 5139 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5140 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5141 } 5142 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5143 5144 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5145 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5146 reg1 = BWN_READ_2(mac, 0x3e6); 5147 reg2 = BWN_READ_2(mac, 0x3f4); 5148 5149 if (phy->analog == 0) 5150 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5151 else { 5152 if (phy->analog >= 2) 5153 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5154 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5155 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5156 } 5157 5158 reg = BWN_RF_READ(mac, 0x60); 5159 index = (reg & 0x001e) >> 1; 5160 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5161 5162 if (phy->type == BWN_PHYTYPE_B) 5163 BWN_RF_WRITE(mac, 0x78, 0x26); 5164 if (phy->gmode || phy->rev >= 2) { 5165 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5166 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5167 BWN_LPD(0, 1, 1))); 5168 } 5169 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5170 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5171 if (phy->gmode || phy->rev >= 2) { 5172 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5173 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5174 BWN_LPD(0, 0, 1))); 5175 } 5176 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5177 BWN_RF_SET(mac, 0x51, 0x0004); 5178 if (phy->rf_rev == 8) 5179 BWN_RF_WRITE(mac, 0x43, 0x1f); 5180 else { 5181 BWN_RF_WRITE(mac, 0x52, 0); 5182 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5183 } 5184 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5185 5186 for (i = 0; i < 16; i++) { 5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5190 if (phy->gmode || phy->rev >= 2) { 5191 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5192 bwn_rf_2050_rfoverval(mac, 5193 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5194 } 5195 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5196 DELAY(10); 5197 if (phy->gmode || phy->rev >= 2) { 5198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5199 bwn_rf_2050_rfoverval(mac, 5200 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5201 } 5202 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5203 DELAY(10); 5204 if (phy->gmode || phy->rev >= 2) { 5205 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5206 bwn_rf_2050_rfoverval(mac, 5207 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5208 } 5209 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5210 DELAY(20); 5211 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5212 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5213 if (phy->gmode || phy->rev >= 2) { 5214 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5215 bwn_rf_2050_rfoverval(mac, 5216 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5217 } 5218 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5219 } 5220 DELAY(10); 5221 5222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5223 tmp1++; 5224 tmp1 >>= 9; 5225 5226 for (i = 0; i < 16; i++) { 5227 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5228 BWN_RF_WRITE(mac, 0x78, radio78); 5229 DELAY(10); 5230 for (j = 0; j < 16; j++) { 5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5233 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5234 if (phy->gmode || phy->rev >= 2) { 5235 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5236 bwn_rf_2050_rfoverval(mac, 5237 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5238 } 5239 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5240 DELAY(10); 5241 if (phy->gmode || phy->rev >= 2) { 5242 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5243 bwn_rf_2050_rfoverval(mac, 5244 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5245 } 5246 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5247 DELAY(10); 5248 if (phy->gmode || phy->rev >= 2) { 5249 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5250 bwn_rf_2050_rfoverval(mac, 5251 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5252 } 5253 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5254 DELAY(10); 5255 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5256 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5257 if (phy->gmode || phy->rev >= 2) { 5258 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5259 bwn_rf_2050_rfoverval(mac, 5260 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5261 } 5262 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5263 } 5264 tmp2++; 5265 tmp2 >>= 8; 5266 if (tmp1 < tmp2) 5267 break; 5268 } 5269 5270 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5271 BWN_RF_WRITE(mac, 0x51, radio1); 5272 BWN_RF_WRITE(mac, 0x52, radio2); 5273 BWN_RF_WRITE(mac, 0x43, radio0); 5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5277 BWN_WRITE_2(mac, 0x3e6, reg1); 5278 if (phy->analog != 0) 5279 BWN_WRITE_2(mac, 0x3f4, reg2); 5280 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5281 bwn_spu_workaround(mac, phy->chan); 5282 if (phy->type == BWN_PHYTYPE_B) { 5283 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5284 BWN_WRITE_2(mac, 0x3ec, reg0); 5285 } else if (phy->gmode) { 5286 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5287 BWN_READ_2(mac, BWN_PHY_RADIO) 5288 & 0x7fff); 5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5291 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5292 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5293 analogoverval); 5294 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5295 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5296 if (BWN_HAS_LOOPBACK(phy)) { 5297 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5298 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5299 } 5300 } 5301 5302 return ((i > 15) ? radio78 : rcc); 5303} 5304 5305static void 5306bwn_phy_init_b6(struct bwn_mac *mac) 5307{ 5308 struct bwn_phy *phy = &mac->mac_phy; 5309 struct bwn_phy_g *pg = &phy->phy_g; 5310 struct bwn_softc *sc = mac->mac_sc; 5311 uint16_t offset, val; 5312 uint8_t old_channel; 5313 5314 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5315 ("%s:%d: fail", __func__, __LINE__)); 5316 5317 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5318 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5319 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5320 BWN_RF_WRITE(mac, 0x51, 0x37); 5321 BWN_RF_WRITE(mac, 0x52, 0x70); 5322 BWN_RF_WRITE(mac, 0x53, 0xb3); 5323 BWN_RF_WRITE(mac, 0x54, 0x9b); 5324 BWN_RF_WRITE(mac, 0x5a, 0x88); 5325 BWN_RF_WRITE(mac, 0x5b, 0x88); 5326 BWN_RF_WRITE(mac, 0x5d, 0x88); 5327 BWN_RF_WRITE(mac, 0x5e, 0x88); 5328 BWN_RF_WRITE(mac, 0x7d, 0x88); 5329 bwn_hf_write(mac, 5330 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5331 } 5332 if (phy->rf_rev == 8) { 5333 BWN_RF_WRITE(mac, 0x51, 0); 5334 BWN_RF_WRITE(mac, 0x52, 0x40); 5335 BWN_RF_WRITE(mac, 0x53, 0xb7); 5336 BWN_RF_WRITE(mac, 0x54, 0x98); 5337 BWN_RF_WRITE(mac, 0x5a, 0x88); 5338 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5339 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5340 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5341 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5342 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5343 } else { 5344 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5345 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5346 } 5347 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5348 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5349 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5350 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5351 } 5352 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5353 BWN_PHY_WRITE(mac, offset, val); 5354 val -= 0x0202; 5355 } 5356 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5357 BWN_PHY_WRITE(mac, offset, val); 5358 val -= 0x0202; 5359 } 5360 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5361 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5362 val += 0x0202; 5363 } 5364 if (phy->type == BWN_PHYTYPE_G) { 5365 BWN_RF_SET(mac, 0x007a, 0x0020); 5366 BWN_RF_SET(mac, 0x0051, 0x0004); 5367 BWN_PHY_SET(mac, 0x0802, 0x0100); 5368 BWN_PHY_SET(mac, 0x042b, 0x2000); 5369 BWN_PHY_WRITE(mac, 0x5b, 0); 5370 BWN_PHY_WRITE(mac, 0x5c, 0); 5371 } 5372 5373 old_channel = phy->chan; 5374 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5375 5376 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5377 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5378 DELAY(40); 5379 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5380 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5381 BWN_RF_WRITE(mac, 0x50, 0x20); 5382 } 5383 if (phy->rf_rev <= 2) { 5384 BWN_RF_WRITE(mac, 0x7c, 0x20); 5385 BWN_RF_WRITE(mac, 0x5a, 0x70); 5386 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5387 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5388 } 5389 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5390 5391 bwn_phy_g_switch_chan(mac, old_channel, 0); 5392 5393 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5394 if (phy->rf_rev >= 6) 5395 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5396 else 5397 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5398 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5399 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5400 pg->pg_txctl); 5401 if (phy->rf_rev <= 5) 5402 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5403 if (phy->rf_rev <= 2) 5404 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5405 5406 if (phy->analog == 4) { 5407 BWN_WRITE_2(mac, 0x3e4, 9); 5408 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5409 } else 5410 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5411 if (phy->type == BWN_PHYTYPE_B) 5412 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5413 else if (phy->type == BWN_PHYTYPE_G) 5414 BWN_WRITE_2(mac, 0x03e6, 0x0); 5415} 5416 5417static void 5418bwn_phy_init_a(struct bwn_mac *mac) 5419{ 5420 struct bwn_phy *phy = &mac->mac_phy; 5421 struct bwn_softc *sc = mac->mac_sc; 5422 5423 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5424 ("%s:%d: fail", __func__, __LINE__)); 5425 5426 if (phy->rev >= 6) { 5427 if (phy->type == BWN_PHYTYPE_A) 5428 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5429 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5430 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5431 else 5432 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5433 } 5434 5435 bwn_wa_init(mac); 5436 5437 if (phy->type == BWN_PHYTYPE_G && 5438 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5439 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5440} 5441 5442static void 5443bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5444{ 5445 int i; 5446 5447 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5448 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5449} 5450 5451static void 5452bwn_wa_agc(struct bwn_mac *mac) 5453{ 5454 struct bwn_phy *phy = &mac->mac_phy; 5455 5456 if (phy->rev == 1) { 5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5465 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5466 } else { 5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5470 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5471 } 5472 5473 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5474 0x5700); 5475 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5477 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5478 BWN_RF_SET(mac, 0x7a, 0x0008); 5479 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5480 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5482 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5483 if (phy->rev == 1) 5484 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5494 if (phy->rev == 1) { 5495 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5496 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5497 } else { 5498 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5500 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5501 if (phy->rev >= 6) { 5502 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5503 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5504 (uint16_t)~0xf000, 0x3000); 5505 } 5506 } 5507 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5508 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5509 if (phy->rev == 1) { 5510 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5511 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5512 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5513 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5518 } else { 5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5522 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5523 } 5524 if (phy->rev >= 6) { 5525 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5526 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5527 } 5528 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5529} 5530 5531static void 5532bwn_wa_grev1(struct bwn_mac *mac) 5533{ 5534 struct bwn_phy *phy = &mac->mac_phy; 5535 int i; 5536 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5537 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5538 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5539 5540 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5541 5542 /* init CRSTHRES and ANTDWELL */ 5543 if (phy->rev == 1) { 5544 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5545 } else if (phy->rev == 2) { 5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5547 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5548 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5549 } else { 5550 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5551 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5552 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5553 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5554 } 5555 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5556 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5557 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5558 5559 /* XXX support PHY-A??? */ 5560 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5561 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5562 bwn_tab_finefreqg[i]); 5563 5564 /* XXX support PHY-A??? */ 5565 if (phy->rev == 1) 5566 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5567 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5568 bwn_tab_noise_g1[i]); 5569 else 5570 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5572 bwn_tab_noise_g2[i]); 5573 5574 5575 for (i = 0; i < N(bwn_tab_rotor); i++) 5576 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5577 bwn_tab_rotor[i]); 5578 5579 /* XXX support PHY-A??? */ 5580 if (phy->rev >= 6) { 5581 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5582 BWN_PHY_ENCORE_EN) 5583 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5584 else 5585 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5586 } else 5587 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5588 5589 for (i = 0; i < N(bwn_tab_retard); i++) 5590 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5591 bwn_tab_retard[i]); 5592 5593 if (phy->rev == 1) { 5594 for (i = 0; i < 16; i++) 5595 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5596 i, 0x0020); 5597 } else { 5598 for (i = 0; i < 32; i++) 5599 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5600 } 5601 5602 bwn_wa_agc(mac); 5603} 5604 5605static void 5606bwn_wa_grev26789(struct bwn_mac *mac) 5607{ 5608 struct bwn_phy *phy = &mac->mac_phy; 5609 int i; 5610 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5611 uint16_t ofdmrev; 5612 5613 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5614 5615 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5616 5617 /* init CRSTHRES and ANTDWELL */ 5618 if (phy->rev == 1) 5619 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5620 else if (phy->rev == 2) { 5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5622 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5623 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5624 } else { 5625 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5626 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5627 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5628 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5629 } 5630 5631 for (i = 0; i < 64; i++) 5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5633 5634 /* XXX support PHY-A??? */ 5635 if (phy->rev == 1) 5636 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5637 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5638 bwn_tab_noise_g1[i]); 5639 else 5640 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5641 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5642 bwn_tab_noise_g2[i]); 5643 5644 /* XXX support PHY-A??? */ 5645 if (phy->rev >= 6) { 5646 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5647 BWN_PHY_ENCORE_EN) 5648 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5649 else 5650 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5651 } else 5652 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5653 5654 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5655 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5656 bwn_tab_sigmasqr2[i]); 5657 5658 if (phy->rev == 1) { 5659 for (i = 0; i < 16; i++) 5660 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5661 0x0020); 5662 } else { 5663 for (i = 0; i < 32; i++) 5664 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5665 } 5666 5667 bwn_wa_agc(mac); 5668 5669 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5670 if (ofdmrev > 2) { 5671 if (phy->type == BWN_PHYTYPE_A) 5672 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5673 else 5674 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5675 } else { 5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5679 } 5680 5681 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5682 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5683} 5684 5685static void 5686bwn_wa_init(struct bwn_mac *mac) 5687{ 5688 struct bwn_phy *phy = &mac->mac_phy; 5689 struct bwn_softc *sc = mac->mac_sc; 5690 5691 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5692 5693 switch (phy->rev) { 5694 case 1: 5695 bwn_wa_grev1(mac); 5696 break; 5697 case 2: 5698 case 6: 5699 case 7: 5700 case 8: 5701 case 9: 5702 bwn_wa_grev26789(mac); 5703 break; 5704 default: 5705 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5706 } 5707 5708 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5709 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5710 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5711 if (phy->rev < 2) { 5712 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5713 0x0002); 5714 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5715 0x0001); 5716 } else { 5717 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5718 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5719 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5720 BWN_BFL_EXTLNA) && 5721 (phy->rev >= 7)) { 5722 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5723 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5724 0x0020, 0x0001); 5725 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5726 0x0021, 0x0001); 5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5728 0x0022, 0x0001); 5729 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5730 0x0023, 0x0000); 5731 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5732 0x0000, 0x0000); 5733 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5734 0x0003, 0x0002); 5735 } 5736 } 5737 } 5738 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5739 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5740 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5741 } 5742 5743 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5744 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5745} 5746 5747static void 5748bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5749 uint16_t value) 5750{ 5751 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5752 uint16_t addr; 5753 5754 addr = table + offset; 5755 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5756 (addr - 1 != pg->pg_ofdmtab_addr)) { 5757 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5758 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5759 } 5760 pg->pg_ofdmtab_addr = addr; 5761 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5762} 5763 5764static void 5765bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5766 uint32_t value) 5767{ 5768 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5769 uint16_t addr; 5770 5771 addr = table + offset; 5772 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5773 (addr - 1 != pg->pg_ofdmtab_addr)) { 5774 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5775 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5776 } 5777 pg->pg_ofdmtab_addr = addr; 5778 5779 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5780 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5781} 5782 5783static void 5784bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5785 uint16_t value) 5786{ 5787 5788 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5789 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5790} 5791 5792static void 5793bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5794{ 5795 struct bwn_phy *phy = &mac->mac_phy; 5796 struct bwn_softc *sc = mac->mac_sc; 5797 unsigned int i, max_loop; 5798 uint16_t value; 5799 uint32_t buffer[5] = { 5800 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5801 }; 5802 5803 if (ofdm) { 5804 max_loop = 0x1e; 5805 buffer[0] = 0x000201cc; 5806 } else { 5807 max_loop = 0xfa; 5808 buffer[0] = 0x000b846e; 5809 } 5810 5811 BWN_ASSERT_LOCKED(mac->mac_sc); 5812 5813 for (i = 0; i < 5; i++) 5814 bwn_ram_write(mac, i * 4, buffer[i]); 5815 5816 BWN_WRITE_2(mac, 0x0568, 0x0000); 5817 BWN_WRITE_2(mac, 0x07c0, 5818 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5819 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5820 BWN_WRITE_2(mac, 0x050c, value); 5821 if (phy->type == BWN_PHYTYPE_LP) 5822 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5823 BWN_WRITE_2(mac, 0x0508, 0x0000); 5824 BWN_WRITE_2(mac, 0x050a, 0x0000); 5825 BWN_WRITE_2(mac, 0x054c, 0x0000); 5826 BWN_WRITE_2(mac, 0x056a, 0x0014); 5827 BWN_WRITE_2(mac, 0x0568, 0x0826); 5828 BWN_WRITE_2(mac, 0x0500, 0x0000); 5829 if (phy->type == BWN_PHYTYPE_LP) 5830 BWN_WRITE_2(mac, 0x0502, 0x0050); 5831 else 5832 BWN_WRITE_2(mac, 0x0502, 0x0030); 5833 5834 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5835 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5836 for (i = 0x00; i < max_loop; i++) { 5837 value = BWN_READ_2(mac, 0x050e); 5838 if (value & 0x0080) 5839 break; 5840 DELAY(10); 5841 } 5842 for (i = 0x00; i < 0x0a; i++) { 5843 value = BWN_READ_2(mac, 0x050e); 5844 if (value & 0x0400) 5845 break; 5846 DELAY(10); 5847 } 5848 for (i = 0x00; i < 0x19; i++) { 5849 value = BWN_READ_2(mac, 0x0690); 5850 if (!(value & 0x0100)) 5851 break; 5852 DELAY(10); 5853 } 5854 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5855 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5856} 5857 5858static void 5859bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5860{ 5861 uint32_t macctl; 5862 5863 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5864 5865 macctl = BWN_READ_4(mac, BWN_MACCTL); 5866 if (macctl & BWN_MACCTL_BIGENDIAN) 5867 printf("TODO: need swap\n"); 5868 5869 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5870 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5871 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5872} 5873 5874static void 5875bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5876{ 5877 uint16_t value; 5878 5879 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5880 ("%s:%d: fail", __func__, __LINE__)); 5881 5882 value = (uint8_t) (ctl->q); 5883 value |= ((uint8_t) (ctl->i)) << 8; 5884 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5885} 5886 5887static uint16_t 5888bwn_lo_calcfeed(struct bwn_mac *mac, 5889 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5890{ 5891 struct bwn_phy *phy = &mac->mac_phy; 5892 struct bwn_softc *sc = mac->mac_sc; 5893 uint16_t rfover; 5894 uint16_t feedthrough; 5895 5896 if (phy->gmode) { 5897 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5898 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5899 5900 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5901 ("%s:%d: fail", __func__, __LINE__)); 5902 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5903 ("%s:%d: fail", __func__, __LINE__)); 5904 5905 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5906 5907 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5908 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5909 phy->rev > 6) 5910 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5911 5912 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5913 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5914 DELAY(10); 5915 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5916 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5917 DELAY(10); 5918 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5919 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5920 DELAY(10); 5921 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5922 } else { 5923 pga |= BWN_PHY_PGACTL_UNKNOWN; 5924 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5925 DELAY(10); 5926 pga |= BWN_PHY_PGACTL_LOWBANDW; 5927 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5928 DELAY(10); 5929 pga |= BWN_PHY_PGACTL_LPF; 5930 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5931 } 5932 DELAY(21); 5933 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5934 5935 return (feedthrough); 5936} 5937 5938static uint16_t 5939bwn_lo_txctl_regtable(struct bwn_mac *mac, 5940 uint16_t *value, uint16_t *pad_mix_gain) 5941{ 5942 struct bwn_phy *phy = &mac->mac_phy; 5943 uint16_t reg, v, padmix; 5944 5945 if (phy->type == BWN_PHYTYPE_B) { 5946 v = 0x30; 5947 if (phy->rf_rev <= 5) { 5948 reg = 0x43; 5949 padmix = 0; 5950 } else { 5951 reg = 0x52; 5952 padmix = 5; 5953 } 5954 } else { 5955 if (phy->rev >= 2 && phy->rf_rev == 8) { 5956 reg = 0x43; 5957 v = 0x10; 5958 padmix = 2; 5959 } else { 5960 reg = 0x52; 5961 v = 0x30; 5962 padmix = 5; 5963 } 5964 } 5965 if (value) 5966 *value = v; 5967 if (pad_mix_gain) 5968 *pad_mix_gain = padmix; 5969 5970 return (reg); 5971} 5972 5973static void 5974bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5975{ 5976 struct bwn_phy *phy = &mac->mac_phy; 5977 struct bwn_phy_g *pg = &phy->phy_g; 5978 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5979 uint16_t reg, mask; 5980 uint16_t trsw_rx, pga; 5981 uint16_t rf_pctl_reg; 5982 5983 static const uint8_t tx_bias_values[] = { 5984 0x09, 0x08, 0x0a, 0x01, 0x00, 5985 0x02, 0x05, 0x04, 0x06, 5986 }; 5987 static const uint8_t tx_magn_values[] = { 5988 0x70, 0x40, 5989 }; 5990 5991 if (!BWN_HAS_LOOPBACK(phy)) { 5992 rf_pctl_reg = 6; 5993 trsw_rx = 2; 5994 pga = 0; 5995 } else { 5996 int lb_gain; 5997 5998 trsw_rx = 0; 5999 lb_gain = pg->pg_max_lb_gain / 2; 6000 if (lb_gain > 10) { 6001 rf_pctl_reg = 0; 6002 pga = abs(10 - lb_gain) / 6; 6003 pga = MIN(MAX(pga, 0), 15); 6004 } else { 6005 int cmp_val; 6006 int tmp; 6007 6008 pga = 0; 6009 cmp_val = 0x24; 6010 if ((phy->rev >= 2) && 6011 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6012 cmp_val = 0x3c; 6013 tmp = lb_gain; 6014 if ((10 - lb_gain) < cmp_val) 6015 tmp = (10 - lb_gain); 6016 if (tmp < 0) 6017 tmp += 6; 6018 else 6019 tmp += 3; 6020 cmp_val /= 4; 6021 tmp /= 4; 6022 if (tmp >= cmp_val) 6023 rf_pctl_reg = cmp_val; 6024 else 6025 rf_pctl_reg = tmp; 6026 } 6027 } 6028 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6029 bwn_phy_g_set_bbatt(mac, 2); 6030 6031 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6032 mask = ~mask; 6033 BWN_RF_MASK(mac, reg, mask); 6034 6035 if (BWN_HAS_TXMAG(phy)) { 6036 int i, j; 6037 int feedthrough; 6038 int min_feedth = 0xffff; 6039 uint8_t tx_magn, tx_bias; 6040 6041 for (i = 0; i < N(tx_magn_values); i++) { 6042 tx_magn = tx_magn_values[i]; 6043 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6044 for (j = 0; j < N(tx_bias_values); j++) { 6045 tx_bias = tx_bias_values[j]; 6046 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6047 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6048 trsw_rx); 6049 if (feedthrough < min_feedth) { 6050 lo->tx_bias = tx_bias; 6051 lo->tx_magn = tx_magn; 6052 min_feedth = feedthrough; 6053 } 6054 if (lo->tx_bias == 0) 6055 break; 6056 } 6057 BWN_RF_WRITE(mac, 0x52, 6058 (BWN_RF_READ(mac, 0x52) 6059 & 0xff00) | lo->tx_bias | lo-> 6060 tx_magn); 6061 } 6062 } else { 6063 lo->tx_magn = 0; 6064 lo->tx_bias = 0; 6065 BWN_RF_MASK(mac, 0x52, 0xfff0); 6066 } 6067 6068 BWN_GETTIME(lo->txctl_measured_time); 6069} 6070 6071static void 6072bwn_lo_get_powervector(struct bwn_mac *mac) 6073{ 6074 struct bwn_phy *phy = &mac->mac_phy; 6075 struct bwn_phy_g *pg = &phy->phy_g; 6076 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6077 int i; 6078 uint64_t tmp; 6079 uint64_t power_vector = 0; 6080 6081 for (i = 0; i < 8; i += 2) { 6082 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6083 power_vector |= (tmp << (i * 8)); 6084 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6085 } 6086 if (power_vector) 6087 lo->power_vector = power_vector; 6088 6089 BWN_GETTIME(lo->pwr_vec_read_time); 6090} 6091 6092static void 6093bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6094 int use_trsw_rx) 6095{ 6096 struct bwn_phy *phy = &mac->mac_phy; 6097 struct bwn_phy_g *pg = &phy->phy_g; 6098 uint16_t tmp; 6099 6100 if (max_rx_gain < 0) 6101 max_rx_gain = 0; 6102 6103 if (BWN_HAS_LOOPBACK(phy)) { 6104 int trsw_rx = 0; 6105 int trsw_rx_gain; 6106 6107 if (use_trsw_rx) { 6108 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6109 if (max_rx_gain >= trsw_rx_gain) { 6110 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6111 trsw_rx = 0x20; 6112 } 6113 } else 6114 trsw_rx_gain = max_rx_gain; 6115 if (trsw_rx_gain < 9) { 6116 pg->pg_lna_lod_gain = 0; 6117 } else { 6118 pg->pg_lna_lod_gain = 1; 6119 trsw_rx_gain -= 8; 6120 } 6121 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6122 pg->pg_pga_gain = trsw_rx_gain / 3; 6123 if (pg->pg_pga_gain >= 5) { 6124 pg->pg_pga_gain -= 5; 6125 pg->pg_lna_gain = 2; 6126 } else 6127 pg->pg_lna_gain = 0; 6128 } else { 6129 pg->pg_lna_gain = 0; 6130 pg->pg_trsw_rx_gain = 0x20; 6131 if (max_rx_gain >= 0x14) { 6132 pg->pg_lna_lod_gain = 1; 6133 pg->pg_pga_gain = 2; 6134 } else if (max_rx_gain >= 0x12) { 6135 pg->pg_lna_lod_gain = 1; 6136 pg->pg_pga_gain = 1; 6137 } else if (max_rx_gain >= 0xf) { 6138 pg->pg_lna_lod_gain = 1; 6139 pg->pg_pga_gain = 0; 6140 } else { 6141 pg->pg_lna_lod_gain = 0; 6142 pg->pg_pga_gain = 0; 6143 } 6144 } 6145 6146 tmp = BWN_RF_READ(mac, 0x7a); 6147 if (pg->pg_lna_lod_gain == 0) 6148 tmp &= ~0x0008; 6149 else 6150 tmp |= 0x0008; 6151 BWN_RF_WRITE(mac, 0x7a, tmp); 6152} 6153 6154static void 6155bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6156{ 6157 struct bwn_phy *phy = &mac->mac_phy; 6158 struct bwn_phy_g *pg = &phy->phy_g; 6159 struct bwn_softc *sc = mac->mac_sc; 6160 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6161 struct timespec ts; 6162 uint16_t tmp; 6163 6164 if (bwn_has_hwpctl(mac)) { 6165 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6166 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6167 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6168 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6169 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6170 6171 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6172 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6173 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6174 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6175 } 6176 if (phy->type == BWN_PHYTYPE_B && 6177 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6180 } 6181 if (phy->rev >= 2) { 6182 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6183 sav->phy_analogoverval = 6184 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6185 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6186 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6187 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6188 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6189 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6190 6191 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6192 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6193 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6194 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6195 if (phy->type == BWN_PHYTYPE_G) { 6196 if ((phy->rev >= 7) && 6197 (siba_sprom_get_bf_lo(sc->sc_dev) & 6198 BWN_BFL_EXTLNA)) { 6199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6200 } else { 6201 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6202 } 6203 } else { 6204 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6205 } 6206 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6207 } 6208 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6209 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6210 sav->rf0 = BWN_RF_READ(mac, 0x43); 6211 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6212 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6213 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6214 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6215 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6216 6217 if (!BWN_HAS_TXMAG(phy)) { 6218 sav->rf2 = BWN_RF_READ(mac, 0x52); 6219 sav->rf2 &= 0x00f0; 6220 } 6221 if (phy->type == BWN_PHYTYPE_B) { 6222 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6223 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6225 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6226 } else { 6227 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6228 | 0x8000); 6229 } 6230 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6231 & 0xf000); 6232 6233 tmp = 6234 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6235 BWN_PHY_WRITE(mac, tmp, 0x007f); 6236 6237 tmp = sav->phy_syncctl; 6238 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6239 tmp = sav->rf1; 6240 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6241 6242 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6243 if (phy->type == BWN_PHYTYPE_G || 6244 (phy->type == BWN_PHYTYPE_B && 6245 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6246 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6247 } else 6248 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6249 if (phy->rev >= 2) 6250 bwn_dummy_transmission(mac, 0, 1); 6251 bwn_phy_g_switch_chan(mac, 6, 0); 6252 BWN_RF_READ(mac, 0x51); 6253 if (phy->type == BWN_PHYTYPE_G) 6254 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6255 6256 nanouptime(&ts); 6257 if (time_before(lo->txctl_measured_time, 6258 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6259 bwn_lo_measure_txctl_values(mac); 6260 6261 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6262 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6263 else { 6264 if (phy->type == BWN_PHYTYPE_B) 6265 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6266 else 6267 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6268 } 6269} 6270 6271static void 6272bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6273{ 6274 struct bwn_phy *phy = &mac->mac_phy; 6275 struct bwn_phy_g *pg = &phy->phy_g; 6276 uint16_t tmp; 6277 6278 if (phy->rev >= 2) { 6279 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6280 tmp = (pg->pg_pga_gain << 8); 6281 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6282 DELAY(5); 6283 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6284 DELAY(2); 6285 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6286 } else { 6287 tmp = (pg->pg_pga_gain | 0xefa0); 6288 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6289 } 6290 if (phy->type == BWN_PHYTYPE_G) { 6291 if (phy->rev >= 3) 6292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6293 else 6294 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6295 if (phy->rev >= 2) 6296 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6297 else 6298 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6299 } 6300 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6301 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6302 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6303 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6304 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6305 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6306 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6307 if (!BWN_HAS_TXMAG(phy)) { 6308 tmp = sav->rf2; 6309 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6310 } 6311 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6312 if (phy->type == BWN_PHYTYPE_B && 6313 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6316 } 6317 if (phy->rev >= 2) { 6318 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6319 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6320 sav->phy_analogoverval); 6321 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6322 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6323 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6324 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6325 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6326 } 6327 if (bwn_has_hwpctl(mac)) { 6328 tmp = (sav->phy_lomask & 0xbfff); 6329 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6330 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6331 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6332 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6333 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6334 } 6335 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6336} 6337 6338static int 6339bwn_lo_probe_loctl(struct bwn_mac *mac, 6340 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6341{ 6342 struct bwn_phy *phy = &mac->mac_phy; 6343 struct bwn_phy_g *pg = &phy->phy_g; 6344 struct bwn_loctl orig, test; 6345 struct bwn_loctl prev = { -100, -100 }; 6346 static const struct bwn_loctl modifiers[] = { 6347 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6348 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6349 }; 6350 int begin, end, lower = 0, i; 6351 uint16_t feedth; 6352 6353 if (d->curstate == 0) { 6354 begin = 1; 6355 end = 8; 6356 } else if (d->curstate % 2 == 0) { 6357 begin = d->curstate - 1; 6358 end = d->curstate + 1; 6359 } else { 6360 begin = d->curstate - 2; 6361 end = d->curstate + 2; 6362 } 6363 if (begin < 1) 6364 begin += 8; 6365 if (end > 8) 6366 end -= 8; 6367 6368 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6369 i = begin; 6370 d->curstate = i; 6371 while (1) { 6372 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6373 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6374 test.i += modifiers[i - 1].i * d->multipler; 6375 test.q += modifiers[i - 1].q * d->multipler; 6376 if ((test.i != prev.i || test.q != prev.q) && 6377 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6378 bwn_lo_write(mac, &test); 6379 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6380 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6381 if (feedth < d->feedth) { 6382 memcpy(probe, &test, 6383 sizeof(struct bwn_loctl)); 6384 lower = 1; 6385 d->feedth = feedth; 6386 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6387 break; 6388 } 6389 } 6390 memcpy(&prev, &test, sizeof(prev)); 6391 if (i == end) 6392 break; 6393 if (i == 8) 6394 i = 1; 6395 else 6396 i++; 6397 d->curstate = i; 6398 } 6399 6400 return (lower); 6401} 6402 6403static void 6404bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6405{ 6406 struct bwn_phy *phy = &mac->mac_phy; 6407 struct bwn_phy_g *pg = &phy->phy_g; 6408 struct bwn_lo_g_sm d; 6409 struct bwn_loctl probe; 6410 int lower, repeat, cnt = 0; 6411 uint16_t feedth; 6412 6413 d.nmeasure = 0; 6414 d.multipler = 1; 6415 if (BWN_HAS_LOOPBACK(phy)) 6416 d.multipler = 3; 6417 6418 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6419 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6420 6421 do { 6422 bwn_lo_write(mac, &d.loctl); 6423 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6424 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6425 if (feedth < 0x258) { 6426 if (feedth >= 0x12c) 6427 *rxgain += 6; 6428 else 6429 *rxgain += 3; 6430 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6431 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6432 } 6433 d.feedth = feedth; 6434 d.curstate = 0; 6435 do { 6436 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6437 ("%s:%d: fail", __func__, __LINE__)); 6438 memcpy(&probe, &d.loctl, 6439 sizeof(struct bwn_loctl)); 6440 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6441 if (!lower) 6442 break; 6443 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6444 break; 6445 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6446 d.nmeasure++; 6447 } while (d.nmeasure < 24); 6448 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6449 6450 if (BWN_HAS_LOOPBACK(phy)) { 6451 if (d.feedth > 0x1194) 6452 *rxgain -= 6; 6453 else if (d.feedth < 0x5dc) 6454 *rxgain += 3; 6455 if (cnt == 0) { 6456 if (d.feedth <= 0x5dc) { 6457 d.multipler = 1; 6458 cnt++; 6459 } else 6460 d.multipler = 2; 6461 } else if (cnt == 2) 6462 d.multipler = 1; 6463 } 6464 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6465 } while (++cnt < repeat); 6466} 6467 6468static struct bwn_lo_calib * 6469bwn_lo_calibset(struct bwn_mac *mac, 6470 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6471{ 6472 struct bwn_phy *phy = &mac->mac_phy; 6473 struct bwn_phy_g *pg = &phy->phy_g; 6474 struct bwn_loctl loctl = { 0, 0 }; 6475 struct bwn_lo_calib *cal; 6476 struct bwn_lo_g_value sval = { 0 }; 6477 int rxgain; 6478 uint16_t pad, reg, value; 6479 6480 sval.old_channel = phy->chan; 6481 bwn_mac_suspend(mac); 6482 bwn_lo_save(mac, &sval); 6483 6484 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6485 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6486 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6487 6488 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6489 if (rfatt->padmix) 6490 rxgain -= pad; 6491 if (BWN_HAS_LOOPBACK(phy)) 6492 rxgain += pg->pg_max_lb_gain; 6493 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6494 bwn_phy_g_set_bbatt(mac, bbatt->att); 6495 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6496 6497 bwn_lo_restore(mac, &sval); 6498 bwn_mac_enable(mac); 6499 6500 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6501 if (!cal) { 6502 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6503 return (NULL); 6504 } 6505 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6506 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6507 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6508 6509 BWN_GETTIME(cal->calib_time); 6510 6511 return (cal); 6512} 6513 6514static struct bwn_lo_calib * 6515bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6516 const struct bwn_rfatt *rfatt) 6517{ 6518 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6519 struct bwn_lo_calib *c; 6520 6521 TAILQ_FOREACH(c, &lo->calib_list, list) { 6522 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6523 continue; 6524 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6525 continue; 6526 return (c); 6527 } 6528 6529 c = bwn_lo_calibset(mac, bbatt, rfatt); 6530 if (!c) 6531 return (NULL); 6532 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6533 6534 return (c); 6535} 6536 6537static void 6538bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6539{ 6540 struct bwn_phy *phy = &mac->mac_phy; 6541 struct bwn_phy_g *pg = &phy->phy_g; 6542 struct bwn_softc *sc = mac->mac_sc; 6543 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6544 const struct bwn_rfatt *rfatt; 6545 const struct bwn_bbatt *bbatt; 6546 uint64_t pvector; 6547 int i; 6548 int rf_offset, bb_offset; 6549 uint8_t changed = 0; 6550 6551 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6552 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6553 ("%s:%d: fail", __func__, __LINE__)); 6554 6555 pvector = lo->power_vector; 6556 if (!update && !pvector) 6557 return; 6558 6559 bwn_mac_suspend(mac); 6560 6561 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6562 struct bwn_lo_calib *cal; 6563 int idx; 6564 uint16_t val; 6565 6566 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6567 continue; 6568 bb_offset = i / lo->rfatt.len; 6569 rf_offset = i % lo->rfatt.len; 6570 bbatt = &(lo->bbatt.array[bb_offset]); 6571 rfatt = &(lo->rfatt.array[rf_offset]); 6572 6573 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6574 if (!cal) { 6575 device_printf(sc->sc_dev, "LO: Could not " 6576 "calibrate DC table entry\n"); 6577 continue; 6578 } 6579 val = (uint8_t)(cal->ctl.q); 6580 val |= ((uint8_t)(cal->ctl.i)) << 4; 6581 free(cal, M_DEVBUF); 6582 6583 idx = i / 2; 6584 if (i % 2) 6585 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6586 | ((val & 0x00ff) << 8); 6587 else 6588 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6589 | (val & 0x00ff); 6590 changed = 1; 6591 } 6592 if (changed) { 6593 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6594 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6595 } 6596 bwn_mac_enable(mac); 6597} 6598 6599static void 6600bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6601{ 6602 6603 if (!rf->padmix) 6604 return; 6605 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6606 rf->att = 4; 6607} 6608 6609static void 6610bwn_lo_g_adjust(struct bwn_mac *mac) 6611{ 6612 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6613 struct bwn_lo_calib *cal; 6614 struct bwn_rfatt rf; 6615 6616 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6617 bwn_lo_fixup_rfatt(&rf); 6618 6619 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6620 if (!cal) 6621 return; 6622 bwn_lo_write(mac, &cal->ctl); 6623} 6624 6625static void 6626bwn_lo_g_init(struct bwn_mac *mac) 6627{ 6628 6629 if (!bwn_has_hwpctl(mac)) 6630 return; 6631 6632 bwn_lo_get_powervector(mac); 6633 bwn_phy_g_dc_lookup_init(mac, 1); 6634} 6635 6636static void 6637bwn_mac_suspend(struct bwn_mac *mac) 6638{ 6639 struct bwn_softc *sc = mac->mac_sc; 6640 int i; 6641 uint32_t tmp; 6642 6643 KASSERT(mac->mac_suspended >= 0, 6644 ("%s:%d: fail", __func__, __LINE__)); 6645 6646 if (mac->mac_suspended == 0) { 6647 bwn_psctl(mac, BWN_PS_AWAKE); 6648 BWN_WRITE_4(mac, BWN_MACCTL, 6649 BWN_READ_4(mac, BWN_MACCTL) 6650 & ~BWN_MACCTL_ON); 6651 BWN_READ_4(mac, BWN_MACCTL); 6652 for (i = 35; i; i--) { 6653 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6654 if (tmp & BWN_INTR_MAC_SUSPENDED) 6655 goto out; 6656 DELAY(10); 6657 } 6658 for (i = 40; i; i--) { 6659 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6660 if (tmp & BWN_INTR_MAC_SUSPENDED) 6661 goto out; 6662 DELAY(1000); 6663 } 6664 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6665 } 6666out: 6667 mac->mac_suspended++; 6668} 6669 6670static void 6671bwn_mac_enable(struct bwn_mac *mac) 6672{ 6673 struct bwn_softc *sc = mac->mac_sc; 6674 uint16_t state; 6675 6676 state = bwn_shm_read_2(mac, BWN_SHARED, 6677 BWN_SHARED_UCODESTAT); 6678 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6679 state != BWN_SHARED_UCODESTAT_SLEEP) 6680 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6681 6682 mac->mac_suspended--; 6683 KASSERT(mac->mac_suspended >= 0, 6684 ("%s:%d: fail", __func__, __LINE__)); 6685 if (mac->mac_suspended == 0) { 6686 BWN_WRITE_4(mac, BWN_MACCTL, 6687 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6688 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6689 BWN_READ_4(mac, BWN_MACCTL); 6690 BWN_READ_4(mac, BWN_INTR_REASON); 6691 bwn_psctl(mac, 0); 6692 } 6693} 6694 6695static void 6696bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6697{ 6698 struct bwn_softc *sc = mac->mac_sc; 6699 int i; 6700 uint16_t ucstat; 6701 6702 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6703 ("%s:%d: fail", __func__, __LINE__)); 6704 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6705 ("%s:%d: fail", __func__, __LINE__)); 6706 6707 /* XXX forcibly awake and hwps-off */ 6708 6709 BWN_WRITE_4(mac, BWN_MACCTL, 6710 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6711 ~BWN_MACCTL_HWPS); 6712 BWN_READ_4(mac, BWN_MACCTL); 6713 if (siba_get_revid(sc->sc_dev) >= 5) { 6714 for (i = 0; i < 100; i++) { 6715 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6716 BWN_SHARED_UCODESTAT); 6717 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6718 break; 6719 DELAY(10); 6720 } 6721 } 6722} 6723 6724static int16_t 6725bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6726{ 6727 6728 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6729 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6730} 6731 6732static void 6733bwn_nrssi_threshold(struct bwn_mac *mac) 6734{ 6735 struct bwn_phy *phy = &mac->mac_phy; 6736 struct bwn_phy_g *pg = &phy->phy_g; 6737 struct bwn_softc *sc = mac->mac_sc; 6738 int32_t a, b; 6739 int16_t tmp16; 6740 uint16_t tmpu16; 6741 6742 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6743 6744 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6745 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6746 a = 0x13; 6747 b = 0x12; 6748 } else { 6749 a = 0xe; 6750 b = 0x11; 6751 } 6752 6753 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6754 a += (pg->pg_nrssi[0] << 6); 6755 a += (a < 32) ? 31 : 32; 6756 a = a >> 6; 6757 a = MIN(MAX(a, -31), 31); 6758 6759 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6760 b += (pg->pg_nrssi[0] << 6); 6761 if (b < 32) 6762 b += 31; 6763 else 6764 b += 32; 6765 b = b >> 6; 6766 b = MIN(MAX(b, -31), 31); 6767 6768 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6769 tmpu16 |= ((uint32_t)b & 0x0000003f); 6770 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6771 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6772 return; 6773 } 6774 6775 tmp16 = bwn_nrssi_read(mac, 0x20); 6776 if (tmp16 >= 0x20) 6777 tmp16 -= 0x40; 6778 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6779} 6780 6781static void 6782bwn_nrssi_slope_11g(struct bwn_mac *mac) 6783{ 6784#define SAVE_RF_MAX 3 6785#define SAVE_PHY_COMM_MAX 4 6786#define SAVE_PHY3_MAX 8 6787 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6788 { 0x7a, 0x52, 0x43 }; 6789 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6790 { 0x15, 0x5a, 0x59, 0x58 }; 6791 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6792 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6793 0x0801, 0x0060, 0x0014, 0x0478 6794 }; 6795 struct bwn_phy *phy = &mac->mac_phy; 6796 struct bwn_phy_g *pg = &phy->phy_g; 6797 int32_t i, tmp32, phy3_idx = 0; 6798 uint16_t delta, tmp; 6799 uint16_t save_rf[SAVE_RF_MAX]; 6800 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6801 uint16_t save_phy3[SAVE_PHY3_MAX]; 6802 uint16_t ant_div, phy0, chan_ex; 6803 int16_t nrssi0, nrssi1; 6804 6805 KASSERT(phy->type == BWN_PHYTYPE_G, 6806 ("%s:%d: fail", __func__, __LINE__)); 6807 6808 if (phy->rf_rev >= 9) 6809 return; 6810 if (phy->rf_rev == 8) 6811 bwn_nrssi_offset(mac); 6812 6813 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6814 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6815 6816 /* 6817 * Save RF/PHY registers for later restoration 6818 */ 6819 ant_div = BWN_READ_2(mac, 0x03e2); 6820 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6821 for (i = 0; i < SAVE_RF_MAX; ++i) 6822 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6823 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6824 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6825 6826 phy0 = BWN_READ_2(mac, BWN_PHY0); 6827 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6828 if (phy->rev >= 3) { 6829 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6830 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6831 BWN_PHY_WRITE(mac, 0x002e, 0); 6832 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6833 switch (phy->rev) { 6834 case 4: 6835 case 6: 6836 case 7: 6837 BWN_PHY_SET(mac, 0x0478, 0x0100); 6838 BWN_PHY_SET(mac, 0x0801, 0x0040); 6839 break; 6840 case 3: 6841 case 5: 6842 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6843 break; 6844 } 6845 BWN_PHY_SET(mac, 0x0060, 0x0040); 6846 BWN_PHY_SET(mac, 0x0014, 0x0200); 6847 } 6848 /* 6849 * Calculate nrssi0 6850 */ 6851 BWN_RF_SET(mac, 0x007a, 0x0070); 6852 bwn_set_all_gains(mac, 0, 8, 0); 6853 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6854 if (phy->rev >= 2) { 6855 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6856 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6857 } 6858 BWN_RF_SET(mac, 0x007a, 0x0080); 6859 DELAY(20); 6860 6861 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6862 if (nrssi0 >= 0x0020) 6863 nrssi0 -= 0x0040; 6864 6865 /* 6866 * Calculate nrssi1 6867 */ 6868 BWN_RF_MASK(mac, 0x007a, 0x007f); 6869 if (phy->rev >= 2) 6870 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6871 6872 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6873 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6874 BWN_RF_SET(mac, 0x007a, 0x000f); 6875 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6876 if (phy->rev >= 2) { 6877 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6878 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6879 } 6880 6881 bwn_set_all_gains(mac, 3, 0, 1); 6882 if (phy->rf_rev == 8) { 6883 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6884 } else { 6885 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6886 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6887 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6888 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6889 } 6890 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6891 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6892 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6893 DELAY(20); 6894 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6895 6896 /* 6897 * Install calculated narrow RSSI values 6898 */ 6899 if (nrssi1 >= 0x0020) 6900 nrssi1 -= 0x0040; 6901 if (nrssi0 == nrssi1) 6902 pg->pg_nrssi_slope = 0x00010000; 6903 else 6904 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6905 if (nrssi0 >= -4) { 6906 pg->pg_nrssi[0] = nrssi1; 6907 pg->pg_nrssi[1] = nrssi0; 6908 } 6909 6910 /* 6911 * Restore saved RF/PHY registers 6912 */ 6913 if (phy->rev >= 3) { 6914 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6915 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6916 save_phy3[phy3_idx]); 6917 } 6918 } 6919 if (phy->rev >= 2) { 6920 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6921 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6922 } 6923 6924 for (i = 0; i < SAVE_RF_MAX; ++i) 6925 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6926 6927 BWN_WRITE_2(mac, 0x03e2, ant_div); 6928 BWN_WRITE_2(mac, 0x03e6, phy0); 6929 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6930 6931 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6932 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6933 6934 bwn_spu_workaround(mac, phy->chan); 6935 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6936 bwn_set_original_gains(mac); 6937 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6938 if (phy->rev >= 3) { 6939 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6940 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6941 save_phy3[phy3_idx]); 6942 } 6943 } 6944 6945 delta = 0x1f - pg->pg_nrssi[0]; 6946 for (i = 0; i < 64; i++) { 6947 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6948 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6949 pg->pg_nrssi_lt[i] = tmp32; 6950 } 6951 6952 bwn_nrssi_threshold(mac); 6953#undef SAVE_RF_MAX 6954#undef SAVE_PHY_COMM_MAX 6955#undef SAVE_PHY3_MAX 6956} 6957 6958static void 6959bwn_nrssi_offset(struct bwn_mac *mac) 6960{ 6961#define SAVE_RF_MAX 2 6962#define SAVE_PHY_COMM_MAX 10 6963#define SAVE_PHY6_MAX 8 6964 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6965 { 0x7a, 0x43 }; 6966 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6967 0x0001, 0x0811, 0x0812, 0x0814, 6968 0x0815, 0x005a, 0x0059, 0x0058, 6969 0x000a, 0x0003 6970 }; 6971 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6972 0x002e, 0x002f, 0x080f, 0x0810, 6973 0x0801, 0x0060, 0x0014, 0x0478 6974 }; 6975 struct bwn_phy *phy = &mac->mac_phy; 6976 int i, phy6_idx = 0; 6977 uint16_t save_rf[SAVE_RF_MAX]; 6978 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6979 uint16_t save_phy6[SAVE_PHY6_MAX]; 6980 int16_t nrssi; 6981 uint16_t saved = 0xffff; 6982 6983 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6984 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6985 for (i = 0; i < SAVE_RF_MAX; ++i) 6986 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6987 6988 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6989 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6990 BWN_PHY_SET(mac, 0x0811, 0x000c); 6991 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6992 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6993 if (phy->rev >= 6) { 6994 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6995 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6996 6997 BWN_PHY_WRITE(mac, 0x002e, 0); 6998 BWN_PHY_WRITE(mac, 0x002f, 0); 6999 BWN_PHY_WRITE(mac, 0x080f, 0); 7000 BWN_PHY_WRITE(mac, 0x0810, 0); 7001 BWN_PHY_SET(mac, 0x0478, 0x0100); 7002 BWN_PHY_SET(mac, 0x0801, 0x0040); 7003 BWN_PHY_SET(mac, 0x0060, 0x0040); 7004 BWN_PHY_SET(mac, 0x0014, 0x0200); 7005 } 7006 BWN_RF_SET(mac, 0x007a, 0x0070); 7007 BWN_RF_SET(mac, 0x007a, 0x0080); 7008 DELAY(30); 7009 7010 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7011 if (nrssi >= 0x20) 7012 nrssi -= 0x40; 7013 if (nrssi == 31) { 7014 for (i = 7; i >= 4; i--) { 7015 BWN_RF_WRITE(mac, 0x007b, i); 7016 DELAY(20); 7017 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7018 0x003f); 7019 if (nrssi >= 0x20) 7020 nrssi -= 0x40; 7021 if (nrssi < 31 && saved == 0xffff) 7022 saved = i; 7023 } 7024 if (saved == 0xffff) 7025 saved = 4; 7026 } else { 7027 BWN_RF_MASK(mac, 0x007a, 0x007f); 7028 if (phy->rev != 1) { 7029 BWN_PHY_SET(mac, 0x0814, 0x0001); 7030 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7031 } 7032 BWN_PHY_SET(mac, 0x0811, 0x000c); 7033 BWN_PHY_SET(mac, 0x0812, 0x000c); 7034 BWN_PHY_SET(mac, 0x0811, 0x0030); 7035 BWN_PHY_SET(mac, 0x0812, 0x0030); 7036 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7037 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7038 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7039 if (phy->rev == 0) 7040 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7041 else 7042 BWN_PHY_SET(mac, 0x000a, 0x2000); 7043 if (phy->rev != 1) { 7044 BWN_PHY_SET(mac, 0x0814, 0x0004); 7045 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7046 } 7047 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7048 BWN_RF_SET(mac, 0x007a, 0x000f); 7049 bwn_set_all_gains(mac, 3, 0, 1); 7050 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7051 DELAY(30); 7052 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7053 if (nrssi >= 0x20) 7054 nrssi -= 0x40; 7055 if (nrssi == -32) { 7056 for (i = 0; i < 4; i++) { 7057 BWN_RF_WRITE(mac, 0x007b, i); 7058 DELAY(20); 7059 nrssi = (int16_t)((BWN_PHY_READ(mac, 7060 0x047f) >> 8) & 0x003f); 7061 if (nrssi >= 0x20) 7062 nrssi -= 0x40; 7063 if (nrssi > -31 && saved == 0xffff) 7064 saved = i; 7065 } 7066 if (saved == 0xffff) 7067 saved = 3; 7068 } else 7069 saved = 0; 7070 } 7071 BWN_RF_WRITE(mac, 0x007b, saved); 7072 7073 /* 7074 * Restore saved RF/PHY registers 7075 */ 7076 if (phy->rev >= 6) { 7077 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7078 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7079 save_phy6[phy6_idx]); 7080 } 7081 } 7082 if (phy->rev != 1) { 7083 for (i = 3; i < 5; i++) 7084 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7085 save_phy_comm[i]); 7086 } 7087 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7088 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7089 7090 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7091 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7092 7093 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7094 BWN_PHY_SET(mac, 0x0429, 0x8000); 7095 bwn_set_original_gains(mac); 7096 if (phy->rev >= 6) { 7097 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7098 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7099 save_phy6[phy6_idx]); 7100 } 7101 } 7102 7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7105 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7106} 7107 7108static void 7109bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7110 int16_t third) 7111{ 7112 struct bwn_phy *phy = &mac->mac_phy; 7113 uint16_t i; 7114 uint16_t start = 0x08, end = 0x18; 7115 uint16_t tmp; 7116 uint16_t table; 7117 7118 if (phy->rev <= 1) { 7119 start = 0x10; 7120 end = 0x20; 7121 } 7122 7123 table = BWN_OFDMTAB_GAINX; 7124 if (phy->rev <= 1) 7125 table = BWN_OFDMTAB_GAINX_R1; 7126 for (i = 0; i < 4; i++) 7127 bwn_ofdmtab_write_2(mac, table, i, first); 7128 7129 for (i = start; i < end; i++) 7130 bwn_ofdmtab_write_2(mac, table, i, second); 7131 7132 if (third != -1) { 7133 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7134 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7135 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7136 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7137 } 7138 bwn_dummy_transmission(mac, 0, 1); 7139} 7140 7141static void 7142bwn_set_original_gains(struct bwn_mac *mac) 7143{ 7144 struct bwn_phy *phy = &mac->mac_phy; 7145 uint16_t i, tmp; 7146 uint16_t table; 7147 uint16_t start = 0x0008, end = 0x0018; 7148 7149 if (phy->rev <= 1) { 7150 start = 0x0010; 7151 end = 0x0020; 7152 } 7153 7154 table = BWN_OFDMTAB_GAINX; 7155 if (phy->rev <= 1) 7156 table = BWN_OFDMTAB_GAINX_R1; 7157 for (i = 0; i < 4; i++) { 7158 tmp = (i & 0xfffc); 7159 tmp |= (i & 0x0001) << 1; 7160 tmp |= (i & 0x0002) >> 1; 7161 7162 bwn_ofdmtab_write_2(mac, table, i, tmp); 7163 } 7164 7165 for (i = start; i < end; i++) 7166 bwn_ofdmtab_write_2(mac, table, i, i - start); 7167 7168 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7169 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7170 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7171 bwn_dummy_transmission(mac, 0, 1); 7172} 7173 7174static void 7175bwn_phy_hwpctl_init(struct bwn_mac *mac) 7176{ 7177 struct bwn_phy *phy = &mac->mac_phy; 7178 struct bwn_phy_g *pg = &phy->phy_g; 7179 struct bwn_rfatt old_rfatt, rfatt; 7180 struct bwn_bbatt old_bbatt, bbatt; 7181 struct bwn_softc *sc = mac->mac_sc; 7182 uint8_t old_txctl = 0; 7183 7184 KASSERT(phy->type == BWN_PHYTYPE_G, 7185 ("%s:%d: fail", __func__, __LINE__)); 7186 7187 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7188 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7189 return; 7190 7191 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7192 7193 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7194 7195 if (!phy->gmode) 7196 return; 7197 bwn_hwpctl_early_init(mac); 7198 if (pg->pg_curtssi == 0) { 7199 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7200 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7201 } else { 7202 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7203 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7204 old_txctl = pg->pg_txctl; 7205 7206 bbatt.att = 11; 7207 if (phy->rf_rev == 8) { 7208 rfatt.att = 15; 7209 rfatt.padmix = 1; 7210 } else { 7211 rfatt.att = 9; 7212 rfatt.padmix = 0; 7213 } 7214 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7215 } 7216 bwn_dummy_transmission(mac, 0, 1); 7217 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7218 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7219 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7220 else 7221 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7222 &old_rfatt, old_txctl); 7223 } 7224 bwn_hwpctl_init_gphy(mac); 7225 7226 /* clear TSSI */ 7227 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7228 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7230 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7231} 7232 7233static void 7234bwn_hwpctl_early_init(struct bwn_mac *mac) 7235{ 7236 struct bwn_phy *phy = &mac->mac_phy; 7237 7238 if (!bwn_has_hwpctl(mac)) { 7239 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7240 return; 7241 } 7242 7243 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7244 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7245 BWN_PHY_SET(mac, 0x047c, 0x0002); 7246 BWN_PHY_SET(mac, 0x047a, 0xf000); 7247 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7248 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7249 BWN_PHY_SET(mac, 0x005d, 0x8000); 7250 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7251 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7252 BWN_PHY_SET(mac, 0x0036, 0x0400); 7253 } else { 7254 BWN_PHY_SET(mac, 0x0036, 0x0200); 7255 BWN_PHY_SET(mac, 0x0036, 0x0400); 7256 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7257 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7258 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7259 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7260 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7261 } 7262} 7263 7264static void 7265bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7266{ 7267 struct bwn_phy *phy = &mac->mac_phy; 7268 struct bwn_phy_g *pg = &phy->phy_g; 7269 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7270 int i; 7271 uint16_t nr_written = 0, tmp, value; 7272 uint8_t rf, bb; 7273 7274 if (!bwn_has_hwpctl(mac)) { 7275 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7276 return; 7277 } 7278 7279 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7280 (pg->pg_idletssi - pg->pg_curtssi)); 7281 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7282 (pg->pg_idletssi - pg->pg_curtssi)); 7283 7284 for (i = 0; i < 32; i++) 7285 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7286 for (i = 32; i < 64; i++) 7287 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7288 for (i = 0; i < 64; i += 2) { 7289 value = (uint16_t) pg->pg_tssi2dbm[i]; 7290 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7291 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7292 } 7293 7294 for (rf = 0; rf < lo->rfatt.len; rf++) { 7295 for (bb = 0; bb < lo->bbatt.len; bb++) { 7296 if (nr_written >= 0x40) 7297 return; 7298 tmp = lo->bbatt.array[bb].att; 7299 tmp <<= 8; 7300 if (phy->rf_rev == 8) 7301 tmp |= 0x50; 7302 else 7303 tmp |= 0x40; 7304 tmp |= lo->rfatt.array[rf].att; 7305 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7306 nr_written++; 7307 } 7308 } 7309 7310 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7311 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7312 7313 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7314 BWN_PHY_SET(mac, 0x0478, 0x0800); 7315 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7316 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7317 7318 bwn_phy_g_dc_lookup_init(mac, 1); 7319 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7320} 7321 7322static void 7323bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7324{ 7325 struct bwn_softc *sc = mac->mac_sc; 7326 7327 if (spu != 0) 7328 bwn_spu_workaround(mac, channel); 7329 7330 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7331 7332 if (channel == 14) { 7333 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7334 bwn_hf_write(mac, 7335 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7336 else 7337 bwn_hf_write(mac, 7338 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7339 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7340 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7341 return; 7342 } 7343 7344 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7345 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7346} 7347 7348static uint16_t 7349bwn_phy_g_chan2freq(uint8_t channel) 7350{ 7351 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7352 7353 KASSERT(channel >= 1 && channel <= 14, 7354 ("%s:%d: fail", __func__, __LINE__)); 7355 7356 return (bwn_phy_g_rf_channels[channel - 1]); 7357} 7358 7359static void 7360bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7361 const struct bwn_rfatt *rfatt, uint8_t txctl) 7362{ 7363 struct bwn_phy *phy = &mac->mac_phy; 7364 struct bwn_phy_g *pg = &phy->phy_g; 7365 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7366 uint16_t bb, rf; 7367 uint16_t tx_bias, tx_magn; 7368 7369 bb = bbatt->att; 7370 rf = rfatt->att; 7371 tx_bias = lo->tx_bias; 7372 tx_magn = lo->tx_magn; 7373 if (tx_bias == 0xff) 7374 tx_bias = 0; 7375 7376 pg->pg_txctl = txctl; 7377 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7378 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7379 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7380 bwn_phy_g_set_bbatt(mac, bb); 7381 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7382 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7383 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7384 else { 7385 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7386 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7387 } 7388 if (BWN_HAS_TXMAG(phy)) 7389 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7390 else 7391 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7392 bwn_lo_g_adjust(mac); 7393} 7394 7395static void 7396bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7397 uint16_t bbatt) 7398{ 7399 struct bwn_phy *phy = &mac->mac_phy; 7400 7401 if (phy->analog == 0) { 7402 BWN_WRITE_2(mac, BWN_PHY0, 7403 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7404 return; 7405 } 7406 if (phy->analog > 1) { 7407 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7408 return; 7409 } 7410 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7411} 7412 7413static uint16_t 7414bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7415{ 7416 struct bwn_phy *phy = &mac->mac_phy; 7417 struct bwn_phy_g *pg = &phy->phy_g; 7418 struct bwn_softc *sc = mac->mac_sc; 7419 int max_lb_gain; 7420 uint16_t extlna; 7421 uint16_t i; 7422 7423 if (phy->gmode == 0) 7424 return (0); 7425 7426 if (BWN_HAS_LOOPBACK(phy)) { 7427 max_lb_gain = pg->pg_max_lb_gain; 7428 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7429 if (max_lb_gain >= 0x46) { 7430 extlna = 0x3000; 7431 max_lb_gain -= 0x46; 7432 } else if (max_lb_gain >= 0x3a) { 7433 extlna = 0x1000; 7434 max_lb_gain -= 0x3a; 7435 } else if (max_lb_gain >= 0x2e) { 7436 extlna = 0x2000; 7437 max_lb_gain -= 0x2e; 7438 } else { 7439 extlna = 0; 7440 max_lb_gain -= 0x10; 7441 } 7442 7443 for (i = 0; i < 16; i++) { 7444 max_lb_gain -= (i * 6); 7445 if (max_lb_gain < 6) 7446 break; 7447 } 7448 7449 if ((phy->rev < 7) || 7450 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7451 if (reg == BWN_PHY_RFOVER) { 7452 return (0x1b3); 7453 } else if (reg == BWN_PHY_RFOVERVAL) { 7454 extlna |= (i << 8); 7455 switch (lpd) { 7456 case BWN_LPD(0, 1, 1): 7457 return (0x0f92); 7458 case BWN_LPD(0, 0, 1): 7459 case BWN_LPD(1, 0, 1): 7460 return (0x0092 | extlna); 7461 case BWN_LPD(1, 0, 0): 7462 return (0x0093 | extlna); 7463 } 7464 KASSERT(0 == 1, 7465 ("%s:%d: fail", __func__, __LINE__)); 7466 } 7467 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7468 } else { 7469 if (reg == BWN_PHY_RFOVER) 7470 return (0x9b3); 7471 if (reg == BWN_PHY_RFOVERVAL) { 7472 if (extlna) 7473 extlna |= 0x8000; 7474 extlna |= (i << 8); 7475 switch (lpd) { 7476 case BWN_LPD(0, 1, 1): 7477 return (0x8f92); 7478 case BWN_LPD(0, 0, 1): 7479 return (0x8092 | extlna); 7480 case BWN_LPD(1, 0, 1): 7481 return (0x2092 | extlna); 7482 case BWN_LPD(1, 0, 0): 7483 return (0x2093 | extlna); 7484 } 7485 KASSERT(0 == 1, 7486 ("%s:%d: fail", __func__, __LINE__)); 7487 } 7488 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7489 } 7490 return (0); 7491 } 7492 7493 if ((phy->rev < 7) || 7494 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7495 if (reg == BWN_PHY_RFOVER) { 7496 return (0x1b3); 7497 } else if (reg == BWN_PHY_RFOVERVAL) { 7498 switch (lpd) { 7499 case BWN_LPD(0, 1, 1): 7500 return (0x0fb2); 7501 case BWN_LPD(0, 0, 1): 7502 return (0x00b2); 7503 case BWN_LPD(1, 0, 1): 7504 return (0x30b2); 7505 case BWN_LPD(1, 0, 0): 7506 return (0x30b3); 7507 } 7508 KASSERT(0 == 1, 7509 ("%s:%d: fail", __func__, __LINE__)); 7510 } 7511 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7512 } else { 7513 if (reg == BWN_PHY_RFOVER) { 7514 return (0x9b3); 7515 } else if (reg == BWN_PHY_RFOVERVAL) { 7516 switch (lpd) { 7517 case BWN_LPD(0, 1, 1): 7518 return (0x8fb2); 7519 case BWN_LPD(0, 0, 1): 7520 return (0x80b2); 7521 case BWN_LPD(1, 0, 1): 7522 return (0x20b2); 7523 case BWN_LPD(1, 0, 0): 7524 return (0x20b3); 7525 } 7526 KASSERT(0 == 1, 7527 ("%s:%d: fail", __func__, __LINE__)); 7528 } 7529 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7530 } 7531 return (0); 7532} 7533 7534static void 7535bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7536{ 7537 7538 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7539 return; 7540 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7541 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7542 DELAY(1000); 7543 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7544} 7545 7546static int 7547bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7548{ 7549 struct bwn_softc *sc = mac->mac_sc; 7550 struct bwn_fw *fw = &mac->mac_fw; 7551 const uint8_t rev = siba_get_revid(sc->sc_dev); 7552 const char *filename; 7553 uint32_t high; 7554 int error; 7555 7556 /* microcode */ 7557 if (rev >= 5 && rev <= 10) 7558 filename = "ucode5"; 7559 else if (rev >= 11 && rev <= 12) 7560 filename = "ucode11"; 7561 else if (rev == 13) 7562 filename = "ucode13"; 7563 else if (rev == 14) 7564 filename = "ucode14"; 7565 else if (rev >= 15) 7566 filename = "ucode15"; 7567 else { 7568 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7569 bwn_release_firmware(mac); 7570 return (EOPNOTSUPP); 7571 } 7572 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7573 if (error) { 7574 bwn_release_firmware(mac); 7575 return (error); 7576 } 7577 7578 /* PCM */ 7579 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7580 if (rev >= 5 && rev <= 10) { 7581 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7582 if (error == ENOENT) 7583 fw->no_pcmfile = 1; 7584 else if (error) { 7585 bwn_release_firmware(mac); 7586 return (error); 7587 } 7588 } else if (rev < 11) { 7589 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7590 return (EOPNOTSUPP); 7591 } 7592 7593 /* initvals */ 7594 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7595 switch (mac->mac_phy.type) { 7596 case BWN_PHYTYPE_A: 7597 if (rev < 5 || rev > 10) 7598 goto fail1; 7599 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7600 filename = "a0g1initvals5"; 7601 else 7602 filename = "a0g0initvals5"; 7603 break; 7604 case BWN_PHYTYPE_G: 7605 if (rev >= 5 && rev <= 10) 7606 filename = "b0g0initvals5"; 7607 else if (rev >= 13) 7608 filename = "b0g0initvals13"; 7609 else 7610 goto fail1; 7611 break; 7612 case BWN_PHYTYPE_LP: 7613 if (rev == 13) 7614 filename = "lp0initvals13"; 7615 else if (rev == 14) 7616 filename = "lp0initvals14"; 7617 else if (rev >= 15) 7618 filename = "lp0initvals15"; 7619 else 7620 goto fail1; 7621 break; 7622 case BWN_PHYTYPE_N: 7623 if (rev >= 11 && rev <= 12) 7624 filename = "n0initvals11"; 7625 else 7626 goto fail1; 7627 break; 7628 default: 7629 goto fail1; 7630 } 7631 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7632 if (error) { 7633 bwn_release_firmware(mac); 7634 return (error); 7635 } 7636 7637 /* bandswitch initvals */ 7638 switch (mac->mac_phy.type) { 7639 case BWN_PHYTYPE_A: 7640 if (rev >= 5 && rev <= 10) { 7641 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7642 filename = "a0g1bsinitvals5"; 7643 else 7644 filename = "a0g0bsinitvals5"; 7645 } else if (rev >= 11) 7646 filename = NULL; 7647 else 7648 goto fail1; 7649 break; 7650 case BWN_PHYTYPE_G: 7651 if (rev >= 5 && rev <= 10) 7652 filename = "b0g0bsinitvals5"; 7653 else if (rev >= 11) 7654 filename = NULL; 7655 else 7656 goto fail1; 7657 break; 7658 case BWN_PHYTYPE_LP: 7659 if (rev == 13) 7660 filename = "lp0bsinitvals13"; 7661 else if (rev == 14) 7662 filename = "lp0bsinitvals14"; 7663 else if (rev >= 15) 7664 filename = "lp0bsinitvals15"; 7665 else 7666 goto fail1; 7667 break; 7668 case BWN_PHYTYPE_N: 7669 if (rev >= 11 && rev <= 12) 7670 filename = "n0bsinitvals11"; 7671 else 7672 goto fail1; 7673 break; 7674 default: 7675 goto fail1; 7676 } 7677 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7678 if (error) { 7679 bwn_release_firmware(mac); 7680 return (error); 7681 } 7682 return (0); 7683fail1: 7684 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7685 bwn_release_firmware(mac); 7686 return (EOPNOTSUPP); 7687} 7688 7689static int 7690bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7691 const char *name, struct bwn_fwfile *bfw) 7692{ 7693 const struct bwn_fwhdr *hdr; 7694 struct bwn_softc *sc = mac->mac_sc; 7695 const struct firmware *fw; 7696 char namebuf[64]; 7697 7698 if (name == NULL) { 7699 bwn_do_release_fw(bfw); 7700 return (0); 7701 } 7702 if (bfw->filename != NULL) { 7703 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7704 return (0); 7705 bwn_do_release_fw(bfw); 7706 } 7707 7708 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7709 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7710 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7711 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7712 fw = firmware_get(namebuf); 7713 if (fw == NULL) { 7714 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7715 namebuf); 7716 return (ENOENT); 7717 } 7718 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7719 goto fail; 7720 hdr = (const struct bwn_fwhdr *)(fw->data); 7721 switch (hdr->type) { 7722 case BWN_FWTYPE_UCODE: 7723 case BWN_FWTYPE_PCM: 7724 if (be32toh(hdr->size) != 7725 (fw->datasize - sizeof(struct bwn_fwhdr))) 7726 goto fail; 7727 /* FALLTHROUGH */ 7728 case BWN_FWTYPE_IV: 7729 if (hdr->ver != 1) 7730 goto fail; 7731 break; 7732 default: 7733 goto fail; 7734 } 7735 bfw->filename = name; 7736 bfw->fw = fw; 7737 bfw->type = type; 7738 return (0); 7739fail: 7740 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7741 if (fw != NULL) 7742 firmware_put(fw, FIRMWARE_UNLOAD); 7743 return (EPROTO); 7744} 7745 7746static void 7747bwn_release_firmware(struct bwn_mac *mac) 7748{ 7749 7750 bwn_do_release_fw(&mac->mac_fw.ucode); 7751 bwn_do_release_fw(&mac->mac_fw.pcm); 7752 bwn_do_release_fw(&mac->mac_fw.initvals); 7753 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7754} 7755 7756static void 7757bwn_do_release_fw(struct bwn_fwfile *bfw) 7758{ 7759 7760 if (bfw->fw != NULL) 7761 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7762 bfw->fw = NULL; 7763 bfw->filename = NULL; 7764} 7765 7766static int 7767bwn_fw_loaducode(struct bwn_mac *mac) 7768{ 7769#define GETFWOFFSET(fwp, offset) \ 7770 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7771#define GETFWSIZE(fwp, offset) \ 7772 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7773 struct bwn_softc *sc = mac->mac_sc; 7774 const uint32_t *data; 7775 unsigned int i; 7776 uint32_t ctl; 7777 uint16_t date, fwcaps, time; 7778 int error = 0; 7779 7780 ctl = BWN_READ_4(mac, BWN_MACCTL); 7781 ctl |= BWN_MACCTL_MCODE_JMP0; 7782 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7783 __LINE__)); 7784 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7785 for (i = 0; i < 64; i++) 7786 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7787 for (i = 0; i < 4096; i += 2) 7788 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7789 7790 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7791 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7792 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7793 i++) { 7794 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7795 DELAY(10); 7796 } 7797 7798 if (mac->mac_fw.pcm.fw) { 7799 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7800 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7801 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7802 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7803 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7804 sizeof(struct bwn_fwhdr)); i++) { 7805 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7806 DELAY(10); 7807 } 7808 } 7809 7810 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7811 BWN_WRITE_4(mac, BWN_MACCTL, 7812 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7813 BWN_MACCTL_MCODE_RUN); 7814 7815 for (i = 0; i < 21; i++) { 7816 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7817 break; 7818 if (i >= 20) { 7819 device_printf(sc->sc_dev, "ucode timeout\n"); 7820 error = ENXIO; 7821 goto error; 7822 } 7823 DELAY(50000); 7824 } 7825 BWN_READ_4(mac, BWN_INTR_REASON); 7826 7827 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7828 if (mac->mac_fw.rev <= 0x128) { 7829 device_printf(sc->sc_dev, "the firmware is too old\n"); 7830 error = EOPNOTSUPP; 7831 goto error; 7832 } 7833 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7834 BWN_SHARED_UCODE_PATCH); 7835 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7836 mac->mac_fw.opensource = (date == 0xffff); 7837 if (bwn_wme != 0) 7838 mac->mac_flags |= BWN_MAC_FLAG_WME; 7839 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7840 7841 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7842 if (mac->mac_fw.opensource == 0) { 7843 device_printf(sc->sc_dev, 7844 "firmware version (rev %u patch %u date %#x time %#x)\n", 7845 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7846 if (mac->mac_fw.no_pcmfile) 7847 device_printf(sc->sc_dev, 7848 "no HW crypto acceleration due to pcm5\n"); 7849 } else { 7850 mac->mac_fw.patch = time; 7851 fwcaps = bwn_fwcaps_read(mac); 7852 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7853 device_printf(sc->sc_dev, 7854 "disabling HW crypto acceleration\n"); 7855 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7856 } 7857 if (!(fwcaps & BWN_FWCAPS_WME)) { 7858 device_printf(sc->sc_dev, "disabling WME support\n"); 7859 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7860 } 7861 } 7862 7863 if (BWN_ISOLDFMT(mac)) 7864 device_printf(sc->sc_dev, "using old firmware image\n"); 7865 7866 return (0); 7867 7868error: 7869 BWN_WRITE_4(mac, BWN_MACCTL, 7870 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7871 BWN_MACCTL_MCODE_JMP0); 7872 7873 return (error); 7874#undef GETFWSIZE 7875#undef GETFWOFFSET 7876} 7877 7878/* OpenFirmware only */ 7879static uint16_t 7880bwn_fwcaps_read(struct bwn_mac *mac) 7881{ 7882 7883 KASSERT(mac->mac_fw.opensource == 1, 7884 ("%s:%d: fail", __func__, __LINE__)); 7885 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7886} 7887 7888static int 7889bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7890 size_t count, size_t array_size) 7891{ 7892#define GET_NEXTIV16(iv) \ 7893 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7894 sizeof(uint16_t) + sizeof(uint16_t))) 7895#define GET_NEXTIV32(iv) \ 7896 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7897 sizeof(uint16_t) + sizeof(uint32_t))) 7898 struct bwn_softc *sc = mac->mac_sc; 7899 const struct bwn_fwinitvals *iv; 7900 uint16_t offset; 7901 size_t i; 7902 uint8_t bit32; 7903 7904 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7905 ("%s:%d: fail", __func__, __LINE__)); 7906 iv = ivals; 7907 for (i = 0; i < count; i++) { 7908 if (array_size < sizeof(iv->offset_size)) 7909 goto fail; 7910 array_size -= sizeof(iv->offset_size); 7911 offset = be16toh(iv->offset_size); 7912 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7913 offset &= BWN_FWINITVALS_OFFSET_MASK; 7914 if (offset >= 0x1000) 7915 goto fail; 7916 if (bit32) { 7917 if (array_size < sizeof(iv->data.d32)) 7918 goto fail; 7919 array_size -= sizeof(iv->data.d32); 7920 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7921 iv = GET_NEXTIV32(iv); 7922 } else { 7923 7924 if (array_size < sizeof(iv->data.d16)) 7925 goto fail; 7926 array_size -= sizeof(iv->data.d16); 7927 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7928 7929 iv = GET_NEXTIV16(iv); 7930 } 7931 } 7932 if (array_size != 0) 7933 goto fail; 7934 return (0); 7935fail: 7936 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7937 return (EPROTO); 7938#undef GET_NEXTIV16 7939#undef GET_NEXTIV32 7940} 7941 7942static int 7943bwn_switch_channel(struct bwn_mac *mac, int chan) 7944{ 7945 struct bwn_phy *phy = &(mac->mac_phy); 7946 struct bwn_softc *sc = mac->mac_sc; 7947 struct ifnet *ifp = sc->sc_ifp; 7948 struct ieee80211com *ic = ifp->if_l2com; 7949 uint16_t channelcookie, savedcookie; 7950 int error; 7951 7952 if (chan == 0xffff) 7953 chan = phy->get_default_chan(mac); 7954 7955 channelcookie = chan; 7956 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7957 channelcookie |= 0x100; 7958 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7959 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7960 error = phy->switch_channel(mac, chan); 7961 if (error) 7962 goto fail; 7963 7964 mac->mac_phy.chan = chan; 7965 DELAY(8000); 7966 return (0); 7967fail: 7968 device_printf(sc->sc_dev, "failed to switch channel\n"); 7969 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7970 return (error); 7971} 7972 7973static uint16_t 7974bwn_ant2phy(int antenna) 7975{ 7976 7977 switch (antenna) { 7978 case BWN_ANT0: 7979 return (BWN_TX_PHY_ANT0); 7980 case BWN_ANT1: 7981 return (BWN_TX_PHY_ANT1); 7982 case BWN_ANT2: 7983 return (BWN_TX_PHY_ANT2); 7984 case BWN_ANT3: 7985 return (BWN_TX_PHY_ANT3); 7986 case BWN_ANTAUTO: 7987 return (BWN_TX_PHY_ANT01AUTO); 7988 } 7989 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7990 return (0); 7991} 7992 7993static void 7994bwn_wme_load(struct bwn_mac *mac) 7995{ 7996 struct bwn_softc *sc = mac->mac_sc; 7997 int i; 7998 7999 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8000 ("%s:%d: fail", __func__, __LINE__)); 8001 8002 bwn_mac_suspend(mac); 8003 for (i = 0; i < N(sc->sc_wmeParams); i++) 8004 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8005 bwn_wme_shm_offsets[i]); 8006 bwn_mac_enable(mac); 8007} 8008 8009static void 8010bwn_wme_loadparams(struct bwn_mac *mac, 8011 const struct wmeParams *p, uint16_t shm_offset) 8012{ 8013#define SM(_v, _f) (((_v) << _f##_S) & _f) 8014 struct bwn_softc *sc = mac->mac_sc; 8015 uint16_t params[BWN_NR_WMEPARAMS]; 8016 int slot, tmp; 8017 unsigned int i; 8018 8019 slot = BWN_READ_2(mac, BWN_RNG) & 8020 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8021 8022 memset(¶ms, 0, sizeof(params)); 8023 8024 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8025 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8026 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8027 8028 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8029 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8030 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8031 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8032 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8033 params[BWN_WMEPARAM_BSLOTS] = slot; 8034 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8035 8036 for (i = 0; i < N(params); i++) { 8037 if (i == BWN_WMEPARAM_STATUS) { 8038 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8039 shm_offset + (i * 2)); 8040 tmp |= 0x100; 8041 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8042 tmp); 8043 } else { 8044 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8045 params[i]); 8046 } 8047 } 8048} 8049 8050static void 8051bwn_mac_write_bssid(struct bwn_mac *mac) 8052{ 8053 struct bwn_softc *sc = mac->mac_sc; 8054 uint32_t tmp; 8055 int i; 8056 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8057 8058 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8059 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8060 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8061 IEEE80211_ADDR_LEN); 8062 8063 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8064 tmp = (uint32_t) (mac_bssid[i + 0]); 8065 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8066 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8067 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8068 bwn_ram_write(mac, 0x20 + i, tmp); 8069 } 8070} 8071 8072static void 8073bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8074 const uint8_t *macaddr) 8075{ 8076 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8077 uint16_t data; 8078 8079 if (!mac) 8080 macaddr = zero; 8081 8082 offset |= 0x0020; 8083 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8084 8085 data = macaddr[0]; 8086 data |= macaddr[1] << 8; 8087 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8088 data = macaddr[2]; 8089 data |= macaddr[3] << 8; 8090 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8091 data = macaddr[4]; 8092 data |= macaddr[5] << 8; 8093 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8094} 8095 8096static void 8097bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8098 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8099{ 8100 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8101 uint8_t per_sta_keys_start = 8; 8102 8103 if (BWN_SEC_NEWAPI(mac)) 8104 per_sta_keys_start = 4; 8105 8106 KASSERT(index < mac->mac_max_nr_keys, 8107 ("%s:%d: fail", __func__, __LINE__)); 8108 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8109 ("%s:%d: fail", __func__, __LINE__)); 8110 8111 if (index >= per_sta_keys_start) 8112 bwn_key_macwrite(mac, index, NULL); 8113 if (key) 8114 memcpy(buf, key, key_len); 8115 bwn_key_write(mac, index, algorithm, buf); 8116 if (index >= per_sta_keys_start) 8117 bwn_key_macwrite(mac, index, mac_addr); 8118 8119 mac->mac_key[index].algorithm = algorithm; 8120} 8121 8122static void 8123bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8124{ 8125 struct bwn_softc *sc = mac->mac_sc; 8126 uint32_t addrtmp[2] = { 0, 0 }; 8127 uint8_t start = 8; 8128 8129 if (BWN_SEC_NEWAPI(mac)) 8130 start = 4; 8131 8132 KASSERT(index >= start, 8133 ("%s:%d: fail", __func__, __LINE__)); 8134 index -= start; 8135 8136 if (addr) { 8137 addrtmp[0] = addr[0]; 8138 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8139 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8140 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8141 addrtmp[1] = addr[4]; 8142 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8143 } 8144 8145 if (siba_get_revid(sc->sc_dev) >= 5) { 8146 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8147 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8148 } else { 8149 if (index >= 8) { 8150 bwn_shm_write_4(mac, BWN_SHARED, 8151 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8152 bwn_shm_write_2(mac, BWN_SHARED, 8153 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8154 } 8155 } 8156} 8157 8158static void 8159bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8160 const uint8_t *key) 8161{ 8162 unsigned int i; 8163 uint32_t offset; 8164 uint16_t kidx, value; 8165 8166 kidx = BWN_SEC_KEY2FW(mac, index); 8167 bwn_shm_write_2(mac, BWN_SHARED, 8168 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8169 8170 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8171 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8172 value = key[i]; 8173 value |= (uint16_t)(key[i + 1]) << 8; 8174 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8175 } 8176} 8177 8178static void 8179bwn_phy_exit(struct bwn_mac *mac) 8180{ 8181 8182 mac->mac_phy.rf_onoff(mac, 0); 8183 if (mac->mac_phy.exit != NULL) 8184 mac->mac_phy.exit(mac); 8185} 8186 8187static void 8188bwn_dma_free(struct bwn_mac *mac) 8189{ 8190 struct bwn_dma *dma; 8191 8192 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8193 return; 8194 dma = &mac->mac_method.dma; 8195 8196 bwn_dma_ringfree(&dma->rx); 8197 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8198 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8199 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8200 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8201 bwn_dma_ringfree(&dma->mcast); 8202} 8203 8204static void 8205bwn_core_stop(struct bwn_mac *mac) 8206{ 8207 struct bwn_softc *sc = mac->mac_sc; 8208 8209 BWN_ASSERT_LOCKED(sc); 8210 8211 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8212 return; 8213 8214 callout_stop(&sc->sc_rfswitch_ch); 8215 callout_stop(&sc->sc_task_ch); 8216 callout_stop(&sc->sc_watchdog_ch); 8217 sc->sc_watchdog_timer = 0; 8218 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8219 BWN_READ_4(mac, BWN_INTR_MASK); 8220 bwn_mac_suspend(mac); 8221 8222 mac->mac_status = BWN_MAC_STATUS_INITED; 8223} 8224 8225static int 8226bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8227{ 8228 struct bwn_mac *up_dev = NULL; 8229 struct bwn_mac *down_dev; 8230 struct bwn_mac *mac; 8231 int err, status; 8232 uint8_t gmode; 8233 8234 BWN_ASSERT_LOCKED(sc); 8235 8236 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8237 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8238 mac->mac_phy.supports_2ghz) { 8239 up_dev = mac; 8240 gmode = 1; 8241 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8242 mac->mac_phy.supports_5ghz) { 8243 up_dev = mac; 8244 gmode = 0; 8245 } else { 8246 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8247 return (EINVAL); 8248 } 8249 if (up_dev != NULL) 8250 break; 8251 } 8252 if (up_dev == NULL) { 8253 device_printf(sc->sc_dev, "Could not find a device\n"); 8254 return (ENODEV); 8255 } 8256 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8257 return (0); 8258 8259 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8260 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8261 8262 down_dev = sc->sc_curmac; 8263 status = down_dev->mac_status; 8264 if (status >= BWN_MAC_STATUS_STARTED) 8265 bwn_core_stop(down_dev); 8266 if (status >= BWN_MAC_STATUS_INITED) 8267 bwn_core_exit(down_dev); 8268 8269 if (down_dev != up_dev) 8270 bwn_phy_reset(down_dev); 8271 8272 up_dev->mac_phy.gmode = gmode; 8273 if (status >= BWN_MAC_STATUS_INITED) { 8274 err = bwn_core_init(up_dev); 8275 if (err) { 8276 device_printf(sc->sc_dev, 8277 "fatal: failed to initialize for %s-GHz\n", 8278 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8279 goto fail; 8280 } 8281 } 8282 if (status >= BWN_MAC_STATUS_STARTED) 8283 bwn_core_start(up_dev); 8284 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8285 sc->sc_curmac = up_dev; 8286 8287 return (0); 8288fail: 8289 sc->sc_curmac = NULL; 8290 return (err); 8291} 8292 8293static void 8294bwn_rf_turnon(struct bwn_mac *mac) 8295{ 8296 8297 bwn_mac_suspend(mac); 8298 mac->mac_phy.rf_onoff(mac, 1); 8299 mac->mac_phy.rf_on = 1; 8300 bwn_mac_enable(mac); 8301} 8302 8303static void 8304bwn_rf_turnoff(struct bwn_mac *mac) 8305{ 8306 8307 bwn_mac_suspend(mac); 8308 mac->mac_phy.rf_onoff(mac, 0); 8309 mac->mac_phy.rf_on = 0; 8310 bwn_mac_enable(mac); 8311} 8312 8313static void 8314bwn_phy_reset(struct bwn_mac *mac) 8315{ 8316 struct bwn_softc *sc = mac->mac_sc; 8317 8318 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8319 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8320 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8321 DELAY(1000); 8322 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8323 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8324 BWN_TGSLOW_PHYRESET); 8325 DELAY(1000); 8326} 8327 8328static int 8329bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8330{ 8331 struct bwn_vap *bvp = BWN_VAP(vap); 8332 struct ieee80211com *ic= vap->iv_ic; 8333 struct ifnet *ifp = ic->ic_ifp; 8334 enum ieee80211_state ostate = vap->iv_state; 8335 struct bwn_softc *sc = ifp->if_softc; 8336 struct bwn_mac *mac = sc->sc_curmac; 8337 int error; 8338 8339 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8340 ieee80211_state_name[vap->iv_state], 8341 ieee80211_state_name[nstate]); 8342 8343 error = bvp->bv_newstate(vap, nstate, arg); 8344 if (error != 0) 8345 return (error); 8346 8347 BWN_LOCK(sc); 8348 8349 bwn_led_newstate(mac, nstate); 8350 8351 /* 8352 * Clear the BSSID when we stop a STA 8353 */ 8354 if (vap->iv_opmode == IEEE80211_M_STA) { 8355 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8356 /* 8357 * Clear out the BSSID. If we reassociate to 8358 * the same AP, this will reinialize things 8359 * correctly... 8360 */ 8361 if (ic->ic_opmode == IEEE80211_M_STA && 8362 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8363 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8364 bwn_set_macaddr(mac); 8365 } 8366 } 8367 } 8368 8369 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8370 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8371 /* XXX nothing to do? */ 8372 } else if (nstate == IEEE80211_S_RUN) { 8373 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8374 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8375 bwn_set_opmode(mac); 8376 bwn_set_pretbtt(mac); 8377 bwn_spu_setdelay(mac, 0); 8378 bwn_set_macaddr(mac); 8379 } 8380 8381 BWN_UNLOCK(sc); 8382 8383 return (error); 8384} 8385 8386static void 8387bwn_set_pretbtt(struct bwn_mac *mac) 8388{ 8389 struct bwn_softc *sc = mac->mac_sc; 8390 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8391 uint16_t pretbtt; 8392 8393 if (ic->ic_opmode == IEEE80211_M_IBSS) 8394 pretbtt = 2; 8395 else 8396 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8398 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8399} 8400 8401static int 8402bwn_intr(void *arg) 8403{ 8404 struct bwn_mac *mac = arg; 8405 struct bwn_softc *sc = mac->mac_sc; 8406 uint32_t reason; 8407 8408 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8409 (sc->sc_flags & BWN_FLAG_INVALID)) 8410 return (FILTER_STRAY); 8411 8412 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8413 if (reason == 0xffffffff) /* shared IRQ */ 8414 return (FILTER_STRAY); 8415 reason &= mac->mac_intr_mask; 8416 if (reason == 0) 8417 return (FILTER_HANDLED); 8418 8419 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8420 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8421 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8422 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8423 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8424 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8425 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8426 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8427 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8428 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8429 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8430 8431 /* Disable interrupts. */ 8432 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8433 8434 mac->mac_reason_intr = reason; 8435 8436 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8437 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8438 8439 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8440 return (FILTER_HANDLED); 8441} 8442 8443static void 8444bwn_intrtask(void *arg, int npending) 8445{ 8446 struct bwn_mac *mac = arg; 8447 struct bwn_softc *sc = mac->mac_sc; 8448 struct ifnet *ifp = sc->sc_ifp; 8449 uint32_t merged = 0; 8450 int i, tx = 0, rx = 0; 8451 8452 BWN_LOCK(sc); 8453 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8454 (sc->sc_flags & BWN_FLAG_INVALID)) { 8455 BWN_UNLOCK(sc); 8456 return; 8457 } 8458 8459 for (i = 0; i < N(mac->mac_reason); i++) 8460 merged |= mac->mac_reason[i]; 8461 8462 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8463 device_printf(sc->sc_dev, "MAC trans error\n"); 8464 8465 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8466 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8467 mac->mac_phy.txerrors--; 8468 if (mac->mac_phy.txerrors == 0) { 8469 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8470 bwn_restart(mac, "PHY TX errors"); 8471 } 8472 } 8473 8474 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8475 if (merged & BWN_DMAINTR_FATALMASK) { 8476 device_printf(sc->sc_dev, 8477 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8478 mac->mac_reason[0], mac->mac_reason[1], 8479 mac->mac_reason[2], mac->mac_reason[3], 8480 mac->mac_reason[4], mac->mac_reason[5]); 8481 bwn_restart(mac, "DMA error"); 8482 BWN_UNLOCK(sc); 8483 return; 8484 } 8485 if (merged & BWN_DMAINTR_NONFATALMASK) { 8486 device_printf(sc->sc_dev, 8487 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8488 mac->mac_reason[0], mac->mac_reason[1], 8489 mac->mac_reason[2], mac->mac_reason[3], 8490 mac->mac_reason[4], mac->mac_reason[5]); 8491 } 8492 } 8493 8494 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8495 bwn_intr_ucode_debug(mac); 8496 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8497 bwn_intr_tbtt_indication(mac); 8498 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8499 bwn_intr_atim_end(mac); 8500 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8501 bwn_intr_beacon(mac); 8502 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8503 bwn_intr_pmq(mac); 8504 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8505 bwn_intr_noise(mac); 8506 8507 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8508 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8509 bwn_dma_rx(mac->mac_method.dma.rx); 8510 rx = 1; 8511 } 8512 } else 8513 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8514 8515 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8516 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8517 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8518 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8519 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8520 8521 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8522 bwn_intr_txeof(mac); 8523 tx = 1; 8524 } 8525 8526 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8527 8528 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8529 int evt = BWN_LED_EVENT_NONE; 8530 8531 if (tx && rx) { 8532 if (sc->sc_rx_rate > sc->sc_tx_rate) 8533 evt = BWN_LED_EVENT_RX; 8534 else 8535 evt = BWN_LED_EVENT_TX; 8536 } else if (tx) { 8537 evt = BWN_LED_EVENT_TX; 8538 } else if (rx) { 8539 evt = BWN_LED_EVENT_RX; 8540 } else if (rx == 0) { 8541 evt = BWN_LED_EVENT_POLL; 8542 } 8543 8544 if (evt != BWN_LED_EVENT_NONE) 8545 bwn_led_event(mac, evt); 8546 } 8547 8548 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8549 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8550 bwn_start_locked(ifp); 8551 } 8552 8553 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8554 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8555 8556 BWN_UNLOCK(sc); 8557} 8558 8559static void 8560bwn_restart(struct bwn_mac *mac, const char *msg) 8561{ 8562 struct bwn_softc *sc = mac->mac_sc; 8563 struct ifnet *ifp = sc->sc_ifp; 8564 struct ieee80211com *ic = ifp->if_l2com; 8565 8566 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8567 return; 8568 8569 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8570 ieee80211_runtask(ic, &mac->mac_hwreset); 8571} 8572 8573static void 8574bwn_intr_ucode_debug(struct bwn_mac *mac) 8575{ 8576 struct bwn_softc *sc = mac->mac_sc; 8577 uint16_t reason; 8578 8579 if (mac->mac_fw.opensource == 0) 8580 return; 8581 8582 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8583 switch (reason) { 8584 case BWN_DEBUGINTR_PANIC: 8585 bwn_handle_fwpanic(mac); 8586 break; 8587 case BWN_DEBUGINTR_DUMP_SHM: 8588 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8589 break; 8590 case BWN_DEBUGINTR_DUMP_REGS: 8591 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8592 break; 8593 case BWN_DEBUGINTR_MARKER: 8594 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8595 break; 8596 default: 8597 device_printf(sc->sc_dev, 8598 "ucode debug unknown reason: %#x\n", reason); 8599 } 8600 8601 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8602 BWN_DEBUGINTR_ACK); 8603} 8604 8605static void 8606bwn_intr_tbtt_indication(struct bwn_mac *mac) 8607{ 8608 struct bwn_softc *sc = mac->mac_sc; 8609 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8610 8611 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8612 bwn_psctl(mac, 0); 8613 if (ic->ic_opmode == IEEE80211_M_IBSS) 8614 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8615} 8616 8617static void 8618bwn_intr_atim_end(struct bwn_mac *mac) 8619{ 8620 8621 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8622 BWN_WRITE_4(mac, BWN_MACCMD, 8623 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8624 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8625 } 8626} 8627 8628static void 8629bwn_intr_beacon(struct bwn_mac *mac) 8630{ 8631 struct bwn_softc *sc = mac->mac_sc; 8632 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8633 uint32_t cmd, beacon0, beacon1; 8634 8635 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8636 ic->ic_opmode == IEEE80211_M_MBSS) 8637 return; 8638 8639 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8640 8641 cmd = BWN_READ_4(mac, BWN_MACCMD); 8642 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8643 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8644 8645 if (beacon0 && beacon1) { 8646 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8647 mac->mac_intr_mask |= BWN_INTR_BEACON; 8648 return; 8649 } 8650 8651 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8652 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8653 bwn_load_beacon0(mac); 8654 bwn_load_beacon1(mac); 8655 cmd = BWN_READ_4(mac, BWN_MACCMD); 8656 cmd |= BWN_MACCMD_BEACON0_VALID; 8657 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8658 } else { 8659 if (!beacon0) { 8660 bwn_load_beacon0(mac); 8661 cmd = BWN_READ_4(mac, BWN_MACCMD); 8662 cmd |= BWN_MACCMD_BEACON0_VALID; 8663 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8664 } else if (!beacon1) { 8665 bwn_load_beacon1(mac); 8666 cmd = BWN_READ_4(mac, BWN_MACCMD); 8667 cmd |= BWN_MACCMD_BEACON1_VALID; 8668 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8669 } 8670 } 8671} 8672 8673static void 8674bwn_intr_pmq(struct bwn_mac *mac) 8675{ 8676 uint32_t tmp; 8677 8678 while (1) { 8679 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8680 if (!(tmp & 0x00000008)) 8681 break; 8682 } 8683 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8684} 8685 8686static void 8687bwn_intr_noise(struct bwn_mac *mac) 8688{ 8689 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8690 uint16_t tmp; 8691 uint8_t noise[4]; 8692 uint8_t i, j; 8693 int32_t average; 8694 8695 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8696 return; 8697 8698 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8699 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8700 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8701 noise[3] == 0x7f) 8702 goto new; 8703 8704 KASSERT(mac->mac_noise.noi_nsamples < 8, 8705 ("%s:%d: fail", __func__, __LINE__)); 8706 i = mac->mac_noise.noi_nsamples; 8707 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8708 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8709 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8710 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8711 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8712 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8713 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8714 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8715 mac->mac_noise.noi_nsamples++; 8716 if (mac->mac_noise.noi_nsamples == 8) { 8717 average = 0; 8718 for (i = 0; i < 8; i++) { 8719 for (j = 0; j < 4; j++) 8720 average += mac->mac_noise.noi_samples[i][j]; 8721 } 8722 average = (((average / 32) * 125) + 64) / 128; 8723 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8724 if (tmp >= 8) 8725 average += 2; 8726 else 8727 average -= 25; 8728 average -= (tmp == 8) ? 72 : 48; 8729 8730 mac->mac_stats.link_noise = average; 8731 mac->mac_noise.noi_running = 0; 8732 return; 8733 } 8734new: 8735 bwn_noise_gensample(mac); 8736} 8737 8738static int 8739bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8740{ 8741 struct bwn_mac *mac = prq->prq_mac; 8742 struct bwn_softc *sc = mac->mac_sc; 8743 unsigned int i; 8744 8745 BWN_ASSERT_LOCKED(sc); 8746 8747 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8748 return (0); 8749 8750 for (i = 0; i < 5000; i++) { 8751 if (bwn_pio_rxeof(prq) == 0) 8752 break; 8753 } 8754 if (i >= 5000) 8755 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8756 return ((i > 0) ? 1 : 0); 8757} 8758 8759static void 8760bwn_dma_rx(struct bwn_dma_ring *dr) 8761{ 8762 int slot, curslot; 8763 8764 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8765 curslot = dr->get_curslot(dr); 8766 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8767 ("%s:%d: fail", __func__, __LINE__)); 8768 8769 slot = dr->dr_curslot; 8770 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8771 bwn_dma_rxeof(dr, &slot); 8772 8773 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8774 BUS_DMASYNC_PREWRITE); 8775 8776 dr->set_curslot(dr, slot); 8777 dr->dr_curslot = slot; 8778} 8779 8780static void 8781bwn_intr_txeof(struct bwn_mac *mac) 8782{ 8783 struct bwn_txstatus stat; 8784 uint32_t stat0, stat1; 8785 uint16_t tmp; 8786 8787 BWN_ASSERT_LOCKED(mac->mac_sc); 8788 8789 while (1) { 8790 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8791 if (!(stat0 & 0x00000001)) 8792 break; 8793 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8794 8795 stat.cookie = (stat0 >> 16); 8796 stat.seq = (stat1 & 0x0000ffff); 8797 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8798 tmp = (stat0 & 0x0000ffff); 8799 stat.framecnt = ((tmp & 0xf000) >> 12); 8800 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8801 stat.sreason = ((tmp & 0x001c) >> 2); 8802 stat.pm = (tmp & 0x0080) ? 1 : 0; 8803 stat.im = (tmp & 0x0040) ? 1 : 0; 8804 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8805 stat.ack = (tmp & 0x0002) ? 1 : 0; 8806 8807 bwn_handle_txeof(mac, &stat); 8808 } 8809} 8810 8811static void 8812bwn_hwreset(void *arg, int npending) 8813{ 8814 struct bwn_mac *mac = arg; 8815 struct bwn_softc *sc = mac->mac_sc; 8816 int error = 0; 8817 int prev_status; 8818 8819 BWN_LOCK(sc); 8820 8821 prev_status = mac->mac_status; 8822 if (prev_status >= BWN_MAC_STATUS_STARTED) 8823 bwn_core_stop(mac); 8824 if (prev_status >= BWN_MAC_STATUS_INITED) 8825 bwn_core_exit(mac); 8826 8827 if (prev_status >= BWN_MAC_STATUS_INITED) { 8828 error = bwn_core_init(mac); 8829 if (error) 8830 goto out; 8831 } 8832 if (prev_status >= BWN_MAC_STATUS_STARTED) 8833 bwn_core_start(mac); 8834out: 8835 if (error) { 8836 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8837 sc->sc_curmac = NULL; 8838 } 8839 BWN_UNLOCK(sc); 8840} 8841 8842static void 8843bwn_handle_fwpanic(struct bwn_mac *mac) 8844{ 8845 struct bwn_softc *sc = mac->mac_sc; 8846 uint16_t reason; 8847 8848 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8849 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8850 8851 if (reason == BWN_FWPANIC_RESTART) 8852 bwn_restart(mac, "ucode panic"); 8853} 8854 8855static void 8856bwn_load_beacon0(struct bwn_mac *mac) 8857{ 8858 8859 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8860} 8861 8862static void 8863bwn_load_beacon1(struct bwn_mac *mac) 8864{ 8865 8866 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8867} 8868 8869static uint32_t 8870bwn_jssi_read(struct bwn_mac *mac) 8871{ 8872 uint32_t val = 0; 8873 8874 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8875 val <<= 16; 8876 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8877 8878 return (val); 8879} 8880 8881static void 8882bwn_noise_gensample(struct bwn_mac *mac) 8883{ 8884 uint32_t jssi = 0x7f7f7f7f; 8885 8886 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8887 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8888 BWN_WRITE_4(mac, BWN_MACCMD, 8889 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8890} 8891 8892static int 8893bwn_dma_freeslot(struct bwn_dma_ring *dr) 8894{ 8895 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8896 8897 return (dr->dr_numslots - dr->dr_usedslot); 8898} 8899 8900static int 8901bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8902{ 8903 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8904 8905 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8906 ("%s:%d: fail", __func__, __LINE__)); 8907 if (slot == dr->dr_numslots - 1) 8908 return (0); 8909 return (slot + 1); 8910} 8911 8912static void 8913bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8914{ 8915 struct bwn_mac *mac = dr->dr_mac; 8916 struct bwn_softc *sc = mac->mac_sc; 8917 struct bwn_dma *dma = &mac->mac_method.dma; 8918 struct bwn_dmadesc_generic *desc; 8919 struct bwn_dmadesc_meta *meta; 8920 struct bwn_rxhdr4 *rxhdr; 8921 struct ifnet *ifp = sc->sc_ifp; 8922 struct mbuf *m; 8923 uint32_t macstat; 8924 int32_t tmp; 8925 int cnt = 0; 8926 uint16_t len; 8927 8928 dr->getdesc(dr, *slot, &desc, &meta); 8929 8930 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8931 m = meta->mt_m; 8932 8933 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8934 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8935 return; 8936 } 8937 8938 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8939 len = le16toh(rxhdr->frame_len); 8940 if (len <= 0) { 8941 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8942 return; 8943 } 8944 if (bwn_dma_check_redzone(dr, m)) { 8945 device_printf(sc->sc_dev, "redzone error.\n"); 8946 bwn_dma_set_redzone(dr, m); 8947 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8948 BUS_DMASYNC_PREWRITE); 8949 return; 8950 } 8951 if (len > dr->dr_rx_bufsize) { 8952 tmp = len; 8953 while (1) { 8954 dr->getdesc(dr, *slot, &desc, &meta); 8955 bwn_dma_set_redzone(dr, meta->mt_m); 8956 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8957 BUS_DMASYNC_PREWRITE); 8958 *slot = bwn_dma_nextslot(dr, *slot); 8959 cnt++; 8960 tmp -= dr->dr_rx_bufsize; 8961 if (tmp <= 0) 8962 break; 8963 } 8964 device_printf(sc->sc_dev, "too small buffer " 8965 "(len %u buffer %u dropped %d)\n", 8966 len, dr->dr_rx_bufsize, cnt); 8967 return; 8968 } 8969 macstat = le32toh(rxhdr->mac_status); 8970 if (macstat & BWN_RX_MAC_FCSERR) { 8971 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8972 device_printf(sc->sc_dev, "RX drop\n"); 8973 return; 8974 } 8975 } 8976 8977 m->m_pkthdr.rcvif = ifp; 8978 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8979 m_adj(m, dr->dr_frameoffset); 8980 8981 bwn_rxeof(dr->dr_mac, m, rxhdr); 8982} 8983 8984static void 8985bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8986{ 8987 struct bwn_dma_ring *dr; 8988 struct bwn_dmadesc_generic *desc; 8989 struct bwn_dmadesc_meta *meta; 8990 struct bwn_pio_txqueue *tq; 8991 struct bwn_pio_txpkt *tp = NULL; 8992 struct bwn_softc *sc = mac->mac_sc; 8993 struct bwn_stats *stats = &mac->mac_stats; 8994 struct ieee80211_node *ni; 8995 struct ieee80211vap *vap; 8996 int retrycnt = 0, slot; 8997 8998 BWN_ASSERT_LOCKED(mac->mac_sc); 8999 9000 if (status->im) 9001 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9002 if (status->ampdu) 9003 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9004 if (status->rtscnt) { 9005 if (status->rtscnt == 0xf) 9006 stats->rtsfail++; 9007 else 9008 stats->rts++; 9009 } 9010 9011 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9012 if (status->ack) { 9013 dr = bwn_dma_parse_cookie(mac, status, 9014 status->cookie, &slot); 9015 if (dr == NULL) { 9016 device_printf(sc->sc_dev, 9017 "failed to parse cookie\n"); 9018 return; 9019 } 9020 while (1) { 9021 dr->getdesc(dr, slot, &desc, &meta); 9022 if (meta->mt_islast) { 9023 ni = meta->mt_ni; 9024 vap = ni->ni_vap; 9025 ieee80211_ratectl_tx_complete(vap, ni, 9026 status->ack ? 9027 IEEE80211_RATECTL_TX_SUCCESS : 9028 IEEE80211_RATECTL_TX_FAILURE, 9029 &retrycnt, 0); 9030 break; 9031 } 9032 slot = bwn_dma_nextslot(dr, slot); 9033 } 9034 } 9035 bwn_dma_handle_txeof(mac, status); 9036 } else { 9037 if (status->ack) { 9038 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9039 if (tq == NULL) { 9040 device_printf(sc->sc_dev, 9041 "failed to parse cookie\n"); 9042 return; 9043 } 9044 ni = tp->tp_ni; 9045 vap = ni->ni_vap; 9046 ieee80211_ratectl_tx_complete(vap, ni, 9047 status->ack ? 9048 IEEE80211_RATECTL_TX_SUCCESS : 9049 IEEE80211_RATECTL_TX_FAILURE, 9050 &retrycnt, 0); 9051 } 9052 bwn_pio_handle_txeof(mac, status); 9053 } 9054 9055 bwn_phy_txpower_check(mac, 0); 9056} 9057 9058static uint8_t 9059bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9060{ 9061 struct bwn_mac *mac = prq->prq_mac; 9062 struct bwn_softc *sc = mac->mac_sc; 9063 struct bwn_rxhdr4 rxhdr; 9064 struct ifnet *ifp = sc->sc_ifp; 9065 struct mbuf *m; 9066 uint32_t ctl32, macstat, v32; 9067 unsigned int i, padding; 9068 uint16_t ctl16, len, totlen, v16; 9069 unsigned char *mp; 9070 char *data; 9071 9072 memset(&rxhdr, 0, sizeof(rxhdr)); 9073 9074 if (prq->prq_rev >= 8) { 9075 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9076 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9077 return (0); 9078 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9079 BWN_PIO8_RXCTL_FRAMEREADY); 9080 for (i = 0; i < 10; i++) { 9081 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9082 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9083 goto ready; 9084 DELAY(10); 9085 } 9086 } else { 9087 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9088 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9089 return (0); 9090 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9091 BWN_PIO_RXCTL_FRAMEREADY); 9092 for (i = 0; i < 10; i++) { 9093 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9094 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9095 goto ready; 9096 DELAY(10); 9097 } 9098 } 9099 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9100 return (1); 9101ready: 9102 if (prq->prq_rev >= 8) 9103 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9104 prq->prq_base + BWN_PIO8_RXDATA); 9105 else 9106 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9107 prq->prq_base + BWN_PIO_RXDATA); 9108 len = le16toh(rxhdr.frame_len); 9109 if (len > 0x700) { 9110 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9111 goto error; 9112 } 9113 if (len == 0) { 9114 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9115 goto error; 9116 } 9117 9118 macstat = le32toh(rxhdr.mac_status); 9119 if (macstat & BWN_RX_MAC_FCSERR) { 9120 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9121 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9122 goto error; 9123 } 9124 } 9125 9126 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9127 totlen = len + padding; 9128 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9129 m = m_getcl(M_NOWAIT, 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, (totlen & ~3), 9137 prq->prq_base + BWN_PIO8_RXDATA); 9138 if (totlen & 3) { 9139 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9140 data = &(mp[totlen - 1]); 9141 switch (totlen & 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, (totlen & ~1), 9154 prq->prq_base + BWN_PIO_RXDATA); 9155 if (totlen & 1) { 9156 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9157 mp[totlen - 1] = v16; 9158 } 9159 } 9160 9161 m->m_pkthdr.rcvif = ifp; 9162 m->m_len = m->m_pkthdr.len = totlen; 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_NOWAIT, 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, meta->mt_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 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 9372 9373 BWN_UNLOCK(sc); 9374 9375 ni = ieee80211_find_rxnode(ic, wh); 9376 if (ni != NULL) { 9377 type = ieee80211_input(ni, m, rssi, noise); 9378 ieee80211_free_node(ni); 9379 } else 9380 type = ieee80211_input_all(ic, m, rssi, noise); 9381 9382 BWN_LOCK(sc); 9383 return; 9384drop: 9385 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9386} 9387 9388static void 9389bwn_dma_handle_txeof(struct bwn_mac *mac, 9390 const struct bwn_txstatus *status) 9391{ 9392 struct bwn_dma *dma = &mac->mac_method.dma; 9393 struct bwn_dma_ring *dr; 9394 struct bwn_dmadesc_generic *desc; 9395 struct bwn_dmadesc_meta *meta; 9396 struct bwn_softc *sc = mac->mac_sc; 9397 struct ieee80211_node *ni; 9398 struct ifnet *ifp = sc->sc_ifp; 9399 struct mbuf *m; 9400 int slot; 9401 9402 BWN_ASSERT_LOCKED(sc); 9403 9404 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9405 if (dr == NULL) { 9406 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9407 return; 9408 } 9409 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9410 9411 while (1) { 9412 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9413 ("%s:%d: fail", __func__, __LINE__)); 9414 dr->getdesc(dr, slot, &desc, &meta); 9415 9416 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9417 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9418 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9419 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9420 9421 if (meta->mt_islast) { 9422 KASSERT(meta->mt_m != NULL, 9423 ("%s:%d: fail", __func__, __LINE__)); 9424 9425 ni = meta->mt_ni; 9426 m = meta->mt_m; 9427 if (ni != NULL) { 9428 /* 9429 * Do any tx complete callback. Note this must 9430 * be done before releasing the node reference. 9431 */ 9432 if (m->m_flags & M_TXCB) 9433 ieee80211_process_callback(ni, m, 0); 9434 ieee80211_free_node(ni); 9435 meta->mt_ni = NULL; 9436 } 9437 m_freem(m); 9438 meta->mt_m = NULL; 9439 } else { 9440 KASSERT(meta->mt_m == NULL, 9441 ("%s:%d: fail", __func__, __LINE__)); 9442 } 9443 9444 dr->dr_usedslot--; 9445 if (meta->mt_islast) { 9446 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9447 break; 9448 } 9449 slot = bwn_dma_nextslot(dr, slot); 9450 } 9451 sc->sc_watchdog_timer = 0; 9452 if (dr->dr_stop) { 9453 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9454 ("%s:%d: fail", __func__, __LINE__)); 9455 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9456 dr->dr_stop = 0; 9457 } 9458} 9459 9460static void 9461bwn_pio_handle_txeof(struct bwn_mac *mac, 9462 const struct bwn_txstatus *status) 9463{ 9464 struct bwn_pio_txqueue *tq; 9465 struct bwn_pio_txpkt *tp = NULL; 9466 struct bwn_softc *sc = mac->mac_sc; 9467 struct ifnet *ifp = sc->sc_ifp; 9468 9469 BWN_ASSERT_LOCKED(sc); 9470 9471 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9472 if (tq == NULL) 9473 return; 9474 9475 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9476 tq->tq_free++; 9477 9478 if (tp->tp_ni != NULL) { 9479 /* 9480 * Do any tx complete callback. Note this must 9481 * be done before releasing the node reference. 9482 */ 9483 if (tp->tp_m->m_flags & M_TXCB) 9484 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9485 ieee80211_free_node(tp->tp_ni); 9486 tp->tp_ni = NULL; 9487 } 9488 m_freem(tp->tp_m); 9489 tp->tp_m = NULL; 9490 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9491 9492 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9493 9494 sc->sc_watchdog_timer = 0; 9495 if (tq->tq_stop) { 9496 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9497 tq->tq_stop = 0; 9498 } 9499} 9500 9501static void 9502bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9503{ 9504 struct bwn_softc *sc = mac->mac_sc; 9505 struct bwn_phy *phy = &mac->mac_phy; 9506 struct ifnet *ifp = sc->sc_ifp; 9507 struct ieee80211com *ic = ifp->if_l2com; 9508 unsigned long now; 9509 int result; 9510 9511 BWN_GETTIME(now); 9512 9513 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9514 return; 9515 phy->nexttime = now + 2 * 1000; 9516 9517 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9518 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9519 return; 9520 9521 if (phy->recalc_txpwr != NULL) { 9522 result = phy->recalc_txpwr(mac, 9523 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9524 if (result == BWN_TXPWR_RES_DONE) 9525 return; 9526 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9527 ("%s: fail", __func__)); 9528 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9529 9530 ieee80211_runtask(ic, &mac->mac_txpower); 9531 } 9532} 9533 9534static uint16_t 9535bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9536{ 9537 9538 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9539} 9540 9541static uint32_t 9542bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9543{ 9544 9545 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9546} 9547 9548static void 9549bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9550{ 9551 9552 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9553} 9554 9555static void 9556bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9557{ 9558 9559 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9560} 9561 9562static int 9563bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9564{ 9565 9566 switch (rate) { 9567 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9568 case 12: 9569 return (BWN_OFDM_RATE_6MB); 9570 case 18: 9571 return (BWN_OFDM_RATE_9MB); 9572 case 24: 9573 return (BWN_OFDM_RATE_12MB); 9574 case 36: 9575 return (BWN_OFDM_RATE_18MB); 9576 case 48: 9577 return (BWN_OFDM_RATE_24MB); 9578 case 72: 9579 return (BWN_OFDM_RATE_36MB); 9580 case 96: 9581 return (BWN_OFDM_RATE_48MB); 9582 case 108: 9583 return (BWN_OFDM_RATE_54MB); 9584 /* CCK rates (NB: not IEEE std, device-specific) */ 9585 case 2: 9586 return (BWN_CCK_RATE_1MB); 9587 case 4: 9588 return (BWN_CCK_RATE_2MB); 9589 case 11: 9590 return (BWN_CCK_RATE_5MB); 9591 case 22: 9592 return (BWN_CCK_RATE_11MB); 9593 } 9594 9595 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9596 return (BWN_CCK_RATE_1MB); 9597} 9598 9599static int 9600bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9601 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9602{ 9603 const struct bwn_phy *phy = &mac->mac_phy; 9604 struct bwn_softc *sc = mac->mac_sc; 9605 struct ieee80211_frame *wh; 9606 struct ieee80211_frame *protwh; 9607 struct ieee80211_frame_cts *cts; 9608 struct ieee80211_frame_rts *rts; 9609 const struct ieee80211_txparam *tp; 9610 struct ieee80211vap *vap = ni->ni_vap; 9611 struct ifnet *ifp = sc->sc_ifp; 9612 struct ieee80211com *ic = ifp->if_l2com; 9613 struct mbuf *mprot; 9614 unsigned int len; 9615 uint32_t macctl = 0; 9616 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9617 uint16_t phyctl = 0; 9618 uint8_t rate, rate_fb; 9619 9620 wh = mtod(m, struct ieee80211_frame *); 9621 memset(txhdr, 0, sizeof(*txhdr)); 9622 9623 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9624 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9625 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9626 9627 /* 9628 * Find TX rate 9629 */ 9630 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9631 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9632 rate = rate_fb = tp->mgmtrate; 9633 else if (ismcast) 9634 rate = rate_fb = tp->mcastrate; 9635 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9636 rate = rate_fb = tp->ucastrate; 9637 else { 9638 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9639 rate = ni->ni_txrate; 9640 9641 if (rix > 0) 9642 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9643 IEEE80211_RATE_VAL; 9644 else 9645 rate_fb = rate; 9646 } 9647 9648 sc->sc_tx_rate = rate; 9649 9650 rate = bwn_ieeerate2hwrate(sc, rate); 9651 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9652 9653 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9654 bwn_plcp_getcck(rate); 9655 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9656 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9657 9658 if ((rate_fb == rate) || 9659 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9660 (*(u_int16_t *)wh->i_dur == htole16(0))) 9661 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9662 else 9663 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9664 m->m_pkthdr.len, rate, isshort); 9665 9666 /* XXX TX encryption */ 9667 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9668 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9669 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9670 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9671 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9672 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9673 9674 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9675 BWN_TX_EFT_FB_CCK; 9676 txhdr->chan = phy->chan; 9677 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9678 BWN_TX_PHY_ENC_CCK; 9679 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9680 rate == BWN_CCK_RATE_11MB)) 9681 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9682 9683 /* XXX TX antenna selection */ 9684 9685 switch (bwn_antenna_sanitize(mac, 0)) { 9686 case 0: 9687 phyctl |= BWN_TX_PHY_ANT01AUTO; 9688 break; 9689 case 1: 9690 phyctl |= BWN_TX_PHY_ANT0; 9691 break; 9692 case 2: 9693 phyctl |= BWN_TX_PHY_ANT1; 9694 break; 9695 case 3: 9696 phyctl |= BWN_TX_PHY_ANT2; 9697 break; 9698 case 4: 9699 phyctl |= BWN_TX_PHY_ANT3; 9700 break; 9701 default: 9702 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9703 } 9704 9705 if (!ismcast) 9706 macctl |= BWN_TX_MAC_ACK; 9707 9708 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9709 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9710 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9711 macctl |= BWN_TX_MAC_LONGFRAME; 9712 9713 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9714 /* XXX RTS rate is always 1MB??? */ 9715 rts_rate = BWN_CCK_RATE_1MB; 9716 rts_rate_fb = bwn_get_fbrate(rts_rate); 9717 9718 protdur = ieee80211_compute_duration(ic->ic_rt, 9719 m->m_pkthdr.len, rate, isshort) + 9720 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9721 9722 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9723 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9724 (txhdr->body.old.rts_frame) : 9725 (txhdr->body.new.rts_frame)); 9726 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9727 protdur); 9728 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9729 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9730 mprot->m_pkthdr.len); 9731 m_freem(mprot); 9732 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9733 len = sizeof(struct ieee80211_frame_cts); 9734 } else { 9735 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9736 (txhdr->body.old.rts_frame) : 9737 (txhdr->body.new.rts_frame)); 9738 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9739 isshort); 9740 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9741 wh->i_addr2, protdur); 9742 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9743 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9744 mprot->m_pkthdr.len); 9745 m_freem(mprot); 9746 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9747 len = sizeof(struct ieee80211_frame_rts); 9748 } 9749 len += IEEE80211_CRC_LEN; 9750 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9751 &txhdr->body.old.rts_plcp : 9752 &txhdr->body.new.rts_plcp), len, rts_rate); 9753 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9754 rts_rate_fb); 9755 9756 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9757 (&txhdr->body.old.rts_frame) : 9758 (&txhdr->body.new.rts_frame)); 9759 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9760 9761 if (BWN_ISOFDMRATE(rts_rate)) { 9762 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9763 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9764 } else { 9765 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9766 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9767 } 9768 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9769 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9770 } 9771 9772 if (BWN_ISOLDFMT(mac)) 9773 txhdr->body.old.cookie = htole16(cookie); 9774 else 9775 txhdr->body.new.cookie = htole16(cookie); 9776 9777 txhdr->macctl = htole32(macctl); 9778 txhdr->phyctl = htole16(phyctl); 9779 9780 /* 9781 * TX radio tap 9782 */ 9783 if (ieee80211_radiotap_active_vap(vap)) { 9784 sc->sc_tx_th.wt_flags = 0; 9785 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9786 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9787 if (isshort && 9788 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9789 rate == BWN_CCK_RATE_11MB)) 9790 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9791 sc->sc_tx_th.wt_rate = rate; 9792 9793 ieee80211_radiotap_tx(vap, m); 9794 } 9795 9796 return (0); 9797} 9798 9799static void 9800bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9801 const uint8_t rate) 9802{ 9803 uint32_t d, plen; 9804 uint8_t *raw = plcp->o.raw; 9805 9806 if (BWN_ISOFDMRATE(rate)) { 9807 d = bwn_plcp_getofdm(rate); 9808 KASSERT(!(octets & 0xf000), 9809 ("%s:%d: fail", __func__, __LINE__)); 9810 d |= (octets << 5); 9811 plcp->o.data = htole32(d); 9812 } else { 9813 plen = octets * 16 / rate; 9814 if ((octets * 16 % rate) > 0) { 9815 plen++; 9816 if ((rate == BWN_CCK_RATE_11MB) 9817 && ((octets * 8 % 11) < 4)) { 9818 raw[1] = 0x84; 9819 } else 9820 raw[1] = 0x04; 9821 } else 9822 raw[1] = 0x04; 9823 plcp->o.data |= htole32(plen << 16); 9824 raw[0] = bwn_plcp_getcck(rate); 9825 } 9826} 9827 9828static uint8_t 9829bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9830{ 9831 struct bwn_softc *sc = mac->mac_sc; 9832 uint8_t mask; 9833 9834 if (n == 0) 9835 return (0); 9836 if (mac->mac_phy.gmode) 9837 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9838 else 9839 mask = siba_sprom_get_ant_a(sc->sc_dev); 9840 if (!(mask & (1 << (n - 1)))) 9841 return (0); 9842 return (n); 9843} 9844 9845static uint8_t 9846bwn_get_fbrate(uint8_t bitrate) 9847{ 9848 switch (bitrate) { 9849 case BWN_CCK_RATE_1MB: 9850 return (BWN_CCK_RATE_1MB); 9851 case BWN_CCK_RATE_2MB: 9852 return (BWN_CCK_RATE_1MB); 9853 case BWN_CCK_RATE_5MB: 9854 return (BWN_CCK_RATE_2MB); 9855 case BWN_CCK_RATE_11MB: 9856 return (BWN_CCK_RATE_5MB); 9857 case BWN_OFDM_RATE_6MB: 9858 return (BWN_CCK_RATE_5MB); 9859 case BWN_OFDM_RATE_9MB: 9860 return (BWN_OFDM_RATE_6MB); 9861 case BWN_OFDM_RATE_12MB: 9862 return (BWN_OFDM_RATE_9MB); 9863 case BWN_OFDM_RATE_18MB: 9864 return (BWN_OFDM_RATE_12MB); 9865 case BWN_OFDM_RATE_24MB: 9866 return (BWN_OFDM_RATE_18MB); 9867 case BWN_OFDM_RATE_36MB: 9868 return (BWN_OFDM_RATE_24MB); 9869 case BWN_OFDM_RATE_48MB: 9870 return (BWN_OFDM_RATE_36MB); 9871 case BWN_OFDM_RATE_54MB: 9872 return (BWN_OFDM_RATE_48MB); 9873 } 9874 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9875 return (0); 9876} 9877 9878static uint32_t 9879bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9880 uint32_t ctl, const void *_data, int len) 9881{ 9882 struct bwn_softc *sc = mac->mac_sc; 9883 uint32_t value = 0; 9884 const uint8_t *data = _data; 9885 9886 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9887 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9888 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9889 9890 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9891 tq->tq_base + BWN_PIO8_TXDATA); 9892 if (len & 3) { 9893 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9894 BWN_PIO8_TXCTL_24_31); 9895 data = &(data[len - 1]); 9896 switch (len & 3) { 9897 case 3: 9898 ctl |= BWN_PIO8_TXCTL_16_23; 9899 value |= (uint32_t)(*data) << 16; 9900 data--; 9901 case 2: 9902 ctl |= BWN_PIO8_TXCTL_8_15; 9903 value |= (uint32_t)(*data) << 8; 9904 data--; 9905 case 1: 9906 value |= (uint32_t)(*data); 9907 } 9908 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9909 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9910 } 9911 9912 return (ctl); 9913} 9914 9915static void 9916bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9917 uint16_t offset, uint32_t value) 9918{ 9919 9920 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9921} 9922 9923static uint16_t 9924bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9925 uint16_t ctl, const void *_data, int len) 9926{ 9927 struct bwn_softc *sc = mac->mac_sc; 9928 const uint8_t *data = _data; 9929 9930 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9931 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9932 9933 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9934 tq->tq_base + BWN_PIO_TXDATA); 9935 if (len & 1) { 9936 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9937 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9938 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9939 } 9940 9941 return (ctl); 9942} 9943 9944static uint16_t 9945bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9946 uint16_t ctl, struct mbuf *m0) 9947{ 9948 int i, j = 0; 9949 uint16_t data = 0; 9950 const uint8_t *buf; 9951 struct mbuf *m = m0; 9952 9953 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9954 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9955 9956 for (; m != NULL; m = m->m_next) { 9957 buf = mtod(m, const uint8_t *); 9958 for (i = 0; i < m->m_len; i++) { 9959 if (!((j++) % 2)) 9960 data |= buf[i]; 9961 else { 9962 data |= (buf[i] << 8); 9963 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9964 data = 0; 9965 } 9966 } 9967 } 9968 if (m0->m_pkthdr.len % 2) { 9969 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9971 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9972 } 9973 9974 return (ctl); 9975} 9976 9977static void 9978bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9979{ 9980 9981 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9982 return; 9983 BWN_WRITE_2(mac, 0x684, 510 + time); 9984 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9985} 9986 9987static struct bwn_dma_ring * 9988bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9989{ 9990 9991 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9992 return (mac->mac_method.dma.wme[WME_AC_BE]); 9993 9994 switch (prio) { 9995 case 3: 9996 return (mac->mac_method.dma.wme[WME_AC_VO]); 9997 case 2: 9998 return (mac->mac_method.dma.wme[WME_AC_VI]); 9999 case 0: 10000 return (mac->mac_method.dma.wme[WME_AC_BE]); 10001 case 1: 10002 return (mac->mac_method.dma.wme[WME_AC_BK]); 10003 } 10004 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10005 return (NULL); 10006} 10007 10008static int 10009bwn_dma_getslot(struct bwn_dma_ring *dr) 10010{ 10011 int slot; 10012 10013 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10014 10015 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10016 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10017 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10018 10019 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10020 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10021 dr->dr_curslot = slot; 10022 dr->dr_usedslot++; 10023 10024 return (slot); 10025} 10026 10027static int 10028bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10029{ 10030 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10031 unsigned int a, b, c, d; 10032 unsigned int avg; 10033 uint32_t tmp; 10034 10035 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10036 a = tmp & 0xff; 10037 b = (tmp >> 8) & 0xff; 10038 c = (tmp >> 16) & 0xff; 10039 d = (tmp >> 24) & 0xff; 10040 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10041 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10042 return (ENOENT); 10043 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10044 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10045 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10046 10047 if (ofdm) { 10048 a = (a + 32) & 0x3f; 10049 b = (b + 32) & 0x3f; 10050 c = (c + 32) & 0x3f; 10051 d = (d + 32) & 0x3f; 10052 } 10053 10054 avg = (a + b + c + d + 2) / 4; 10055 if (ofdm) { 10056 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10057 & BWN_HF_4DB_CCK_POWERBOOST) 10058 avg = (avg >= 13) ? (avg - 13) : 0; 10059 } 10060 return (avg); 10061} 10062 10063static void 10064bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10065{ 10066 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10067 int rfatt = *rfattp; 10068 int bbatt = *bbattp; 10069 10070 while (1) { 10071 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10072 break; 10073 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10074 break; 10075 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10076 break; 10077 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10078 break; 10079 if (bbatt > lo->bbatt.max) { 10080 bbatt -= 4; 10081 rfatt += 1; 10082 continue; 10083 } 10084 if (bbatt < lo->bbatt.min) { 10085 bbatt += 4; 10086 rfatt -= 1; 10087 continue; 10088 } 10089 if (rfatt > lo->rfatt.max) { 10090 rfatt -= 1; 10091 bbatt += 4; 10092 continue; 10093 } 10094 if (rfatt < lo->rfatt.min) { 10095 rfatt += 1; 10096 bbatt -= 4; 10097 continue; 10098 } 10099 break; 10100 } 10101 10102 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10103 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10104} 10105 10106static void 10107bwn_phy_lock(struct bwn_mac *mac) 10108{ 10109 struct bwn_softc *sc = mac->mac_sc; 10110 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10111 10112 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10113 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10114 10115 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10116 bwn_psctl(mac, BWN_PS_AWAKE); 10117} 10118 10119static void 10120bwn_phy_unlock(struct bwn_mac *mac) 10121{ 10122 struct bwn_softc *sc = mac->mac_sc; 10123 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10124 10125 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10126 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10127 10128 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10129 bwn_psctl(mac, 0); 10130} 10131 10132static void 10133bwn_rf_lock(struct bwn_mac *mac) 10134{ 10135 10136 BWN_WRITE_4(mac, BWN_MACCTL, 10137 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10138 BWN_READ_4(mac, BWN_MACCTL); 10139 DELAY(10); 10140} 10141 10142static void 10143bwn_rf_unlock(struct bwn_mac *mac) 10144{ 10145 10146 BWN_READ_2(mac, BWN_PHYVER); 10147 BWN_WRITE_4(mac, BWN_MACCTL, 10148 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10149} 10150 10151static struct bwn_pio_txqueue * 10152bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10153 struct bwn_pio_txpkt **pack) 10154{ 10155 struct bwn_pio *pio = &mac->mac_method.pio; 10156 struct bwn_pio_txqueue *tq = NULL; 10157 unsigned int index; 10158 10159 switch (cookie & 0xf000) { 10160 case 0x1000: 10161 tq = &pio->wme[WME_AC_BK]; 10162 break; 10163 case 0x2000: 10164 tq = &pio->wme[WME_AC_BE]; 10165 break; 10166 case 0x3000: 10167 tq = &pio->wme[WME_AC_VI]; 10168 break; 10169 case 0x4000: 10170 tq = &pio->wme[WME_AC_VO]; 10171 break; 10172 case 0x5000: 10173 tq = &pio->mcast; 10174 break; 10175 } 10176 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10177 if (tq == NULL) 10178 return (NULL); 10179 index = (cookie & 0x0fff); 10180 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10181 if (index >= N(tq->tq_pkts)) 10182 return (NULL); 10183 *pack = &tq->tq_pkts[index]; 10184 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10185 return (tq); 10186} 10187 10188static void 10189bwn_txpwr(void *arg, int npending) 10190{ 10191 struct bwn_mac *mac = arg; 10192 struct bwn_softc *sc = mac->mac_sc; 10193 10194 BWN_LOCK(sc); 10195 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10196 mac->mac_phy.set_txpwr != NULL) 10197 mac->mac_phy.set_txpwr(mac); 10198 BWN_UNLOCK(sc); 10199} 10200 10201static void 10202bwn_task_15s(struct bwn_mac *mac) 10203{ 10204 uint16_t reg; 10205 10206 if (mac->mac_fw.opensource) { 10207 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10208 if (reg) { 10209 bwn_restart(mac, "fw watchdog"); 10210 return; 10211 } 10212 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10213 } 10214 if (mac->mac_phy.task_15s) 10215 mac->mac_phy.task_15s(mac); 10216 10217 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10218} 10219 10220static void 10221bwn_task_30s(struct bwn_mac *mac) 10222{ 10223 10224 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10225 return; 10226 mac->mac_noise.noi_running = 1; 10227 mac->mac_noise.noi_nsamples = 0; 10228 10229 bwn_noise_gensample(mac); 10230} 10231 10232static void 10233bwn_task_60s(struct bwn_mac *mac) 10234{ 10235 10236 if (mac->mac_phy.task_60s) 10237 mac->mac_phy.task_60s(mac); 10238 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10239} 10240 10241static void 10242bwn_tasks(void *arg) 10243{ 10244 struct bwn_mac *mac = arg; 10245 struct bwn_softc *sc = mac->mac_sc; 10246 10247 BWN_ASSERT_LOCKED(sc); 10248 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10249 return; 10250 10251 if (mac->mac_task_state % 4 == 0) 10252 bwn_task_60s(mac); 10253 if (mac->mac_task_state % 2 == 0) 10254 bwn_task_30s(mac); 10255 bwn_task_15s(mac); 10256 10257 mac->mac_task_state++; 10258 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10259} 10260 10261static int 10262bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10263{ 10264 struct bwn_softc *sc = mac->mac_sc; 10265 10266 KASSERT(a == 0, ("not support APHY\n")); 10267 10268 switch (plcp->o.raw[0] & 0xf) { 10269 case 0xb: 10270 return (BWN_OFDM_RATE_6MB); 10271 case 0xf: 10272 return (BWN_OFDM_RATE_9MB); 10273 case 0xa: 10274 return (BWN_OFDM_RATE_12MB); 10275 case 0xe: 10276 return (BWN_OFDM_RATE_18MB); 10277 case 0x9: 10278 return (BWN_OFDM_RATE_24MB); 10279 case 0xd: 10280 return (BWN_OFDM_RATE_36MB); 10281 case 0x8: 10282 return (BWN_OFDM_RATE_48MB); 10283 case 0xc: 10284 return (BWN_OFDM_RATE_54MB); 10285 } 10286 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10287 plcp->o.raw[0] & 0xf); 10288 return (-1); 10289} 10290 10291static int 10292bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10293{ 10294 struct bwn_softc *sc = mac->mac_sc; 10295 10296 switch (plcp->o.raw[0]) { 10297 case 0x0a: 10298 return (BWN_CCK_RATE_1MB); 10299 case 0x14: 10300 return (BWN_CCK_RATE_2MB); 10301 case 0x37: 10302 return (BWN_CCK_RATE_5MB); 10303 case 0x6e: 10304 return (BWN_CCK_RATE_11MB); 10305 } 10306 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10307 return (-1); 10308} 10309 10310static void 10311bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10312 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10313 int rssi, int noise) 10314{ 10315 struct bwn_softc *sc = mac->mac_sc; 10316 const struct ieee80211_frame_min *wh; 10317 uint64_t tsf; 10318 uint16_t low_mactime_now; 10319 10320 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10321 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10322 10323 wh = mtod(m, const struct ieee80211_frame_min *); 10324 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10325 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10326 10327 bwn_tsf_read(mac, &tsf); 10328 low_mactime_now = tsf; 10329 tsf = tsf & ~0xffffULL; 10330 tsf += le16toh(rxhdr->mac_time); 10331 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10332 tsf -= 0x10000; 10333 10334 sc->sc_rx_th.wr_tsf = tsf; 10335 sc->sc_rx_th.wr_rate = rate; 10336 sc->sc_rx_th.wr_antsignal = rssi; 10337 sc->sc_rx_th.wr_antnoise = noise; 10338} 10339 10340static void 10341bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10342{ 10343 uint32_t low, high; 10344 10345 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10346 ("%s:%d: fail", __func__, __LINE__)); 10347 10348 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10349 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10350 *tsf = high; 10351 *tsf <<= 32; 10352 *tsf |= low; 10353} 10354 10355static int 10356bwn_dma_attach(struct bwn_mac *mac) 10357{ 10358 struct bwn_dma *dma = &mac->mac_method.dma; 10359 struct bwn_softc *sc = mac->mac_sc; 10360 bus_addr_t lowaddr = 0; 10361 int error; 10362 10363 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10364 return (0); 10365 10366 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10367 10368 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10369 10370 dma->dmatype = bwn_dma_gettype(mac); 10371 if (dma->dmatype == BWN_DMA_30BIT) 10372 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10373 else if (dma->dmatype == BWN_DMA_32BIT) 10374 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10375 else 10376 lowaddr = BUS_SPACE_MAXADDR; 10377 10378 /* 10379 * Create top level DMA tag 10380 */ 10381 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10382 BWN_ALIGN, 0, /* alignment, bounds */ 10383 lowaddr, /* lowaddr */ 10384 BUS_SPACE_MAXADDR, /* highaddr */ 10385 NULL, NULL, /* filter, filterarg */ 10386 BUS_SPACE_MAXSIZE, /* maxsize */ 10387 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10388 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10389 0, /* flags */ 10390 NULL, NULL, /* lockfunc, lockarg */ 10391 &dma->parent_dtag); 10392 if (error) { 10393 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10394 return (error); 10395 } 10396 10397 /* 10398 * Create TX/RX mbuf DMA tag 10399 */ 10400 error = bus_dma_tag_create(dma->parent_dtag, 10401 1, 10402 0, 10403 BUS_SPACE_MAXADDR, 10404 BUS_SPACE_MAXADDR, 10405 NULL, NULL, 10406 MCLBYTES, 10407 1, 10408 BUS_SPACE_MAXSIZE_32BIT, 10409 0, 10410 NULL, NULL, 10411 &dma->rxbuf_dtag); 10412 if (error) { 10413 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10414 goto fail0; 10415 } 10416 error = bus_dma_tag_create(dma->parent_dtag, 10417 1, 10418 0, 10419 BUS_SPACE_MAXADDR, 10420 BUS_SPACE_MAXADDR, 10421 NULL, NULL, 10422 MCLBYTES, 10423 1, 10424 BUS_SPACE_MAXSIZE_32BIT, 10425 0, 10426 NULL, NULL, 10427 &dma->txbuf_dtag); 10428 if (error) { 10429 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10430 goto fail1; 10431 } 10432 10433 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10434 if (!dma->wme[WME_AC_BK]) 10435 goto fail2; 10436 10437 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10438 if (!dma->wme[WME_AC_BE]) 10439 goto fail3; 10440 10441 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10442 if (!dma->wme[WME_AC_VI]) 10443 goto fail4; 10444 10445 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10446 if (!dma->wme[WME_AC_VO]) 10447 goto fail5; 10448 10449 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10450 if (!dma->mcast) 10451 goto fail6; 10452 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10453 if (!dma->rx) 10454 goto fail7; 10455 10456 return (error); 10457 10458fail7: bwn_dma_ringfree(&dma->mcast); 10459fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10460fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10461fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10462fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10463fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10464fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10465fail0: bus_dma_tag_destroy(dma->parent_dtag); 10466 return (error); 10467} 10468 10469static struct bwn_dma_ring * 10470bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10471 uint16_t cookie, int *slot) 10472{ 10473 struct bwn_dma *dma = &mac->mac_method.dma; 10474 struct bwn_dma_ring *dr; 10475 struct bwn_softc *sc = mac->mac_sc; 10476 10477 BWN_ASSERT_LOCKED(mac->mac_sc); 10478 10479 switch (cookie & 0xf000) { 10480 case 0x1000: 10481 dr = dma->wme[WME_AC_BK]; 10482 break; 10483 case 0x2000: 10484 dr = dma->wme[WME_AC_BE]; 10485 break; 10486 case 0x3000: 10487 dr = dma->wme[WME_AC_VI]; 10488 break; 10489 case 0x4000: 10490 dr = dma->wme[WME_AC_VO]; 10491 break; 10492 case 0x5000: 10493 dr = dma->mcast; 10494 break; 10495 default: 10496 dr = NULL; 10497 KASSERT(0 == 1, 10498 ("invalid cookie value %d", cookie & 0xf000)); 10499 } 10500 *slot = (cookie & 0x0fff); 10501 if (*slot < 0 || *slot >= dr->dr_numslots) { 10502 /* 10503 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10504 * that it occurs events which have same H/W sequence numbers. 10505 * When it's occurred just prints a WARNING msgs and ignores. 10506 */ 10507 KASSERT(status->seq == dma->lastseq, 10508 ("%s:%d: fail", __func__, __LINE__)); 10509 device_printf(sc->sc_dev, 10510 "out of slot ranges (0 < %d < %d)\n", *slot, 10511 dr->dr_numslots); 10512 return (NULL); 10513 } 10514 dma->lastseq = status->seq; 10515 return (dr); 10516} 10517 10518static void 10519bwn_dma_stop(struct bwn_mac *mac) 10520{ 10521 struct bwn_dma *dma; 10522 10523 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10524 return; 10525 dma = &mac->mac_method.dma; 10526 10527 bwn_dma_ringstop(&dma->rx); 10528 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10529 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10530 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10531 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10532 bwn_dma_ringstop(&dma->mcast); 10533} 10534 10535static void 10536bwn_dma_ringstop(struct bwn_dma_ring **dr) 10537{ 10538 10539 if (dr == NULL) 10540 return; 10541 10542 bwn_dma_cleanup(*dr); 10543} 10544 10545static void 10546bwn_pio_stop(struct bwn_mac *mac) 10547{ 10548 struct bwn_pio *pio; 10549 10550 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10551 return; 10552 pio = &mac->mac_method.pio; 10553 10554 bwn_destroy_queue_tx(&pio->mcast); 10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10557 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10558 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10559} 10560 10561static void 10562bwn_led_attach(struct bwn_mac *mac) 10563{ 10564 struct bwn_softc *sc = mac->mac_sc; 10565 const uint8_t *led_act = NULL; 10566 uint16_t val[BWN_LED_MAX]; 10567 int i; 10568 10569 sc->sc_led_idle = (2350 * hz) / 1000; 10570 sc->sc_led_blink = 1; 10571 10572 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10573 if (siba_get_pci_subvendor(sc->sc_dev) == 10574 bwn_vendor_led_act[i].vid) { 10575 led_act = bwn_vendor_led_act[i].led_act; 10576 break; 10577 } 10578 } 10579 if (led_act == NULL) 10580 led_act = bwn_default_led_act; 10581 10582 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10583 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10584 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10585 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10586 10587 for (i = 0; i < BWN_LED_MAX; ++i) { 10588 struct bwn_led *led = &sc->sc_leds[i]; 10589 10590 if (val[i] == 0xff) { 10591 led->led_act = led_act[i]; 10592 } else { 10593 if (val[i] & BWN_LED_ACT_LOW) 10594 led->led_flags |= BWN_LED_F_ACTLOW; 10595 led->led_act = val[i] & BWN_LED_ACT_MASK; 10596 } 10597 led->led_mask = (1 << i); 10598 10599 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10600 led->led_act == BWN_LED_ACT_BLINK_POLL || 10601 led->led_act == BWN_LED_ACT_BLINK) { 10602 led->led_flags |= BWN_LED_F_BLINK; 10603 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10604 led->led_flags |= BWN_LED_F_POLLABLE; 10605 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10606 led->led_flags |= BWN_LED_F_SLOW; 10607 10608 if (sc->sc_blink_led == NULL) { 10609 sc->sc_blink_led = led; 10610 if (led->led_flags & BWN_LED_F_SLOW) 10611 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10612 } 10613 } 10614 10615 DPRINTF(sc, BWN_DEBUG_LED, 10616 "%dth led, act %d, lowact %d\n", i, 10617 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10618 } 10619 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10620} 10621 10622static __inline uint16_t 10623bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10624{ 10625 10626 if (led->led_flags & BWN_LED_F_ACTLOW) 10627 on = !on; 10628 if (on) 10629 val |= led->led_mask; 10630 else 10631 val &= ~led->led_mask; 10632 return val; 10633} 10634 10635static void 10636bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10637{ 10638 struct bwn_softc *sc = mac->mac_sc; 10639 struct ifnet *ifp = sc->sc_ifp; 10640 struct ieee80211com *ic = ifp->if_l2com; 10641 uint16_t val; 10642 int i; 10643 10644 if (nstate == IEEE80211_S_INIT) { 10645 callout_stop(&sc->sc_led_blink_ch); 10646 sc->sc_led_blinking = 0; 10647 } 10648 10649 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10650 return; 10651 10652 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10653 for (i = 0; i < BWN_LED_MAX; ++i) { 10654 struct bwn_led *led = &sc->sc_leds[i]; 10655 int on; 10656 10657 if (led->led_act == BWN_LED_ACT_UNKN || 10658 led->led_act == BWN_LED_ACT_NULL) 10659 continue; 10660 10661 if ((led->led_flags & BWN_LED_F_BLINK) && 10662 nstate != IEEE80211_S_INIT) 10663 continue; 10664 10665 switch (led->led_act) { 10666 case BWN_LED_ACT_ON: /* Always on */ 10667 on = 1; 10668 break; 10669 case BWN_LED_ACT_OFF: /* Always off */ 10670 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10671 on = 0; 10672 break; 10673 default: 10674 on = 1; 10675 switch (nstate) { 10676 case IEEE80211_S_INIT: 10677 on = 0; 10678 break; 10679 case IEEE80211_S_RUN: 10680 if (led->led_act == BWN_LED_ACT_11G && 10681 ic->ic_curmode != IEEE80211_MODE_11G) 10682 on = 0; 10683 break; 10684 default: 10685 if (led->led_act == BWN_LED_ACT_ASSOC) 10686 on = 0; 10687 break; 10688 } 10689 break; 10690 } 10691 10692 val = bwn_led_onoff(led, val, on); 10693 } 10694 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10695} 10696 10697static void 10698bwn_led_event(struct bwn_mac *mac, int event) 10699{ 10700 struct bwn_softc *sc = mac->mac_sc; 10701 struct bwn_led *led = sc->sc_blink_led; 10702 int rate; 10703 10704 if (event == BWN_LED_EVENT_POLL) { 10705 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10706 return; 10707 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10708 return; 10709 } 10710 10711 sc->sc_led_ticks = ticks; 10712 if (sc->sc_led_blinking) 10713 return; 10714 10715 switch (event) { 10716 case BWN_LED_EVENT_RX: 10717 rate = sc->sc_rx_rate; 10718 break; 10719 case BWN_LED_EVENT_TX: 10720 rate = sc->sc_tx_rate; 10721 break; 10722 case BWN_LED_EVENT_POLL: 10723 rate = 0; 10724 break; 10725 default: 10726 panic("unknown LED event %d\n", event); 10727 break; 10728 } 10729 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10730 bwn_led_duration[rate].off_dur); 10731} 10732 10733static void 10734bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10735{ 10736 struct bwn_softc *sc = mac->mac_sc; 10737 struct bwn_led *led = sc->sc_blink_led; 10738 uint16_t val; 10739 10740 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10741 val = bwn_led_onoff(led, val, 1); 10742 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10743 10744 if (led->led_flags & BWN_LED_F_SLOW) { 10745 BWN_LED_SLOWDOWN(on_dur); 10746 BWN_LED_SLOWDOWN(off_dur); 10747 } 10748 10749 sc->sc_led_blinking = 1; 10750 sc->sc_led_blink_offdur = off_dur; 10751 10752 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10753} 10754 10755static void 10756bwn_led_blink_next(void *arg) 10757{ 10758 struct bwn_mac *mac = arg; 10759 struct bwn_softc *sc = mac->mac_sc; 10760 uint16_t val; 10761 10762 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10763 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10764 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10765 10766 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10767 bwn_led_blink_end, mac); 10768} 10769 10770static void 10771bwn_led_blink_end(void *arg) 10772{ 10773 struct bwn_mac *mac = arg; 10774 struct bwn_softc *sc = mac->mac_sc; 10775 10776 sc->sc_led_blinking = 0; 10777} 10778 10779static int 10780bwn_suspend(device_t dev) 10781{ 10782 struct bwn_softc *sc = device_get_softc(dev); 10783 10784 bwn_stop(sc, 1); 10785 return (0); 10786} 10787 10788static int 10789bwn_resume(device_t dev) 10790{ 10791 struct bwn_softc *sc = device_get_softc(dev); 10792 struct ifnet *ifp = sc->sc_ifp; 10793 10794 if (ifp->if_flags & IFF_UP) 10795 bwn_init(sc); 10796 return (0); 10797} 10798 10799static void 10800bwn_rfswitch(void *arg) 10801{ 10802 struct bwn_softc *sc = arg; 10803 struct bwn_mac *mac = sc->sc_curmac; 10804 int cur = 0, prev = 0; 10805 10806 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10807 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10808 10809 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10810 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10811 & BWN_RF_HWENABLED_HI_MASK)) 10812 cur = 1; 10813 } else { 10814 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10815 & BWN_RF_HWENABLED_LO_MASK) 10816 cur = 1; 10817 } 10818 10819 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10820 prev = 1; 10821 10822 if (cur != prev) { 10823 if (cur) 10824 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10825 else 10826 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10827 10828 device_printf(sc->sc_dev, 10829 "status of RF switch is changed to %s\n", 10830 cur ? "ON" : "OFF"); 10831 if (cur != mac->mac_phy.rf_on) { 10832 if (cur) 10833 bwn_rf_turnon(mac); 10834 else 10835 bwn_rf_turnoff(mac); 10836 } 10837 } 10838 10839 callout_schedule(&sc->sc_rfswitch_ch, hz); 10840} 10841 10842static void 10843bwn_phy_lp_init_pre(struct bwn_mac *mac) 10844{ 10845 struct bwn_phy *phy = &mac->mac_phy; 10846 struct bwn_phy_lp *plp = &phy->phy_lp; 10847 10848 plp->plp_antenna = BWN_ANT_DEFAULT; 10849} 10850 10851static int 10852bwn_phy_lp_init(struct bwn_mac *mac) 10853{ 10854 static const struct bwn_stxtable tables[] = { 10855 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10856 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10857 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10858 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10859 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10860 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10861 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10862 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10863 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10864 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10865 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10866 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10867 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10868 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10869 { 2, 11, 0x40, 0, 0x0f } 10870 }; 10871 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10872 struct bwn_softc *sc = mac->mac_sc; 10873 const struct bwn_stxtable *st; 10874 struct ifnet *ifp = sc->sc_ifp; 10875 struct ieee80211com *ic = ifp->if_l2com; 10876 int i, error; 10877 uint16_t tmp; 10878 10879 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10880 bwn_phy_lp_bbinit(mac); 10881 10882 /* initialize RF */ 10883 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10884 DELAY(1); 10885 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10886 DELAY(1); 10887 10888 if (mac->mac_phy.rf_ver == 0x2062) 10889 bwn_phy_lp_b2062_init(mac); 10890 else { 10891 bwn_phy_lp_b2063_init(mac); 10892 10893 /* synchronize stx table. */ 10894 for (i = 0; i < N(tables); i++) { 10895 st = &tables[i]; 10896 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10897 tmp >>= st->st_rfshift; 10898 tmp <<= st->st_physhift; 10899 BWN_PHY_SETMASK(mac, 10900 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10901 ~(st->st_mask << st->st_physhift), tmp); 10902 } 10903 10904 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10905 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10906 } 10907 10908 /* calibrate RC */ 10909 if (mac->mac_phy.rev >= 2) 10910 bwn_phy_lp_rxcal_r2(mac); 10911 else if (!plp->plp_rccap) { 10912 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10913 bwn_phy_lp_rccal_r12(mac); 10914 } else 10915 bwn_phy_lp_set_rccap(mac); 10916 10917 error = bwn_phy_lp_switch_channel(mac, 7); 10918 if (error) 10919 device_printf(sc->sc_dev, 10920 "failed to change channel 7 (%d)\n", error); 10921 bwn_phy_lp_txpctl_init(mac); 10922 bwn_phy_lp_calib(mac); 10923 return (0); 10924} 10925 10926static uint16_t 10927bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10928{ 10929 10930 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10931 return (BWN_READ_2(mac, BWN_PHYDATA)); 10932} 10933 10934static void 10935bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10936{ 10937 10938 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10939 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10940} 10941 10942static void 10943bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10944 uint16_t set) 10945{ 10946 10947 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10948 BWN_WRITE_2(mac, BWN_PHYDATA, 10949 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10950} 10951 10952static uint16_t 10953bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10954{ 10955 10956 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10957 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10958 reg |= 0x100; 10959 if (mac->mac_phy.rev >= 2) 10960 reg |= 0x200; 10961 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10962 return BWN_READ_2(mac, BWN_RFDATALO); 10963} 10964 10965static void 10966bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10967{ 10968 10969 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10970 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10971 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10972} 10973 10974static void 10975bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10976{ 10977 10978 if (on) { 10979 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10980 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10981 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10982 return; 10983 } 10984 10985 if (mac->mac_phy.rev >= 2) { 10986 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10987 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10988 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10989 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10990 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10991 return; 10992 } 10993 10994 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10995 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10996 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10997 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10998} 10999 11000static int 11001bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11002{ 11003 struct bwn_phy *phy = &mac->mac_phy; 11004 struct bwn_phy_lp *plp = &phy->phy_lp; 11005 int error; 11006 11007 if (phy->rf_ver == 0x2063) { 11008 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11009 if (error) 11010 return (error); 11011 } else { 11012 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11013 if (error) 11014 return (error); 11015 bwn_phy_lp_set_anafilter(mac, chan); 11016 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11017 } 11018 11019 plp->plp_chan = chan; 11020 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11021 return (0); 11022} 11023 11024static uint32_t 11025bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11026{ 11027 struct bwn_softc *sc = mac->mac_sc; 11028 struct ifnet *ifp = sc->sc_ifp; 11029 struct ieee80211com *ic = ifp->if_l2com; 11030 11031 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11032} 11033 11034static void 11035bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11036{ 11037 struct bwn_phy *phy = &mac->mac_phy; 11038 struct bwn_phy_lp *plp = &phy->phy_lp; 11039 11040 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11041 return; 11042 11043 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11044 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11045 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11046 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11047 plp->plp_antenna = antenna; 11048} 11049 11050static void 11051bwn_phy_lp_task_60s(struct bwn_mac *mac) 11052{ 11053 11054 bwn_phy_lp_calib(mac); 11055} 11056 11057static void 11058bwn_phy_lp_readsprom(struct bwn_mac *mac) 11059{ 11060 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11061 struct bwn_softc *sc = mac->mac_sc; 11062 struct ifnet *ifp = sc->sc_ifp; 11063 struct ieee80211com *ic = ifp->if_l2com; 11064 11065 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11066 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11067 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11068 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11069 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11070 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11071 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11072 return; 11073 } 11074 11075 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11076 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11077 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11078 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11079 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11080 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11081 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11082 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11083} 11084 11085static void 11086bwn_phy_lp_bbinit(struct bwn_mac *mac) 11087{ 11088 11089 bwn_phy_lp_tblinit(mac); 11090 if (mac->mac_phy.rev >= 2) 11091 bwn_phy_lp_bbinit_r2(mac); 11092 else 11093 bwn_phy_lp_bbinit_r01(mac); 11094} 11095 11096static void 11097bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11098{ 11099 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11100 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11101 struct bwn_softc *sc = mac->mac_sc; 11102 struct ifnet *ifp = sc->sc_ifp; 11103 struct ieee80211com *ic = ifp->if_l2com; 11104 11105 bwn_phy_lp_set_txgain(mac, 11106 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11107 bwn_phy_lp_set_bbmult(mac, 150); 11108} 11109 11110static void 11111bwn_phy_lp_calib(struct bwn_mac *mac) 11112{ 11113 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11114 struct bwn_softc *sc = mac->mac_sc; 11115 struct ifnet *ifp = sc->sc_ifp; 11116 struct ieee80211com *ic = ifp->if_l2com; 11117 const struct bwn_rxcompco *rc = NULL; 11118 struct bwn_txgain ogain; 11119 int i, omode, oafeovr, orf, obbmult; 11120 uint8_t mode, fc = 0; 11121 11122 if (plp->plp_chanfullcal != plp->plp_chan) { 11123 plp->plp_chanfullcal = plp->plp_chan; 11124 fc = 1; 11125 } 11126 11127 bwn_mac_suspend(mac); 11128 11129 /* BlueTooth Coexistance Override */ 11130 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11131 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11132 11133 if (mac->mac_phy.rev >= 2) 11134 bwn_phy_lp_digflt_save(mac); 11135 bwn_phy_lp_get_txpctlmode(mac); 11136 mode = plp->plp_txpctlmode; 11137 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11138 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11139 bwn_phy_lp_bugfix(mac); 11140 if (mac->mac_phy.rev >= 2 && fc == 1) { 11141 bwn_phy_lp_get_txpctlmode(mac); 11142 omode = plp->plp_txpctlmode; 11143 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11144 if (oafeovr) 11145 ogain = bwn_phy_lp_get_txgain(mac); 11146 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11147 obbmult = bwn_phy_lp_get_bbmult(mac); 11148 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11149 if (oafeovr) 11150 bwn_phy_lp_set_txgain(mac, &ogain); 11151 bwn_phy_lp_set_bbmult(mac, obbmult); 11152 bwn_phy_lp_set_txpctlmode(mac, omode); 11153 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11154 } 11155 bwn_phy_lp_set_txpctlmode(mac, mode); 11156 if (mac->mac_phy.rev >= 2) 11157 bwn_phy_lp_digflt_restore(mac); 11158 11159 /* do RX IQ Calculation; assumes that noise is true. */ 11160 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11161 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11162 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11163 rc = &bwn_rxcompco_5354[i]; 11164 } 11165 } else if (mac->mac_phy.rev >= 2) 11166 rc = &bwn_rxcompco_r2; 11167 else { 11168 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11169 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11170 rc = &bwn_rxcompco_r12[i]; 11171 } 11172 } 11173 if (rc == NULL) 11174 goto fail; 11175 11176 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11177 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11178 11179 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11180 11181 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11182 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11183 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11184 } else { 11185 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11186 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11187 } 11188 11189 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11190 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11191 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11193 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11194 bwn_phy_lp_set_deaf(mac, 0); 11195 /* XXX no checking return value? */ 11196 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11197 bwn_phy_lp_clear_deaf(mac, 0); 11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11201 11202 /* disable RX GAIN override. */ 11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11205 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11206 if (mac->mac_phy.rev >= 2) { 11207 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11208 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11209 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11210 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11211 } 11212 } else { 11213 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11214 } 11215 11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11217 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11218fail: 11219 bwn_mac_enable(mac); 11220} 11221 11222static void 11223bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11224{ 11225 11226 if (on) { 11227 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11228 return; 11229 } 11230 11231 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11232 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11233} 11234 11235static int 11236bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11237{ 11238 static const struct bwn_b206x_chan *bc = NULL; 11239 struct bwn_softc *sc = mac->mac_sc; 11240 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11241 tmp[6]; 11242 uint16_t old, scale, tmp16; 11243 int i, div; 11244 11245 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11246 if (bwn_b2063_chantable[i].bc_chan == chan) { 11247 bc = &bwn_b2063_chantable[i]; 11248 break; 11249 } 11250 } 11251 if (bc == NULL) 11252 return (EINVAL); 11253 11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11256 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11257 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11261 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11262 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11263 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11264 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11265 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11266 11267 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11268 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11269 11270 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11271 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11272 freqref = freqxtal * 3; 11273 div = (freqxtal <= 26000000 ? 1 : 2); 11274 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11275 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11276 999999) / 1000000) + 1; 11277 11278 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11279 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11280 0xfff8, timeout >> 2); 11281 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11282 0xff9f,timeout << 5); 11283 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11284 11285 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11286 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11287 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11288 11289 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11290 (timeoutref + 1)) - 1; 11291 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11292 0xf0, count >> 8); 11293 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11294 11295 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11296 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11297 while (tmp[1] >= freqref) { 11298 tmp[0]++; 11299 tmp[1] -= freqref; 11300 } 11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11302 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11303 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11305 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11306 11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11309 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11310 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11311 11312 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11313 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11314 11315 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11316 scale = 1; 11317 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11318 } else { 11319 scale = 0; 11320 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11321 } 11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11323 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11324 11325 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11326 (scale + 1); 11327 if (tmp[5] > 150) 11328 tmp[5] = 0; 11329 11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11331 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11332 11333 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11334 if (freqxtal > 26000000) 11335 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11336 else 11337 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11338 11339 if (val[0] == 45) 11340 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11341 else 11342 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11343 11344 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11345 DELAY(1); 11346 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11347 11348 /* VCO Calibration */ 11349 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11350 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11351 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11352 DELAY(1); 11353 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11354 DELAY(1); 11355 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11356 DELAY(1); 11357 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11358 DELAY(300); 11359 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11360 11361 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11362 return (0); 11363} 11364 11365static int 11366bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11367{ 11368 struct bwn_softc *sc = mac->mac_sc; 11369 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11370 const struct bwn_b206x_chan *bc = NULL; 11371 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11372 uint32_t tmp[9]; 11373 int i; 11374 11375 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11376 if (bwn_b2062_chantable[i].bc_chan == chan) { 11377 bc = &bwn_b2062_chantable[i]; 11378 break; 11379 } 11380 } 11381 11382 if (bc == NULL) 11383 return (EINVAL); 11384 11385 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11388 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11389 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11390 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11391 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11392 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11393 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11394 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11395 11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11397 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11398 bwn_phy_lp_b2062_reset_pllbias(mac); 11399 tmp[0] = freqxtal / 1000; 11400 tmp[1] = plp->plp_div * 1000; 11401 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11402 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11403 tmp[2] *= 2; 11404 tmp[3] = 48 * tmp[0]; 11405 tmp[5] = tmp[2] / tmp[3]; 11406 tmp[6] = tmp[2] % tmp[3]; 11407 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11408 tmp[4] = tmp[6] * 0x100; 11409 tmp[5] = tmp[4] / tmp[3]; 11410 tmp[6] = tmp[4] % tmp[3]; 11411 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11412 tmp[4] = tmp[6] * 0x100; 11413 tmp[5] = tmp[4] / tmp[3]; 11414 tmp[6] = tmp[4] % tmp[3]; 11415 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11416 tmp[4] = tmp[6] * 0x100; 11417 tmp[5] = tmp[4] / tmp[3]; 11418 tmp[6] = tmp[4] % tmp[3]; 11419 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11420 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11421 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11422 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11424 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11425 11426 bwn_phy_lp_b2062_vco_calib(mac); 11427 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11428 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11429 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11430 bwn_phy_lp_b2062_reset_pllbias(mac); 11431 bwn_phy_lp_b2062_vco_calib(mac); 11432 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11433 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11434 return (EIO); 11435 } 11436 } 11437 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11438 return (0); 11439} 11440 11441static void 11442bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11443{ 11444 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11445 uint16_t tmp = (channel == 14); 11446 11447 if (mac->mac_phy.rev < 2) { 11448 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11449 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11450 bwn_phy_lp_set_rccap(mac); 11451 return; 11452 } 11453 11454 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11455} 11456 11457static void 11458bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11459{ 11460 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11461 struct bwn_softc *sc = mac->mac_sc; 11462 struct ifnet *ifp = sc->sc_ifp; 11463 struct ieee80211com *ic = ifp->if_l2com; 11464 uint16_t iso, tmp[3]; 11465 11466 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11467 11468 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11469 iso = plp->plp_txisoband_m; 11470 else if (freq <= 5320) 11471 iso = plp->plp_txisoband_l; 11472 else if (freq <= 5700) 11473 iso = plp->plp_txisoband_m; 11474 else 11475 iso = plp->plp_txisoband_h; 11476 11477 tmp[0] = ((iso - 26) / 12) << 12; 11478 tmp[1] = tmp[0] + 0x1000; 11479 tmp[2] = tmp[0] + 0x2000; 11480 11481 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11482 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11483} 11484 11485static void 11486bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11487{ 11488 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11489 int i; 11490 static const uint16_t addr[] = { 11491 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11492 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11493 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11494 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11495 BWN_PHY_OFDM(0xcf), 11496 }; 11497 static const uint16_t val[] = { 11498 0xde5e, 0xe832, 0xe331, 0x4d26, 11499 0x0026, 0x1420, 0x0020, 0xfe08, 11500 0x0008, 11501 }; 11502 11503 for (i = 0; i < N(addr); i++) { 11504 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11505 BWN_PHY_WRITE(mac, addr[i], val[i]); 11506 } 11507} 11508 11509static void 11510bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11511{ 11512 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11513 struct bwn_softc *sc = mac->mac_sc; 11514 uint16_t ctl; 11515 11516 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11517 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11518 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11519 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11520 break; 11521 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11522 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11523 break; 11524 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11525 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11526 break; 11527 default: 11528 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11529 device_printf(sc->sc_dev, "unknown command mode\n"); 11530 break; 11531 } 11532} 11533 11534static void 11535bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11536{ 11537 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11538 uint16_t ctl; 11539 uint8_t old; 11540 11541 bwn_phy_lp_get_txpctlmode(mac); 11542 old = plp->plp_txpctlmode; 11543 if (old == mode) 11544 return; 11545 plp->plp_txpctlmode = mode; 11546 11547 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11548 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11549 plp->plp_tssiidx); 11550 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11551 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11552 11553 /* disable TX GAIN override */ 11554 if (mac->mac_phy.rev < 2) 11555 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11556 else { 11557 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11558 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11559 } 11560 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11561 11562 plp->plp_txpwridx = -1; 11563 } 11564 if (mac->mac_phy.rev >= 2) { 11565 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11566 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11567 else 11568 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11569 } 11570 11571 /* writes TX Power Control mode */ 11572 switch (plp->plp_txpctlmode) { 11573 case BWN_PHYLP_TXPCTL_OFF: 11574 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11575 break; 11576 case BWN_PHYLP_TXPCTL_ON_HW: 11577 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11578 break; 11579 case BWN_PHYLP_TXPCTL_ON_SW: 11580 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11581 break; 11582 default: 11583 ctl = 0; 11584 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11585 } 11586 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11587 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11588} 11589 11590static void 11591bwn_phy_lp_bugfix(struct bwn_mac *mac) 11592{ 11593 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11594 struct bwn_softc *sc = mac->mac_sc; 11595 const unsigned int size = 256; 11596 struct bwn_txgain tg; 11597 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11598 uint16_t tssinpt, tssiidx, value[2]; 11599 uint8_t mode; 11600 int8_t txpwridx; 11601 11602 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11603 M_NOWAIT | M_ZERO); 11604 if (tabs == NULL) { 11605 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11606 return; 11607 } 11608 11609 bwn_phy_lp_get_txpctlmode(mac); 11610 mode = plp->plp_txpctlmode; 11611 txpwridx = plp->plp_txpwridx; 11612 tssinpt = plp->plp_tssinpt; 11613 tssiidx = plp->plp_tssiidx; 11614 11615 bwn_tab_read_multi(mac, 11616 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11617 BWN_TAB_4(7, 0x140), size, tabs); 11618 11619 bwn_phy_lp_tblinit(mac); 11620 bwn_phy_lp_bbinit(mac); 11621 bwn_phy_lp_txpctl_init(mac); 11622 bwn_phy_lp_rf_onoff(mac, 1); 11623 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11624 11625 bwn_tab_write_multi(mac, 11626 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11627 BWN_TAB_4(7, 0x140), size, tabs); 11628 11629 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11630 plp->plp_tssinpt = tssinpt; 11631 plp->plp_tssiidx = tssiidx; 11632 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11633 if (txpwridx != -1) { 11634 /* set TX power by index */ 11635 plp->plp_txpwridx = txpwridx; 11636 bwn_phy_lp_get_txpctlmode(mac); 11637 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11638 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11639 if (mac->mac_phy.rev >= 2) { 11640 rxcomp = bwn_tab_read(mac, 11641 BWN_TAB_4(7, txpwridx + 320)); 11642 txgain = bwn_tab_read(mac, 11643 BWN_TAB_4(7, txpwridx + 192)); 11644 tg.tg_pad = (txgain >> 16) & 0xff; 11645 tg.tg_gm = txgain & 0xff; 11646 tg.tg_pga = (txgain >> 8) & 0xff; 11647 tg.tg_dac = (rxcomp >> 28) & 0xff; 11648 bwn_phy_lp_set_txgain(mac, &tg); 11649 } else { 11650 rxcomp = bwn_tab_read(mac, 11651 BWN_TAB_4(10, txpwridx + 320)); 11652 txgain = bwn_tab_read(mac, 11653 BWN_TAB_4(10, txpwridx + 192)); 11654 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11655 0xf800, (txgain >> 4) & 0x7fff); 11656 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11657 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11658 } 11659 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11660 11661 /* set TX IQCC */ 11662 value[0] = (rxcomp >> 10) & 0x3ff; 11663 value[1] = rxcomp & 0x3ff; 11664 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11665 11666 coeff = bwn_tab_read(mac, 11667 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11668 BWN_TAB_4(10, txpwridx + 448)); 11669 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11670 if (mac->mac_phy.rev >= 2) { 11671 rfpwr = bwn_tab_read(mac, 11672 BWN_TAB_4(7, txpwridx + 576)); 11673 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11674 rfpwr & 0xffff); 11675 } 11676 bwn_phy_lp_set_txgain_override(mac); 11677 } 11678 if (plp->plp_rccap) 11679 bwn_phy_lp_set_rccap(mac); 11680 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11681 bwn_phy_lp_set_txpctlmode(mac, mode); 11682 free(tabs, M_DEVBUF); 11683} 11684 11685static void 11686bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11687{ 11688 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11689 int i; 11690 static const uint16_t addr[] = { 11691 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11692 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11693 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11694 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11695 BWN_PHY_OFDM(0xcf), 11696 }; 11697 11698 for (i = 0; i < N(addr); i++) 11699 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11700} 11701 11702static void 11703bwn_phy_lp_tblinit(struct bwn_mac *mac) 11704{ 11705 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11706 11707 if (mac->mac_phy.rev < 2) { 11708 bwn_phy_lp_tblinit_r01(mac); 11709 bwn_phy_lp_tblinit_txgain(mac); 11710 bwn_phy_lp_set_gaintbl(mac, freq); 11711 return; 11712 } 11713 11714 bwn_phy_lp_tblinit_r2(mac); 11715 bwn_phy_lp_tblinit_txgain(mac); 11716} 11717 11718struct bwn_wpair { 11719 uint16_t reg; 11720 uint16_t value; 11721}; 11722 11723struct bwn_smpair { 11724 uint16_t offset; 11725 uint16_t mask; 11726 uint16_t set; 11727}; 11728 11729static void 11730bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11731{ 11732 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11733 struct bwn_softc *sc = mac->mac_sc; 11734 struct ifnet *ifp = sc->sc_ifp; 11735 struct ieee80211com *ic = ifp->if_l2com; 11736 static const struct bwn_wpair v1[] = { 11737 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11738 { BWN_PHY_AFE_CTL, 0x8800 }, 11739 { BWN_PHY_AFE_CTL_OVR, 0 }, 11740 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11741 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11742 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11743 { BWN_PHY_OFDM(0xf9), 0 }, 11744 { BWN_PHY_TR_LOOKUP_1, 0 } 11745 }; 11746 static const struct bwn_smpair v2[] = { 11747 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11748 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11749 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11750 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11751 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11752 }; 11753 static const struct bwn_smpair v3[] = { 11754 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11755 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11756 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11757 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11758 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11759 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11760 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11761 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11762 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11763 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11764 11765 }; 11766 int i; 11767 11768 for (i = 0; i < N(v1); i++) 11769 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11770 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11771 for (i = 0; i < N(v2); i++) 11772 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11773 11774 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11775 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11776 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11777 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11778 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11779 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11780 } else { 11781 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11782 } 11783 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11784 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11785 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11786 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11788 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11789 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11790 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11791 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11792 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11793 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11794 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11795 (siba_get_chiprev(sc->sc_dev) == 0)) { 11796 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11797 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11798 } else { 11799 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11800 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11801 } 11802 for (i = 0; i < N(v3); i++) 11803 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11804 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11805 (siba_get_chiprev(sc->sc_dev) == 0)) { 11806 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11807 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11808 } 11809 11810 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11811 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11813 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11814 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11815 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11816 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11817 } else 11818 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11819 11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11822 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11823 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11824 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11825 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11826 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11827 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11828 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11829 11830 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11831 (siba_get_chiprev(sc->sc_dev) == 0)) { 11832 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11833 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11834 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11835 } 11836 11837 bwn_phy_lp_digflt_save(mac); 11838} 11839 11840static void 11841bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11842{ 11843 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11844 struct bwn_softc *sc = mac->mac_sc; 11845 struct ifnet *ifp = sc->sc_ifp; 11846 struct ieee80211com *ic = ifp->if_l2com; 11847 static const struct bwn_smpair v1[] = { 11848 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11849 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11850 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11851 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11852 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11853 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11854 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11855 }; 11856 static const struct bwn_smpair v2[] = { 11857 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11858 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11859 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11860 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11861 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11862 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11863 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11864 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11865 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11866 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11867 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11868 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11869 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11870 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11871 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11872 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11873 }; 11874 static const struct bwn_smpair v3[] = { 11875 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11876 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11877 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11878 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11879 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11880 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11881 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11882 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11883 }; 11884 static const struct bwn_smpair v4[] = { 11885 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11886 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11887 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11888 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11889 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11890 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11891 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11892 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11893 }; 11894 static const struct bwn_smpair v5[] = { 11895 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11896 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11897 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11898 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11899 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11900 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11901 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11902 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11903 }; 11904 int i; 11905 uint16_t tmp, tmp2; 11906 11907 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11908 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11909 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11910 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11911 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11912 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11913 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11914 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11915 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11918 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11919 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11920 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11921 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11922 for (i = 0; i < N(v1); i++) 11923 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11924 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11925 0xff00, plp->plp_rxpwroffset); 11926 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11927 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11928 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11929 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11930 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11931 if (mac->mac_phy.rev == 0) 11932 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11933 0xffcf, 0x0010); 11934 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11935 } else { 11936 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11937 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11938 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11939 } 11940 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11941 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11942 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11943 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11944 else 11945 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11946 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11947 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11948 0xfff9, (plp->plp_bxarch << 1)); 11949 if (mac->mac_phy.rev == 1 && 11950 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11951 for (i = 0; i < N(v2); i++) 11952 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11953 v2[i].set); 11954 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11955 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11956 ((mac->mac_phy.rev == 0) && 11957 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11958 for (i = 0; i < N(v3); i++) 11959 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11960 v3[i].set); 11961 } else if (mac->mac_phy.rev == 1 || 11962 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11963 for (i = 0; i < N(v4); i++) 11964 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11965 v4[i].set); 11966 } else { 11967 for (i = 0; i < N(v5); i++) 11968 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11969 v5[i].set); 11970 } 11971 if (mac->mac_phy.rev == 1 && 11972 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11975 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11976 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11977 } 11978 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11979 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11980 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11981 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11982 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11983 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11984 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11985 } 11986 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11987 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11988 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11989 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11990 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11991 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11992 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11993 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11994 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11995 } else { 11996 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11997 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11998 } 11999 if (mac->mac_phy.rev == 1) { 12000 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12001 tmp2 = (tmp & 0x03e0) >> 5; 12002 tmp2 |= tmp2 << 5; 12003 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12004 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12005 tmp2 = (tmp & 0x1f00) >> 8; 12006 tmp2 |= tmp2 << 5; 12007 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12008 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12009 tmp2 = tmp & 0x00ff; 12010 tmp2 |= tmp << 8; 12011 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12012 } 12013} 12014 12015struct bwn_b2062_freq { 12016 uint16_t freq; 12017 uint8_t value[6]; 12018}; 12019 12020static void 12021bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12022{ 12023#define CALC_CTL7(freq, div) \ 12024 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12025#define CALC_CTL18(freq, div) \ 12026 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12027#define CALC_CTL19(freq, div) \ 12028 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12029 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12030 struct bwn_softc *sc = mac->mac_sc; 12031 struct ifnet *ifp = sc->sc_ifp; 12032 struct ieee80211com *ic = ifp->if_l2com; 12033 static const struct bwn_b2062_freq freqdata_tab[] = { 12034 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12035 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12036 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12037 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12038 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12039 { 19200, { 1, 1, 1, 1, 14, 9 } } 12040 }; 12041 static const struct bwn_wpair v1[] = { 12042 { BWN_B2062_N_TXCTL3, 0 }, 12043 { BWN_B2062_N_TXCTL4, 0 }, 12044 { BWN_B2062_N_TXCTL5, 0 }, 12045 { BWN_B2062_N_TXCTL6, 0 }, 12046 { BWN_B2062_N_PDNCTL0, 0x40 }, 12047 { BWN_B2062_N_PDNCTL0, 0 }, 12048 { BWN_B2062_N_CALIB_TS, 0x10 }, 12049 { BWN_B2062_N_CALIB_TS, 0 } 12050 }; 12051 const struct bwn_b2062_freq *f = NULL; 12052 uint32_t xtalfreq, ref; 12053 unsigned int i; 12054 12055 bwn_phy_lp_b2062_tblinit(mac); 12056 12057 for (i = 0; i < N(v1); i++) 12058 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12059 if (mac->mac_phy.rev > 0) 12060 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12061 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12062 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12063 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12064 else 12065 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12066 12067 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12068 ("%s:%d: fail", __func__, __LINE__)); 12069 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12070 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12071 12072 if (xtalfreq <= 30000000) { 12073 plp->plp_div = 1; 12074 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12075 } else { 12076 plp->plp_div = 2; 12077 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12078 } 12079 12080 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12081 CALC_CTL7(xtalfreq, plp->plp_div)); 12082 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12083 CALC_CTL18(xtalfreq, plp->plp_div)); 12084 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12085 CALC_CTL19(xtalfreq, plp->plp_div)); 12086 12087 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12088 ref &= 0xffff; 12089 for (i = 0; i < N(freqdata_tab); i++) { 12090 if (ref < freqdata_tab[i].freq) { 12091 f = &freqdata_tab[i]; 12092 break; 12093 } 12094 } 12095 if (f == NULL) 12096 f = &freqdata_tab[N(freqdata_tab) - 1]; 12097 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12098 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12099 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12100 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12101 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12102 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12103#undef CALC_CTL7 12104#undef CALC_CTL18 12105#undef CALC_CTL19 12106} 12107 12108static void 12109bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12110{ 12111 12112 bwn_phy_lp_b2063_tblinit(mac); 12113 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12114 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12115 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12116 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12117 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12119 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12120 if (mac->mac_phy.rev == 2) { 12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12123 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12124 } else { 12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12126 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12127 } 12128} 12129 12130static void 12131bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12132{ 12133 struct bwn_softc *sc = mac->mac_sc; 12134 static const struct bwn_wpair v1[] = { 12135 { BWN_B2063_RX_BB_SP8, 0x0 }, 12136 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12137 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12138 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12139 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12140 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12141 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12142 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12143 }; 12144 static const struct bwn_wpair v2[] = { 12145 { BWN_B2063_TX_BB_SP3, 0x0 }, 12146 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12147 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12148 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12149 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12150 }; 12151 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12152 int i; 12153 uint8_t tmp; 12154 12155 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12156 12157 for (i = 0; i < 2; i++) 12158 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12159 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12160 for (i = 2; i < N(v1); i++) 12161 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12162 for (i = 0; i < 10000; i++) { 12163 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12164 break; 12165 DELAY(1000); 12166 } 12167 12168 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12169 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12170 12171 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12172 12173 for (i = 0; i < N(v2); i++) 12174 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12175 if (freqxtal == 24000000) { 12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12177 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12178 } else { 12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12180 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12181 } 12182 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12183 for (i = 0; i < 10000; i++) { 12184 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12185 break; 12186 DELAY(1000); 12187 } 12188 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12189 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12190 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12191} 12192 12193static void 12194bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12195{ 12196 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12197 struct bwn_softc *sc = mac->mac_sc; 12198 struct bwn_phy_lp_iq_est ie; 12199 struct bwn_txgain tx_gains; 12200 static const uint32_t pwrtbl[21] = { 12201 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12202 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12203 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12204 0x0004c, 0x0002c, 0x0001a, 12205 }; 12206 uint32_t npwr, ipwr, sqpwr, tmp; 12207 int loopback, i, j, sum, error; 12208 uint16_t save[7]; 12209 uint8_t txo, bbmult, txpctlmode; 12210 12211 error = bwn_phy_lp_switch_channel(mac, 7); 12212 if (error) 12213 device_printf(sc->sc_dev, 12214 "failed to change channel to 7 (%d)\n", error); 12215 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12216 bbmult = bwn_phy_lp_get_bbmult(mac); 12217 if (txo) 12218 tx_gains = bwn_phy_lp_get_txgain(mac); 12219 12220 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12221 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12222 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12223 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12224 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12225 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12226 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12227 12228 bwn_phy_lp_get_txpctlmode(mac); 12229 txpctlmode = plp->plp_txpctlmode; 12230 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12231 12232 /* disable CRS */ 12233 bwn_phy_lp_set_deaf(mac, 1); 12234 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12235 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12236 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12237 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12240 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12241 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12242 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12243 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12246 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12247 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12248 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12249 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12251 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12252 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12253 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12254 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12255 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12256 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12257 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12258 12259 loopback = bwn_phy_lp_loopback(mac); 12260 if (loopback == -1) 12261 goto done; 12262 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12263 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12266 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12267 12268 tmp = 0; 12269 memset(&ie, 0, sizeof(ie)); 12270 for (i = 128; i <= 159; i++) { 12271 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12272 sum = 0; 12273 for (j = 5; j <= 25; j++) { 12274 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12275 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12276 goto done; 12277 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12278 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12279 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12280 12); 12281 sum += ((ipwr - npwr) * (ipwr - npwr)); 12282 if ((i == 128) || (sum < tmp)) { 12283 plp->plp_rccap = i; 12284 tmp = sum; 12285 } 12286 } 12287 } 12288 bwn_phy_lp_ddfs_turnoff(mac); 12289done: 12290 /* restore CRS */ 12291 bwn_phy_lp_clear_deaf(mac, 1); 12292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12293 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12294 12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12297 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12298 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12299 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12300 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12301 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12302 12303 bwn_phy_lp_set_bbmult(mac, bbmult); 12304 if (txo) 12305 bwn_phy_lp_set_txgain(mac, &tx_gains); 12306 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12307 if (plp->plp_rccap) 12308 bwn_phy_lp_set_rccap(mac); 12309} 12310 12311static void 12312bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12313{ 12314 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12315 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12316 12317 if (mac->mac_phy.rev == 1) 12318 rc_cap = MIN(rc_cap + 5, 15); 12319 12320 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12321 MAX(plp->plp_rccap - 4, 0x80)); 12322 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12323 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12324 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12325} 12326 12327static uint32_t 12328bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12329{ 12330 uint32_t i, q, r; 12331 12332 if (div == 0) 12333 return (0); 12334 12335 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12336 q <<= 1; 12337 if (r << 1 >= div) { 12338 q++; 12339 r = (r << 1) - div; 12340 } 12341 } 12342 if (r << 1 >= div) 12343 q++; 12344 return (q); 12345} 12346 12347static void 12348bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12349{ 12350 struct bwn_softc *sc = mac->mac_sc; 12351 12352 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12353 DELAY(20); 12354 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12355 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12356 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12357 } else { 12358 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12359 } 12360 DELAY(5); 12361} 12362 12363static void 12364bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12365{ 12366 12367 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12368 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12369 DELAY(200); 12370} 12371 12372static void 12373bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12374{ 12375#define FLAG_A 0x01 12376#define FLAG_G 0x02 12377 struct bwn_softc *sc = mac->mac_sc; 12378 struct ifnet *ifp = sc->sc_ifp; 12379 struct ieee80211com *ic = ifp->if_l2com; 12380 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12381 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12382 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12383 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12384 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12385 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12386 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12387 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12389 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12391 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12392 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12425 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12426 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12427 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12428 }; 12429 const struct bwn_b206x_rfinit_entry *br; 12430 unsigned int i; 12431 12432 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12433 br = &bwn_b2062_init_tab[i]; 12434 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12435 if (br->br_flags & FLAG_G) 12436 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12437 } else { 12438 if (br->br_flags & FLAG_A) 12439 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12440 } 12441 } 12442#undef FLAG_A 12443#undef FLAG_B 12444} 12445 12446static void 12447bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12448{ 12449#define FLAG_A 0x01 12450#define FLAG_G 0x02 12451 struct bwn_softc *sc = mac->mac_sc; 12452 struct ifnet *ifp = sc->sc_ifp; 12453 struct ieee80211com *ic = ifp->if_l2com; 12454 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12455 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12456 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12457 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12462 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12463 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12464 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12465 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12466 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12467 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12468 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12469 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12470 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12471 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12472 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12473 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12474 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12475 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12476 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12483 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12487 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12488 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12493 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12494 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12495 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12496 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12497 }; 12498 const struct bwn_b206x_rfinit_entry *br; 12499 unsigned int i; 12500 12501 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12502 br = &bwn_b2063_init_tab[i]; 12503 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12504 if (br->br_flags & FLAG_G) 12505 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12506 } else { 12507 if (br->br_flags & FLAG_A) 12508 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12509 } 12510 } 12511#undef FLAG_A 12512#undef FLAG_B 12513} 12514 12515static void 12516bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12517 int count, void *_data) 12518{ 12519 unsigned int i; 12520 uint32_t offset, type; 12521 uint8_t *data = _data; 12522 12523 type = BWN_TAB_GETTYPE(typenoffset); 12524 offset = BWN_TAB_GETOFFSET(typenoffset); 12525 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12526 12527 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12528 12529 for (i = 0; i < count; i++) { 12530 switch (type) { 12531 case BWN_TAB_8BIT: 12532 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12533 data++; 12534 break; 12535 case BWN_TAB_16BIT: 12536 *((uint16_t *)data) = BWN_PHY_READ(mac, 12537 BWN_PHY_TABLEDATALO); 12538 data += 2; 12539 break; 12540 case BWN_TAB_32BIT: 12541 *((uint32_t *)data) = BWN_PHY_READ(mac, 12542 BWN_PHY_TABLEDATAHI); 12543 *((uint32_t *)data) <<= 16; 12544 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12545 BWN_PHY_TABLEDATALO); 12546 data += 4; 12547 break; 12548 default: 12549 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12550 } 12551 } 12552} 12553 12554static void 12555bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12556 int count, const void *_data) 12557{ 12558 uint32_t offset, type, value; 12559 const uint8_t *data = _data; 12560 unsigned int i; 12561 12562 type = BWN_TAB_GETTYPE(typenoffset); 12563 offset = BWN_TAB_GETOFFSET(typenoffset); 12564 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12565 12566 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12567 12568 for (i = 0; i < count; i++) { 12569 switch (type) { 12570 case BWN_TAB_8BIT: 12571 value = *data; 12572 data++; 12573 KASSERT(!(value & ~0xff), 12574 ("%s:%d: fail", __func__, __LINE__)); 12575 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12576 break; 12577 case BWN_TAB_16BIT: 12578 value = *((const uint16_t *)data); 12579 data += 2; 12580 KASSERT(!(value & ~0xffff), 12581 ("%s:%d: fail", __func__, __LINE__)); 12582 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12583 break; 12584 case BWN_TAB_32BIT: 12585 value = *((const uint32_t *)data); 12586 data += 4; 12587 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12588 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12589 break; 12590 default: 12591 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12592 } 12593 } 12594} 12595 12596static struct bwn_txgain 12597bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12598{ 12599 struct bwn_txgain tg; 12600 uint16_t tmp; 12601 12602 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12603 if (mac->mac_phy.rev < 2) { 12604 tmp = BWN_PHY_READ(mac, 12605 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12606 tg.tg_gm = tmp & 0x0007; 12607 tg.tg_pga = (tmp & 0x0078) >> 3; 12608 tg.tg_pad = (tmp & 0x780) >> 7; 12609 return (tg); 12610 } 12611 12612 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12613 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12614 tg.tg_gm = tmp & 0xff; 12615 tg.tg_pga = (tmp >> 8) & 0xff; 12616 return (tg); 12617} 12618 12619static uint8_t 12620bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12621{ 12622 12623 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12624} 12625 12626static void 12627bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12628{ 12629 uint16_t pa; 12630 12631 if (mac->mac_phy.rev < 2) { 12632 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12633 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12634 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12635 bwn_phy_lp_set_txgain_override(mac); 12636 return; 12637 } 12638 12639 pa = bwn_phy_lp_get_pa_gain(mac); 12640 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12641 (tg->tg_pga << 8) | tg->tg_gm); 12642 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12643 tg->tg_pad | (pa << 6)); 12644 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12645 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12646 tg->tg_pad | (pa << 8)); 12647 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12648 bwn_phy_lp_set_txgain_override(mac); 12649} 12650 12651static void 12652bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12653{ 12654 12655 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12656} 12657 12658static void 12659bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12660{ 12661 uint16_t trsw = (tx << 1) | rx; 12662 12663 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12664 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12665} 12666 12667static void 12668bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12669{ 12670 struct bwn_softc *sc = mac->mac_sc; 12671 struct ifnet *ifp = sc->sc_ifp; 12672 struct ieee80211com *ic = ifp->if_l2com; 12673 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12674 12675 if (mac->mac_phy.rev < 2) { 12676 trsw = gain & 0x1; 12677 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12678 ext_lna = (gain & 2) >> 1; 12679 12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12681 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12682 0xfbff, ext_lna << 10); 12683 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12684 0xf7ff, ext_lna << 11); 12685 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12686 } else { 12687 low_gain = gain & 0xffff; 12688 high_gain = (gain >> 16) & 0xf; 12689 ext_lna = (gain >> 21) & 0x1; 12690 trsw = ~(gain >> 20) & 0x1; 12691 12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12693 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12694 0xfdff, ext_lna << 9); 12695 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12696 0xfbff, ext_lna << 10); 12697 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12698 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12699 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12700 tmp = (gain >> 2) & 0x3; 12701 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12702 0xe7ff, tmp<<11); 12703 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12704 tmp << 3); 12705 } 12706 } 12707 12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12710 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12711 if (mac->mac_phy.rev >= 2) { 12712 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12713 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12714 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12715 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12716 } 12717 return; 12718 } 12719 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12720} 12721 12722static void 12723bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12724{ 12725 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12726 12727 if (user) 12728 plp->plp_crsusr_off = 1; 12729 else 12730 plp->plp_crssys_off = 1; 12731 12732 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12733} 12734 12735static void 12736bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12737{ 12738 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12739 struct bwn_softc *sc = mac->mac_sc; 12740 struct ifnet *ifp = sc->sc_ifp; 12741 struct ieee80211com *ic = ifp->if_l2com; 12742 12743 if (user) 12744 plp->plp_crsusr_off = 0; 12745 else 12746 plp->plp_crssys_off = 0; 12747 12748 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12749 return; 12750 12751 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12752 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12753 else 12754 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12755} 12756 12757static unsigned int 12758bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12759{ 12760 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12761 static uint8_t sqrt_table[256] = { 12762 10, 14, 17, 20, 22, 24, 26, 28, 12763 30, 31, 33, 34, 36, 37, 38, 40, 12764 41, 42, 43, 44, 45, 46, 47, 48, 12765 50, 50, 51, 52, 53, 54, 55, 56, 12766 57, 58, 59, 60, 60, 61, 62, 63, 12767 64, 64, 65, 66, 67, 67, 68, 69, 12768 70, 70, 71, 72, 72, 73, 74, 74, 12769 75, 76, 76, 77, 78, 78, 79, 80, 12770 80, 81, 81, 82, 83, 83, 84, 84, 12771 85, 86, 86, 87, 87, 88, 88, 89, 12772 90, 90, 91, 91, 92, 92, 93, 93, 12773 94, 94, 95, 95, 96, 96, 97, 97, 12774 98, 98, 99, 100, 100, 100, 101, 101, 12775 102, 102, 103, 103, 104, 104, 105, 105, 12776 106, 106, 107, 107, 108, 108, 109, 109, 12777 110, 110, 110, 111, 111, 112, 112, 113, 12778 113, 114, 114, 114, 115, 115, 116, 116, 12779 117, 117, 117, 118, 118, 119, 119, 120, 12780 120, 120, 121, 121, 122, 122, 122, 123, 12781 123, 124, 124, 124, 125, 125, 126, 126, 12782 126, 127, 127, 128, 128, 128, 129, 129, 12783 130, 130, 130, 131, 131, 131, 132, 132, 12784 133, 133, 133, 134, 134, 134, 135, 135, 12785 136, 136, 136, 137, 137, 137, 138, 138, 12786 138, 139, 139, 140, 140, 140, 141, 141, 12787 141, 142, 142, 142, 143, 143, 143, 144, 12788 144, 144, 145, 145, 145, 146, 146, 146, 12789 147, 147, 147, 148, 148, 148, 149, 149, 12790 150, 150, 150, 150, 151, 151, 151, 152, 12791 152, 152, 153, 153, 153, 154, 154, 154, 12792 155, 155, 155, 156, 156, 156, 157, 157, 12793 157, 158, 158, 158, 159, 159, 159, 160 12794 }; 12795 12796 if (x == 0) 12797 return (0); 12798 if (x >= 256) { 12799 unsigned int tmp; 12800 12801 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12802 /* do nothing */ ; 12803 return (tmp); 12804 } 12805 return (sqrt_table[x - 1] / 10); 12806} 12807 12808static int 12809bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12810{ 12811#define CALC_COEFF(_v, _x, _y, _z) do { \ 12812 int _t; \ 12813 _t = _x - 20; \ 12814 if (_t >= 0) { \ 12815 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12816 } else { \ 12817 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12818 } \ 12819} while (0) 12820#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12821 int _t; \ 12822 _t = _x - 11; \ 12823 if (_t >= 0) \ 12824 _v = (_y << (31 - _x)) / (_z >> _t); \ 12825 else \ 12826 _v = (_y << (31 - _x)) / (_z << -_t); \ 12827} while (0) 12828 struct bwn_phy_lp_iq_est ie; 12829 uint16_t v0, v1; 12830 int tmp[2], ret; 12831 12832 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12833 v0 = v1 >> 8; 12834 v1 |= 0xff; 12835 12836 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12837 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12838 12839 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12840 if (ret == 0) 12841 goto done; 12842 12843 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12844 ret = 0; 12845 goto done; 12846 } 12847 12848 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12849 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12850 12851 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12852 v0 = tmp[0] >> 3; 12853 v1 = tmp[1] >> 4; 12854done: 12855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12856 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12857 return ret; 12858#undef CALC_COEFF 12859#undef CALC_COEFF2 12860} 12861 12862static void 12863bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12864{ 12865 static const uint16_t noisescale[] = { 12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12867 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12868 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12869 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12870 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12871 }; 12872 static const uint16_t crsgainnft[] = { 12873 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12874 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12875 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12876 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12877 0x013d, 12878 }; 12879 static const uint16_t filterctl[] = { 12880 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12881 0xff53, 0x0127, 12882 }; 12883 static const uint32_t psctl[] = { 12884 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12885 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12886 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12887 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12888 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12889 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12890 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12891 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12892 }; 12893 static const uint16_t ofdmcckgain_r0[] = { 12894 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12895 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12896 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12897 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12898 0x755d, 12899 }; 12900 static const uint16_t ofdmcckgain_r1[] = { 12901 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12902 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12903 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12904 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12905 0x755d, 12906 }; 12907 static const uint16_t gaindelta[] = { 12908 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12909 0x0000, 12910 }; 12911 static const uint32_t txpwrctl[] = { 12912 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12913 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12914 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12915 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12916 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12917 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12918 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12919 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12920 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12921 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12922 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12923 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12924 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000, 12949 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12950 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12951 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12952 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12953 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12954 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12955 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12956 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12957 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12958 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12959 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12960 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12961 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12962 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12963 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12964 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12965 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12966 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12967 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12968 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12969 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12970 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12971 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12972 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12973 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12974 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12975 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 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, 0x04200000, 0x04000000, 13000 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13001 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13002 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13003 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13004 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13005 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13006 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13007 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13008 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13009 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13010 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13011 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13012 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13013 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13014 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13015 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13016 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13017 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13018 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13019 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13020 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13021 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13022 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13023 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13024 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13025 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13026 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13027 0x00000702, 13028 }; 13029 13030 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13031 13032 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13033 bwn_tab_sigsq_tbl); 13034 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13035 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13036 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13037 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13038 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13039 bwn_tab_pllfrac_tbl); 13040 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13041 bwn_tabl_iqlocal_tbl); 13042 if (mac->mac_phy.rev == 0) { 13043 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13044 ofdmcckgain_r0); 13045 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13046 ofdmcckgain_r0); 13047 } else { 13048 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13049 ofdmcckgain_r1); 13050 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13051 ofdmcckgain_r1); 13052 } 13053 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13054 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13055} 13056 13057static void 13058bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13059{ 13060 struct bwn_softc *sc = mac->mac_sc; 13061 int i; 13062 static const uint16_t noisescale[] = { 13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13065 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13066 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13068 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13069 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13070 }; 13071 static const uint32_t filterctl[] = { 13072 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13073 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13074 }; 13075 static const uint32_t psctl[] = { 13076 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13077 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13078 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13079 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13080 }; 13081 static const uint32_t gainidx[] = { 13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13084 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13085 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13086 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13087 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13088 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13089 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13090 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13091 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13092 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13093 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13094 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13095 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13096 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13099 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13100 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13101 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13102 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13103 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13104 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13105 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13106 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13107 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13108 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13109 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13110 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13111 0x0000001a, 0x64ca55ad, 0x0000001a 13112 }; 13113 static const uint16_t auxgainidx[] = { 13114 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13115 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13116 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13117 0x0004, 0x0016 13118 }; 13119 static const uint16_t swctl[] = { 13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13121 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13122 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13123 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13124 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13125 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13126 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13127 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13128 }; 13129 static const uint8_t hf[] = { 13130 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13131 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13132 }; 13133 static const uint32_t gainval[] = { 13134 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13135 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13136 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13137 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13138 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13139 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13142 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13144 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13145 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13146 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13147 0x000000f1, 0x00000000, 0x00000000 13148 }; 13149 static const uint16_t gain[] = { 13150 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13151 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13152 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13153 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13154 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13155 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13161 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13162 }; 13163 static const uint32_t papdeps[] = { 13164 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13165 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13166 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13167 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13168 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13169 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13170 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13171 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13172 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13173 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13174 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13175 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13176 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13177 }; 13178 static const uint32_t papdmult[] = { 13179 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13180 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13181 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13182 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13183 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13184 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13185 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13186 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13187 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13188 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13189 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13190 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13191 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13192 }; 13193 static const uint32_t gainidx_a0[] = { 13194 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13195 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13196 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13197 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13198 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13199 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13200 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13201 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13202 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13203 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13204 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13205 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13206 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13207 }; 13208 static const uint16_t auxgainidx_a0[] = { 13209 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13210 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13211 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13212 0x0002, 0x0014 13213 }; 13214 static const uint32_t gainval_a0[] = { 13215 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13216 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13217 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13218 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13219 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13220 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13223 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13225 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13226 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13227 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13228 0x000000f7, 0x00000000, 0x00000000 13229 }; 13230 static const uint16_t gain_a0[] = { 13231 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13232 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13233 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13234 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13235 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13236 0x035f, 0x075f, 0x0b5f, 0x0f5f, 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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13242 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13243 }; 13244 13245 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13246 13247 for (i = 0; i < 704; i++) 13248 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13249 13250 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13251 bwn_tab_sigsq_tbl); 13252 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13253 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13254 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13255 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13256 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13257 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13258 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13259 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13260 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13261 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13262 bwn_tab_pllfrac_tbl); 13263 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13264 bwn_tabl_iqlocal_tbl); 13265 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13266 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13267 13268 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13269 (siba_get_chiprev(sc->sc_dev) == 0)) { 13270 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13271 gainidx_a0); 13272 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13273 auxgainidx_a0); 13274 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13275 gainval_a0); 13276 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13277 } 13278} 13279 13280static void 13281bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13282{ 13283 struct bwn_softc *sc = mac->mac_sc; 13284 struct ifnet *ifp = sc->sc_ifp; 13285 struct ieee80211com *ic = ifp->if_l2com; 13286 static struct bwn_txgain_entry txgain_r2[] = { 13287 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13288 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13289 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13290 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13291 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13292 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13293 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13294 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13295 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13296 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13297 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13298 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13299 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13300 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13301 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13302 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13303 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13304 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13305 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13306 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13307 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13308 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13309 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13310 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13311 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13312 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13313 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13314 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13315 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13316 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13317 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13318 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13319 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13320 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13321 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13322 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13323 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13324 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13325 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13326 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13327 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13328 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13329 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13330 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13331 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13332 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13333 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13334 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13335 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13336 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13337 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13338 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13339 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13340 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13341 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13342 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13343 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13344 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13345 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13346 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13347 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13348 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13349 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13350 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13351 }; 13352 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13353 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13354 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13355 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13356 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13357 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13358 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13359 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13360 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13361 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13362 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13363 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13364 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13365 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13366 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13367 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13368 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13369 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13370 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13371 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13372 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13373 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13374 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13375 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13376 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13377 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13378 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13379 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13380 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13381 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13382 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13383 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13384 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13385 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13386 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13387 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13388 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13389 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13390 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13391 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13392 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13393 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13394 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13395 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13396 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13397 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13398 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13399 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13400 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13401 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13402 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13403 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13404 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13405 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13406 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13407 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13408 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13409 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13410 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13411 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13412 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13413 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13414 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13415 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13416 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13417 }; 13418 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13419 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13420 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13421 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13422 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13423 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13424 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13425 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13426 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13427 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13428 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13429 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13430 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13431 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13432 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13433 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13434 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13435 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13436 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13437 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13438 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13439 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13440 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13441 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13442 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13443 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13444 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13445 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13446 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13447 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13448 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13449 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13450 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13451 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13452 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13453 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13454 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13455 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13456 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13457 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13458 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13459 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13460 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13461 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13462 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13463 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13464 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13465 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13466 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13467 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13468 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13469 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13470 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13471 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13472 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13473 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13474 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13475 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13476 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13477 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13478 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13479 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13480 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13481 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13482 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13483 }; 13484 static struct bwn_txgain_entry txgain_r0[] = { 13485 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13486 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13487 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13488 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13489 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13490 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13491 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13492 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13493 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13494 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13495 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13496 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13497 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13498 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13499 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13500 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13501 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13502 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13503 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13504 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13505 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13506 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13507 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13508 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13509 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13510 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13511 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13512 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13513 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13514 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13515 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13516 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13517 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13518 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13519 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13520 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13521 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13522 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13523 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13524 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13525 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13526 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13527 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13528 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13529 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13530 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13531 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13532 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13533 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13534 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13535 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13536 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13537 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13538 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13539 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13540 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13541 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13542 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13543 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13544 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13545 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13546 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13547 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13548 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13549 }; 13550 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13551 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13552 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13553 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13554 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13555 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13556 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13557 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13558 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13559 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13560 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13561 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13562 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13563 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13564 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13565 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13566 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13567 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13568 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13569 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13570 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13571 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13572 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13573 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13574 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13575 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13576 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13577 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13578 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13579 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13580 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13581 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13582 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13583 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13584 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13585 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13586 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13587 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13588 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13589 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13590 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13591 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13592 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13593 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13594 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13595 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13596 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13597 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13598 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13599 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13600 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13601 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13602 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13603 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13604 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13605 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13606 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13607 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13608 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13609 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13610 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13611 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13612 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13613 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13614 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13615 }; 13616 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13617 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13618 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13619 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13620 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13621 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13622 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13623 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13624 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13625 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13626 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13627 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13628 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13629 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13630 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13631 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13632 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13633 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13634 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13635 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13636 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13637 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13638 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13639 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13640 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13641 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13642 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13643 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13644 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13645 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13646 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13647 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13648 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13649 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13650 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13651 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13652 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13653 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13654 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13655 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13656 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13657 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13658 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13659 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13660 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13661 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13662 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13663 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13664 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13665 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13666 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13667 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13668 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13669 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13670 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13671 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13672 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13673 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13674 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13675 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13676 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13677 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13678 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13679 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13680 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13681 }; 13682 static struct bwn_txgain_entry txgain_r1[] = { 13683 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13684 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13685 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13686 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13687 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13688 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13689 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13690 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13691 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13692 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13693 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13694 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13695 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13696 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13697 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13698 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13699 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13700 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13701 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13702 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13703 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13704 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13705 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13706 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13707 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13708 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13709 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13710 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13711 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13712 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13713 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13714 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13715 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13716 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13717 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13718 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13719 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13720 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13721 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13722 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13723 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13724 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13725 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13726 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13727 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13728 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13729 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13730 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13731 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13732 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13733 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13734 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13735 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13736 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13737 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13738 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13739 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13740 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13741 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13742 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13743 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13744 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13745 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13746 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13747 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13748 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13749 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13750 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13751 { 7, 11, 6, 0, 71 } 13752 }; 13753 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13754 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13755 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13756 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13757 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13758 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13759 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13760 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13761 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13762 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13763 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13764 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13765 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13766 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13767 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13768 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13769 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13770 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13771 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13772 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13773 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13774 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13775 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13776 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13777 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13778 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13779 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13780 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13781 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13782 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13783 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13784 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13785 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13786 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13787 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13788 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13789 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13790 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13791 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13792 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13793 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13794 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13795 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13796 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13797 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13798 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13799 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13800 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13801 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13802 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13803 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13804 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13805 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13806 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13807 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13808 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13809 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13810 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13811 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13812 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13813 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13814 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13815 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13816 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13817 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13818 }; 13819 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13820 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13821 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13822 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13823 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13824 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13825 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13826 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13827 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13828 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13829 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13830 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13831 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13832 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13833 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13834 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13835 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13836 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13837 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13838 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13839 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13840 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13841 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13842 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13843 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13844 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13845 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13846 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13847 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13848 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13849 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13850 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13851 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13852 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13853 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13854 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13855 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13856 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13857 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13858 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13859 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13860 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13861 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13862 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13863 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13864 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13865 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13866 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13867 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13868 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13869 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13870 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13871 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13872 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13873 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13874 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13875 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13876 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13877 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13878 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13879 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13880 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13881 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13882 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13883 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13884 }; 13885 13886 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13887 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13888 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13889 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13890 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13891 txgain_2ghz_r2); 13892 else 13893 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13894 txgain_5ghz_r2); 13895 return; 13896 } 13897 13898 if (mac->mac_phy.rev == 0) { 13899 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13900 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13901 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13902 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13903 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13904 txgain_2ghz_r0); 13905 else 13906 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13907 txgain_5ghz_r0); 13908 return; 13909 } 13910 13911 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13912 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13913 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13914 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13915 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13916 else 13917 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13918} 13919 13920static void 13921bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13922{ 13923 uint32_t offset, type; 13924 13925 type = BWN_TAB_GETTYPE(typeoffset); 13926 offset = BWN_TAB_GETOFFSET(typeoffset); 13927 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13928 13929 switch (type) { 13930 case BWN_TAB_8BIT: 13931 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13933 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13934 break; 13935 case BWN_TAB_16BIT: 13936 KASSERT(!(value & ~0xffff), 13937 ("%s:%d: fail", __func__, __LINE__)); 13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13939 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13940 break; 13941 case BWN_TAB_32BIT: 13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13943 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13944 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13945 break; 13946 default: 13947 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13948 } 13949} 13950 13951static int 13952bwn_phy_lp_loopback(struct bwn_mac *mac) 13953{ 13954 struct bwn_phy_lp_iq_est ie; 13955 int i, index = -1; 13956 uint32_t tmp; 13957 13958 memset(&ie, 0, sizeof(ie)); 13959 13960 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13961 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13962 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13966 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13967 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13968 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13969 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13970 for (i = 0; i < 32; i++) { 13971 bwn_phy_lp_set_rxgain_idx(mac, i); 13972 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13973 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13974 continue; 13975 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13976 if ((tmp > 4000) && (tmp < 10000)) { 13977 index = i; 13978 break; 13979 } 13980 } 13981 bwn_phy_lp_ddfs_turnoff(mac); 13982 return (index); 13983} 13984 13985static void 13986bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13987{ 13988 13989 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13990} 13991 13992static void 13993bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13994 int incr1, int incr2, int scale_idx) 13995{ 13996 13997 bwn_phy_lp_ddfs_turnoff(mac); 13998 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13999 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14003 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14004 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14005 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14006 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14007 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14008} 14009 14010static uint8_t 14011bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14012 struct bwn_phy_lp_iq_est *ie) 14013{ 14014 int i; 14015 14016 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14017 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14018 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14019 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14020 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14021 14022 for (i = 0; i < 500; i++) { 14023 if (!(BWN_PHY_READ(mac, 14024 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14025 break; 14026 DELAY(1000); 14027 } 14028 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14029 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14030 return 0; 14031 } 14032 14033 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14034 ie->ie_iqprod <<= 16; 14035 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14036 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14037 ie->ie_ipwr <<= 16; 14038 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14039 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14040 ie->ie_qpwr <<= 16; 14041 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14042 14043 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14044 return 1; 14045} 14046 14047static uint32_t 14048bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14049{ 14050 uint32_t offset, type, value; 14051 14052 type = BWN_TAB_GETTYPE(typeoffset); 14053 offset = BWN_TAB_GETOFFSET(typeoffset); 14054 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14055 14056 switch (type) { 14057 case BWN_TAB_8BIT: 14058 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14059 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14060 break; 14061 case BWN_TAB_16BIT: 14062 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14063 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14064 break; 14065 case BWN_TAB_32BIT: 14066 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14067 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14068 value <<= 16; 14069 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14070 break; 14071 default: 14072 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14073 value = 0; 14074 } 14075 14076 return (value); 14077} 14078 14079static void 14080bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14081{ 14082 14083 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14084 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14085} 14086 14087static void 14088bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14089{ 14090 uint16_t ctl; 14091 14092 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14093 ctl |= dac << 7; 14094 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14095} 14096 14097static void 14098bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14099{ 14100 14101 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14102 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14103} 14104 14105static void 14106bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14107{ 14108 14109 if (mac->mac_phy.rev < 2) 14110 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14111 else { 14112 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14113 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14114 } 14115 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14116} 14117 14118static uint16_t 14119bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14120{ 14121 14122 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14123} 14124 14125static uint8_t 14126bwn_nbits(int32_t val) 14127{ 14128 uint32_t tmp; 14129 uint8_t nbits = 0; 14130 14131 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14132 nbits++; 14133 return (nbits); 14134} 14135 14136static void 14137bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14138 struct bwn_txgain_entry *table) 14139{ 14140 int i; 14141 14142 for (i = offset; i < count; i++) 14143 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14144} 14145 14146static void 14147bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14148 struct bwn_txgain_entry data) 14149{ 14150 14151 if (mac->mac_phy.rev >= 2) 14152 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14153 else 14154 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14155} 14156 14157static void 14158bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14159 struct bwn_txgain_entry te) 14160{ 14161 struct bwn_softc *sc = mac->mac_sc; 14162 struct ifnet *ifp = sc->sc_ifp; 14163 struct ieee80211com *ic = ifp->if_l2com; 14164 uint32_t tmp; 14165 14166 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14167 14168 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14169 if (mac->mac_phy.rev >= 3) { 14170 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14171 (0x10 << 24) : (0x70 << 24)); 14172 } else { 14173 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14174 (0x14 << 24) : (0x7f << 24)); 14175 } 14176 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14177 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14178 te.te_bbmult << 20 | te.te_dac << 28); 14179} 14180 14181static void 14182bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14183 struct bwn_txgain_entry te) 14184{ 14185 14186 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14187 14188 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14189 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14190 te.te_dac); 14191 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14192} 14193 14194static void 14195bwn_sysctl_node(struct bwn_softc *sc) 14196{ 14197 device_t dev = sc->sc_dev; 14198 struct bwn_mac *mac; 14199 struct bwn_stats *stats; 14200 14201 /* XXX assume that count of MAC is only 1. */ 14202 14203 if ((mac = sc->sc_curmac) == NULL) 14204 return; 14205 stats = &mac->mac_stats; 14206 14207 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14208 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14209 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14210 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14211 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14212 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14213 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14214 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14215 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14216 14217#ifdef BWN_DEBUG 14218 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14219 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14220 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14221#endif 14222} 14223 14224static device_method_t bwn_methods[] = { 14225 /* Device interface */ 14226 DEVMETHOD(device_probe, bwn_probe), 14227 DEVMETHOD(device_attach, bwn_attach), 14228 DEVMETHOD(device_detach, bwn_detach), 14229 DEVMETHOD(device_suspend, bwn_suspend), 14230 DEVMETHOD(device_resume, bwn_resume), 14231 DEVMETHOD_END 14232}; 14233static driver_t bwn_driver = { 14234 "bwn", 14235 bwn_methods, 14236 sizeof(struct bwn_softc) 14237}; 14238static devclass_t bwn_devclass; 14239DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14240MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14241MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14242MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14243MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14244