if_bwn.c revision 286865
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 286865 2015-08-17 23:44:38Z adrian $"); 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 ieee80211com *); 185static void bwn_update_promisc(struct ieee80211com *); 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(ic); 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 = ic->ic_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 ieee80211com *ic) 2776{ 2777 struct bwn_softc *sc = ic->ic_softc; 2778 struct bwn_mac *mac; 2779 2780 BWN_LOCK(sc); 2781 if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { 2782 mac = (struct bwn_mac *)sc->sc_curmac; 2783 bwn_set_slot_time(mac, 2784 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2785 } 2786 BWN_UNLOCK(sc); 2787} 2788 2789/* 2790 * Callback from the 802.11 layer after a promiscuous mode change. 2791 * Note this interface does not check the operating mode as this 2792 * is an internal callback and we are expected to honor the current 2793 * state (e.g. this is used for setting the interface in promiscuous 2794 * mode when operating in hostap mode to do ACS). 2795 */ 2796static void 2797bwn_update_promisc(struct ieee80211com *ic) 2798{ 2799 struct bwn_softc *sc = ic->ic_softc; 2800 struct bwn_mac *mac = sc->sc_curmac; 2801 2802 BWN_LOCK(sc); 2803 mac = sc->sc_curmac; 2804 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2805 if (ic->ic_ifp->if_flags & IFF_PROMISC) 2806 sc->sc_filters |= BWN_MACCTL_PROMISC; 2807 else 2808 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2809 bwn_set_opmode(mac); 2810 } 2811 BWN_UNLOCK(sc); 2812} 2813 2814/* 2815 * Callback from the 802.11 layer to update WME parameters. 2816 */ 2817static int 2818bwn_wme_update(struct ieee80211com *ic) 2819{ 2820 struct bwn_softc *sc = ic->ic_softc; 2821 struct bwn_mac *mac = sc->sc_curmac; 2822 struct wmeParams *wmep; 2823 int i; 2824 2825 BWN_LOCK(sc); 2826 mac = sc->sc_curmac; 2827 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2828 bwn_mac_suspend(mac); 2829 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2830 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2831 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2832 } 2833 bwn_mac_enable(mac); 2834 } 2835 BWN_UNLOCK(sc); 2836 return (0); 2837} 2838 2839static void 2840bwn_scan_start(struct ieee80211com *ic) 2841{ 2842 struct bwn_softc *sc = ic->ic_softc; 2843 struct bwn_mac *mac; 2844 2845 BWN_LOCK(sc); 2846 mac = sc->sc_curmac; 2847 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2848 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2849 bwn_set_opmode(mac); 2850 /* disable CFP update during scan */ 2851 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2852 } 2853 BWN_UNLOCK(sc); 2854} 2855 2856static void 2857bwn_scan_end(struct ieee80211com *ic) 2858{ 2859 struct bwn_softc *sc = ic->ic_softc; 2860 struct bwn_mac *mac; 2861 2862 BWN_LOCK(sc); 2863 mac = sc->sc_curmac; 2864 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2865 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2866 bwn_set_opmode(mac); 2867 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2868 } 2869 BWN_UNLOCK(sc); 2870} 2871 2872static void 2873bwn_set_channel(struct ieee80211com *ic) 2874{ 2875 struct bwn_softc *sc = ic->ic_softc; 2876 struct bwn_mac *mac = sc->sc_curmac; 2877 struct bwn_phy *phy = &mac->mac_phy; 2878 int chan, error; 2879 2880 BWN_LOCK(sc); 2881 2882 error = bwn_switch_band(sc, ic->ic_curchan); 2883 if (error) 2884 goto fail; 2885 bwn_mac_suspend(mac); 2886 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2887 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2888 if (chan != phy->chan) 2889 bwn_switch_channel(mac, chan); 2890 2891 /* TX power level */ 2892 if (ic->ic_curchan->ic_maxpower != 0 && 2893 ic->ic_curchan->ic_maxpower != phy->txpower) { 2894 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2895 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2896 BWN_TXPWR_IGNORE_TSSI); 2897 } 2898 2899 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2900 if (phy->set_antenna) 2901 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2902 2903 if (sc->sc_rf_enabled != phy->rf_on) { 2904 if (sc->sc_rf_enabled) { 2905 bwn_rf_turnon(mac); 2906 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2907 device_printf(sc->sc_dev, 2908 "please turn on the RF switch\n"); 2909 } else 2910 bwn_rf_turnoff(mac); 2911 } 2912 2913 bwn_mac_enable(mac); 2914 2915fail: 2916 /* 2917 * Setup radio tap channel freq and flags 2918 */ 2919 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2920 htole16(ic->ic_curchan->ic_freq); 2921 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2922 htole16(ic->ic_curchan->ic_flags & 0xffff); 2923 2924 BWN_UNLOCK(sc); 2925} 2926 2927static struct ieee80211vap * 2928bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2929 enum ieee80211_opmode opmode, int flags, 2930 const uint8_t bssid[IEEE80211_ADDR_LEN], 2931 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2932{ 2933 struct bwn_softc *sc = ic->ic_softc; 2934 struct ieee80211vap *vap; 2935 struct bwn_vap *bvp; 2936 uint8_t mac[IEEE80211_ADDR_LEN]; 2937 2938 IEEE80211_ADDR_COPY(mac, mac0); 2939 switch (opmode) { 2940 case IEEE80211_M_HOSTAP: 2941 case IEEE80211_M_MBSS: 2942 case IEEE80211_M_STA: 2943 case IEEE80211_M_WDS: 2944 case IEEE80211_M_MONITOR: 2945 case IEEE80211_M_IBSS: 2946 case IEEE80211_M_AHDEMO: 2947 break; 2948 default: 2949 return (NULL); 2950 } 2951 2952 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2953 2954 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2955 M_80211_VAP, M_NOWAIT | M_ZERO); 2956 if (bvp == NULL) { 2957 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2958 return (NULL); 2959 } 2960 vap = &bvp->bv_vap; 2961 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2962 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2963 /* override with driver methods */ 2964 bvp->bv_newstate = vap->iv_newstate; 2965 vap->iv_newstate = bwn_newstate; 2966 2967 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2968 vap->iv_max_aid = BWN_STAID_MAX; 2969 2970 ieee80211_ratectl_init(vap); 2971 2972 /* complete setup */ 2973 ieee80211_vap_attach(vap, ieee80211_media_change, 2974 ieee80211_media_status); 2975 return (vap); 2976} 2977 2978static void 2979bwn_vap_delete(struct ieee80211vap *vap) 2980{ 2981 struct bwn_vap *bvp = BWN_VAP(vap); 2982 2983 ieee80211_ratectl_deinit(vap); 2984 ieee80211_vap_detach(vap); 2985 free(bvp, M_80211_VAP); 2986} 2987 2988static void 2989bwn_init(void *arg) 2990{ 2991 struct bwn_softc *sc = arg; 2992 struct ifnet *ifp = sc->sc_ifp; 2993 struct ieee80211com *ic = ifp->if_l2com; 2994 int error = 0; 2995 2996 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2997 __func__, ifp->if_flags); 2998 2999 BWN_LOCK(sc); 3000 error = bwn_init_locked(sc); 3001 BWN_UNLOCK(sc); 3002 3003 if (error == 0) 3004 ieee80211_start_all(ic); /* start all vap's */ 3005} 3006 3007static int 3008bwn_init_locked(struct bwn_softc *sc) 3009{ 3010 struct bwn_mac *mac; 3011 struct ifnet *ifp = sc->sc_ifp; 3012 int error; 3013 3014 BWN_ASSERT_LOCKED(sc); 3015 3016 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3017 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3018 sc->sc_filters = 0; 3019 bwn_wme_clear(sc); 3020 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3021 sc->sc_rf_enabled = 1; 3022 3023 mac = sc->sc_curmac; 3024 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3025 error = bwn_core_init(mac); 3026 if (error != 0) 3027 return (error); 3028 } 3029 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3030 bwn_core_start(mac); 3031 3032 bwn_set_opmode(mac); 3033 bwn_set_pretbtt(mac); 3034 bwn_spu_setdelay(mac, 0); 3035 bwn_set_macaddr(mac); 3036 3037 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3038 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3039 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3040 3041 return (0); 3042} 3043 3044static void 3045bwn_stop(struct bwn_softc *sc, int statechg) 3046{ 3047 3048 BWN_LOCK(sc); 3049 bwn_stop_locked(sc, statechg); 3050 BWN_UNLOCK(sc); 3051} 3052 3053static void 3054bwn_stop_locked(struct bwn_softc *sc, int statechg) 3055{ 3056 struct bwn_mac *mac = sc->sc_curmac; 3057 struct ifnet *ifp = sc->sc_ifp; 3058 3059 BWN_ASSERT_LOCKED(sc); 3060 3061 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3062 /* XXX FIXME opmode not based on VAP */ 3063 bwn_set_opmode(mac); 3064 bwn_set_macaddr(mac); 3065 } 3066 3067 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3068 bwn_core_stop(mac); 3069 3070 callout_stop(&sc->sc_led_blink_ch); 3071 sc->sc_led_blinking = 0; 3072 3073 bwn_core_exit(mac); 3074 sc->sc_rf_enabled = 0; 3075 3076 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3077} 3078 3079static void 3080bwn_wme_clear(struct bwn_softc *sc) 3081{ 3082#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3083 struct wmeParams *p; 3084 unsigned int i; 3085 3086 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3087 ("%s:%d: fail", __func__, __LINE__)); 3088 3089 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3090 p = &(sc->sc_wmeParams[i]); 3091 3092 switch (bwn_wme_shm_offsets[i]) { 3093 case BWN_WME_VOICE: 3094 p->wmep_txopLimit = 0; 3095 p->wmep_aifsn = 2; 3096 /* XXX FIXME: log2(cwmin) */ 3097 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3098 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3099 break; 3100 case BWN_WME_VIDEO: 3101 p->wmep_txopLimit = 0; 3102 p->wmep_aifsn = 2; 3103 /* XXX FIXME: log2(cwmin) */ 3104 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3105 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3106 break; 3107 case BWN_WME_BESTEFFORT: 3108 p->wmep_txopLimit = 0; 3109 p->wmep_aifsn = 3; 3110 /* XXX FIXME: log2(cwmin) */ 3111 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3112 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3113 break; 3114 case BWN_WME_BACKGROUND: 3115 p->wmep_txopLimit = 0; 3116 p->wmep_aifsn = 7; 3117 /* XXX FIXME: log2(cwmin) */ 3118 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3119 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3120 break; 3121 default: 3122 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3123 } 3124 } 3125} 3126 3127static int 3128bwn_core_init(struct bwn_mac *mac) 3129{ 3130 struct bwn_softc *sc = mac->mac_sc; 3131 uint64_t hf; 3132 int error; 3133 3134 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3135 ("%s:%d: fail", __func__, __LINE__)); 3136 3137 siba_powerup(sc->sc_dev, 0); 3138 if (!siba_dev_isup(sc->sc_dev)) 3139 bwn_reset_core(mac, 3140 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3141 3142 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3143 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3144 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3145 BWN_GETTIME(mac->mac_phy.nexttime); 3146 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3147 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3148 mac->mac_stats.link_noise = -95; 3149 mac->mac_reason_intr = 0; 3150 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3151 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3152#ifdef BWN_DEBUG 3153 if (sc->sc_debug & BWN_DEBUG_XMIT) 3154 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3155#endif 3156 mac->mac_suspended = 1; 3157 mac->mac_task_state = 0; 3158 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3159 3160 mac->mac_phy.init_pre(mac); 3161 3162 siba_pcicore_intr(sc->sc_dev); 3163 3164 siba_fix_imcfglobug(sc->sc_dev); 3165 bwn_bt_disable(mac); 3166 if (mac->mac_phy.prepare_hw) { 3167 error = mac->mac_phy.prepare_hw(mac); 3168 if (error) 3169 goto fail0; 3170 } 3171 error = bwn_chip_init(mac); 3172 if (error) 3173 goto fail0; 3174 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3175 siba_get_revid(sc->sc_dev)); 3176 hf = bwn_hf_read(mac); 3177 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3178 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3179 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3180 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3181 if (mac->mac_phy.rev == 1) 3182 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3183 } 3184 if (mac->mac_phy.rf_ver == 0x2050) { 3185 if (mac->mac_phy.rf_rev < 6) 3186 hf |= BWN_HF_FORCE_VCO_RECALC; 3187 if (mac->mac_phy.rf_rev == 6) 3188 hf |= BWN_HF_4318_TSSI; 3189 } 3190 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3191 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3192 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3193 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3194 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3195 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3196 bwn_hf_write(mac, hf); 3197 3198 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3199 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3200 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3201 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3202 3203 bwn_rate_init(mac); 3204 bwn_set_phytxctl(mac); 3205 3206 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3207 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3208 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3209 3210 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3211 bwn_pio_init(mac); 3212 else 3213 bwn_dma_init(mac); 3214 bwn_wme_init(mac); 3215 bwn_spu_setdelay(mac, 1); 3216 bwn_bt_enable(mac); 3217 3218 siba_powerup(sc->sc_dev, 3219 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3220 bwn_set_macaddr(mac); 3221 bwn_crypt_init(mac); 3222 3223 /* XXX LED initializatin */ 3224 3225 mac->mac_status = BWN_MAC_STATUS_INITED; 3226 3227 return (error); 3228 3229fail0: 3230 siba_powerdown(sc->sc_dev); 3231 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3232 ("%s:%d: fail", __func__, __LINE__)); 3233 return (error); 3234} 3235 3236static void 3237bwn_core_start(struct bwn_mac *mac) 3238{ 3239 struct bwn_softc *sc = mac->mac_sc; 3240 uint32_t tmp; 3241 3242 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3243 ("%s:%d: fail", __func__, __LINE__)); 3244 3245 if (siba_get_revid(sc->sc_dev) < 5) 3246 return; 3247 3248 while (1) { 3249 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3250 if (!(tmp & 0x00000001)) 3251 break; 3252 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3253 } 3254 3255 bwn_mac_enable(mac); 3256 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3257 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3258 3259 mac->mac_status = BWN_MAC_STATUS_STARTED; 3260} 3261 3262static void 3263bwn_core_exit(struct bwn_mac *mac) 3264{ 3265 struct bwn_softc *sc = mac->mac_sc; 3266 uint32_t macctl; 3267 3268 BWN_ASSERT_LOCKED(mac->mac_sc); 3269 3270 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3271 ("%s:%d: fail", __func__, __LINE__)); 3272 3273 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3274 return; 3275 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3276 3277 macctl = BWN_READ_4(mac, BWN_MACCTL); 3278 macctl &= ~BWN_MACCTL_MCODE_RUN; 3279 macctl |= BWN_MACCTL_MCODE_JMP0; 3280 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3281 3282 bwn_dma_stop(mac); 3283 bwn_pio_stop(mac); 3284 bwn_chip_exit(mac); 3285 mac->mac_phy.switch_analog(mac, 0); 3286 siba_dev_down(sc->sc_dev, 0); 3287 siba_powerdown(sc->sc_dev); 3288} 3289 3290static void 3291bwn_bt_disable(struct bwn_mac *mac) 3292{ 3293 struct bwn_softc *sc = mac->mac_sc; 3294 3295 (void)sc; 3296 /* XXX do nothing yet */ 3297} 3298 3299static int 3300bwn_chip_init(struct bwn_mac *mac) 3301{ 3302 struct bwn_softc *sc = mac->mac_sc; 3303 struct bwn_phy *phy = &mac->mac_phy; 3304 uint32_t macctl; 3305 int error; 3306 3307 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3308 if (phy->gmode) 3309 macctl |= BWN_MACCTL_GMODE; 3310 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3311 3312 error = bwn_fw_fillinfo(mac); 3313 if (error) 3314 return (error); 3315 error = bwn_fw_loaducode(mac); 3316 if (error) 3317 return (error); 3318 3319 error = bwn_gpio_init(mac); 3320 if (error) 3321 return (error); 3322 3323 error = bwn_fw_loadinitvals(mac); 3324 if (error) { 3325 siba_gpio_set(sc->sc_dev, 0); 3326 return (error); 3327 } 3328 phy->switch_analog(mac, 1); 3329 error = bwn_phy_init(mac); 3330 if (error) { 3331 siba_gpio_set(sc->sc_dev, 0); 3332 return (error); 3333 } 3334 if (phy->set_im) 3335 phy->set_im(mac, BWN_IMMODE_NONE); 3336 if (phy->set_antenna) 3337 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3338 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3339 3340 if (phy->type == BWN_PHYTYPE_B) 3341 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3342 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3343 if (siba_get_revid(sc->sc_dev) < 5) 3344 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3345 3346 BWN_WRITE_4(mac, BWN_MACCTL, 3347 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3348 BWN_WRITE_4(mac, BWN_MACCTL, 3349 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3350 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3351 3352 bwn_set_opmode(mac); 3353 if (siba_get_revid(sc->sc_dev) < 3) { 3354 BWN_WRITE_2(mac, 0x060e, 0x0000); 3355 BWN_WRITE_2(mac, 0x0610, 0x8000); 3356 BWN_WRITE_2(mac, 0x0604, 0x0000); 3357 BWN_WRITE_2(mac, 0x0606, 0x0200); 3358 } else { 3359 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3360 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3361 } 3362 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3363 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3364 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3365 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3366 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3367 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3368 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3369 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3370 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3371 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3372 return (error); 3373} 3374 3375/* read hostflags */ 3376static uint64_t 3377bwn_hf_read(struct bwn_mac *mac) 3378{ 3379 uint64_t ret; 3380 3381 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3382 ret <<= 16; 3383 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3384 ret <<= 16; 3385 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3386 return (ret); 3387} 3388 3389static void 3390bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3391{ 3392 3393 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3394 (value & 0x00000000ffffull)); 3395 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3396 (value & 0x0000ffff0000ull) >> 16); 3397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3398 (value & 0xffff00000000ULL) >> 32); 3399} 3400 3401static void 3402bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3403{ 3404 3405 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3406 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3407} 3408 3409static void 3410bwn_rate_init(struct bwn_mac *mac) 3411{ 3412 3413 switch (mac->mac_phy.type) { 3414 case BWN_PHYTYPE_A: 3415 case BWN_PHYTYPE_G: 3416 case BWN_PHYTYPE_LP: 3417 case BWN_PHYTYPE_N: 3418 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3419 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3420 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3421 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3422 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3423 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3424 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3425 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3426 break; 3427 /* FALLTHROUGH */ 3428 case BWN_PHYTYPE_B: 3429 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3430 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3431 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3432 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3433 break; 3434 default: 3435 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3436 } 3437} 3438 3439static void 3440bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3441{ 3442 uint16_t offset; 3443 3444 if (ofdm) { 3445 offset = 0x480; 3446 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3447 } else { 3448 offset = 0x4c0; 3449 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3450 } 3451 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3452 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3453} 3454 3455static uint8_t 3456bwn_plcp_getcck(const uint8_t bitrate) 3457{ 3458 3459 switch (bitrate) { 3460 case BWN_CCK_RATE_1MB: 3461 return (0x0a); 3462 case BWN_CCK_RATE_2MB: 3463 return (0x14); 3464 case BWN_CCK_RATE_5MB: 3465 return (0x37); 3466 case BWN_CCK_RATE_11MB: 3467 return (0x6e); 3468 } 3469 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3470 return (0); 3471} 3472 3473static uint8_t 3474bwn_plcp_getofdm(const uint8_t bitrate) 3475{ 3476 3477 switch (bitrate) { 3478 case BWN_OFDM_RATE_6MB: 3479 return (0xb); 3480 case BWN_OFDM_RATE_9MB: 3481 return (0xf); 3482 case BWN_OFDM_RATE_12MB: 3483 return (0xa); 3484 case BWN_OFDM_RATE_18MB: 3485 return (0xe); 3486 case BWN_OFDM_RATE_24MB: 3487 return (0x9); 3488 case BWN_OFDM_RATE_36MB: 3489 return (0xd); 3490 case BWN_OFDM_RATE_48MB: 3491 return (0x8); 3492 case BWN_OFDM_RATE_54MB: 3493 return (0xc); 3494 } 3495 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3496 return (0); 3497} 3498 3499static void 3500bwn_set_phytxctl(struct bwn_mac *mac) 3501{ 3502 uint16_t ctl; 3503 3504 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3505 BWN_TX_PHY_TXPWR); 3506 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3507 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3508 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3509} 3510 3511static void 3512bwn_pio_init(struct bwn_mac *mac) 3513{ 3514 struct bwn_pio *pio = &mac->mac_method.pio; 3515 3516 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3517 & ~BWN_MACCTL_BIGENDIAN); 3518 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3519 3520 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3521 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3522 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3523 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3524 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3525 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3526} 3527 3528static void 3529bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3530 int index) 3531{ 3532 struct bwn_pio_txpkt *tp; 3533 struct bwn_softc *sc = mac->mac_sc; 3534 unsigned int i; 3535 3536 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3537 tq->tq_index = index; 3538 3539 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3540 if (siba_get_revid(sc->sc_dev) >= 8) 3541 tq->tq_size = 1920; 3542 else { 3543 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3544 tq->tq_size -= 80; 3545 } 3546 3547 TAILQ_INIT(&tq->tq_pktlist); 3548 for (i = 0; i < N(tq->tq_pkts); i++) { 3549 tp = &(tq->tq_pkts[i]); 3550 tp->tp_index = i; 3551 tp->tp_queue = tq; 3552 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3553 } 3554} 3555 3556static uint16_t 3557bwn_pio_idx2base(struct bwn_mac *mac, int index) 3558{ 3559 struct bwn_softc *sc = mac->mac_sc; 3560 static const uint16_t bases[] = { 3561 BWN_PIO_BASE0, 3562 BWN_PIO_BASE1, 3563 BWN_PIO_BASE2, 3564 BWN_PIO_BASE3, 3565 BWN_PIO_BASE4, 3566 BWN_PIO_BASE5, 3567 BWN_PIO_BASE6, 3568 BWN_PIO_BASE7, 3569 }; 3570 static const uint16_t bases_rev11[] = { 3571 BWN_PIO11_BASE0, 3572 BWN_PIO11_BASE1, 3573 BWN_PIO11_BASE2, 3574 BWN_PIO11_BASE3, 3575 BWN_PIO11_BASE4, 3576 BWN_PIO11_BASE5, 3577 }; 3578 3579 if (siba_get_revid(sc->sc_dev) >= 11) { 3580 if (index >= N(bases_rev11)) 3581 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3582 return (bases_rev11[index]); 3583 } 3584 if (index >= N(bases)) 3585 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3586 return (bases[index]); 3587} 3588 3589static void 3590bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3591 int index) 3592{ 3593 struct bwn_softc *sc = mac->mac_sc; 3594 3595 prq->prq_mac = mac; 3596 prq->prq_rev = siba_get_revid(sc->sc_dev); 3597 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3598 bwn_dma_rxdirectfifo(mac, index, 1); 3599} 3600 3601static void 3602bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3603{ 3604 if (tq == NULL) 3605 return; 3606 bwn_pio_cancel_tx_packets(tq); 3607} 3608 3609static void 3610bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3611{ 3612 3613 bwn_destroy_pioqueue_tx(pio); 3614} 3615 3616static uint16_t 3617bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3618 uint16_t offset) 3619{ 3620 3621 return (BWN_READ_2(mac, tq->tq_base + offset)); 3622} 3623 3624static void 3625bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3626{ 3627 uint32_t ctl; 3628 int type; 3629 uint16_t base; 3630 3631 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3632 base = bwn_dma_base(type, idx); 3633 if (type == BWN_DMA_64BIT) { 3634 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3635 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3636 if (enable) 3637 ctl |= BWN_DMA64_RXDIRECTFIFO; 3638 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3639 } else { 3640 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3641 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3642 if (enable) 3643 ctl |= BWN_DMA32_RXDIRECTFIFO; 3644 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3645 } 3646} 3647 3648static uint64_t 3649bwn_dma_mask(struct bwn_mac *mac) 3650{ 3651 uint32_t tmp; 3652 uint16_t base; 3653 3654 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3655 if (tmp & SIBA_TGSHIGH_DMA64) 3656 return (BWN_DMA_BIT_MASK(64)); 3657 base = bwn_dma_base(0, 0); 3658 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3659 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3660 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3661 return (BWN_DMA_BIT_MASK(32)); 3662 3663 return (BWN_DMA_BIT_MASK(30)); 3664} 3665 3666static int 3667bwn_dma_mask2type(uint64_t dmamask) 3668{ 3669 3670 if (dmamask == BWN_DMA_BIT_MASK(30)) 3671 return (BWN_DMA_30BIT); 3672 if (dmamask == BWN_DMA_BIT_MASK(32)) 3673 return (BWN_DMA_32BIT); 3674 if (dmamask == BWN_DMA_BIT_MASK(64)) 3675 return (BWN_DMA_64BIT); 3676 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3677 return (BWN_DMA_30BIT); 3678} 3679 3680static void 3681bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3682{ 3683 struct bwn_pio_txpkt *tp; 3684 unsigned int i; 3685 3686 for (i = 0; i < N(tq->tq_pkts); i++) { 3687 tp = &(tq->tq_pkts[i]); 3688 if (tp->tp_m) { 3689 m_freem(tp->tp_m); 3690 tp->tp_m = NULL; 3691 } 3692 } 3693} 3694 3695static uint16_t 3696bwn_dma_base(int type, int controller_idx) 3697{ 3698 static const uint16_t map64[] = { 3699 BWN_DMA64_BASE0, 3700 BWN_DMA64_BASE1, 3701 BWN_DMA64_BASE2, 3702 BWN_DMA64_BASE3, 3703 BWN_DMA64_BASE4, 3704 BWN_DMA64_BASE5, 3705 }; 3706 static const uint16_t map32[] = { 3707 BWN_DMA32_BASE0, 3708 BWN_DMA32_BASE1, 3709 BWN_DMA32_BASE2, 3710 BWN_DMA32_BASE3, 3711 BWN_DMA32_BASE4, 3712 BWN_DMA32_BASE5, 3713 }; 3714 3715 if (type == BWN_DMA_64BIT) { 3716 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3717 ("%s:%d: fail", __func__, __LINE__)); 3718 return (map64[controller_idx]); 3719 } 3720 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3721 ("%s:%d: fail", __func__, __LINE__)); 3722 return (map32[controller_idx]); 3723} 3724 3725static void 3726bwn_dma_init(struct bwn_mac *mac) 3727{ 3728 struct bwn_dma *dma = &mac->mac_method.dma; 3729 3730 /* setup TX DMA channels. */ 3731 bwn_dma_setup(dma->wme[WME_AC_BK]); 3732 bwn_dma_setup(dma->wme[WME_AC_BE]); 3733 bwn_dma_setup(dma->wme[WME_AC_VI]); 3734 bwn_dma_setup(dma->wme[WME_AC_VO]); 3735 bwn_dma_setup(dma->mcast); 3736 /* setup RX DMA channel. */ 3737 bwn_dma_setup(dma->rx); 3738} 3739 3740static struct bwn_dma_ring * 3741bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3742 int for_tx, int type) 3743{ 3744 struct bwn_dma *dma = &mac->mac_method.dma; 3745 struct bwn_dma_ring *dr; 3746 struct bwn_dmadesc_generic *desc; 3747 struct bwn_dmadesc_meta *mt; 3748 struct bwn_softc *sc = mac->mac_sc; 3749 int error, i; 3750 3751 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3752 if (dr == NULL) 3753 goto out; 3754 dr->dr_numslots = BWN_RXRING_SLOTS; 3755 if (for_tx) 3756 dr->dr_numslots = BWN_TXRING_SLOTS; 3757 3758 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3759 M_DEVBUF, M_NOWAIT | M_ZERO); 3760 if (dr->dr_meta == NULL) 3761 goto fail0; 3762 3763 dr->dr_type = type; 3764 dr->dr_mac = mac; 3765 dr->dr_base = bwn_dma_base(type, controller_index); 3766 dr->dr_index = controller_index; 3767 if (type == BWN_DMA_64BIT) { 3768 dr->getdesc = bwn_dma_64_getdesc; 3769 dr->setdesc = bwn_dma_64_setdesc; 3770 dr->start_transfer = bwn_dma_64_start_transfer; 3771 dr->suspend = bwn_dma_64_suspend; 3772 dr->resume = bwn_dma_64_resume; 3773 dr->get_curslot = bwn_dma_64_get_curslot; 3774 dr->set_curslot = bwn_dma_64_set_curslot; 3775 } else { 3776 dr->getdesc = bwn_dma_32_getdesc; 3777 dr->setdesc = bwn_dma_32_setdesc; 3778 dr->start_transfer = bwn_dma_32_start_transfer; 3779 dr->suspend = bwn_dma_32_suspend; 3780 dr->resume = bwn_dma_32_resume; 3781 dr->get_curslot = bwn_dma_32_get_curslot; 3782 dr->set_curslot = bwn_dma_32_set_curslot; 3783 } 3784 if (for_tx) { 3785 dr->dr_tx = 1; 3786 dr->dr_curslot = -1; 3787 } else { 3788 if (dr->dr_index == 0) { 3789 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3790 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3791 } else 3792 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3793 } 3794 3795 error = bwn_dma_allocringmemory(dr); 3796 if (error) 3797 goto fail2; 3798 3799 if (for_tx) { 3800 /* 3801 * Assumption: BWN_TXRING_SLOTS can be divided by 3802 * BWN_TX_SLOTS_PER_FRAME 3803 */ 3804 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3805 ("%s:%d: fail", __func__, __LINE__)); 3806 3807 dr->dr_txhdr_cache = 3808 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3809 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3810 KASSERT(dr->dr_txhdr_cache != NULL, 3811 ("%s:%d: fail", __func__, __LINE__)); 3812 3813 /* 3814 * Create TX ring DMA stuffs 3815 */ 3816 error = bus_dma_tag_create(dma->parent_dtag, 3817 BWN_ALIGN, 0, 3818 BUS_SPACE_MAXADDR, 3819 BUS_SPACE_MAXADDR, 3820 NULL, NULL, 3821 BWN_HDRSIZE(mac), 3822 1, 3823 BUS_SPACE_MAXSIZE_32BIT, 3824 0, 3825 NULL, NULL, 3826 &dr->dr_txring_dtag); 3827 if (error) { 3828 device_printf(sc->sc_dev, 3829 "can't create TX ring DMA tag: TODO frees\n"); 3830 goto fail1; 3831 } 3832 3833 for (i = 0; i < dr->dr_numslots; i += 2) { 3834 dr->getdesc(dr, i, &desc, &mt); 3835 3836 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3837 mt->mt_m = NULL; 3838 mt->mt_ni = NULL; 3839 mt->mt_islast = 0; 3840 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3841 &mt->mt_dmap); 3842 if (error) { 3843 device_printf(sc->sc_dev, 3844 "can't create RX buf DMA map\n"); 3845 goto fail1; 3846 } 3847 3848 dr->getdesc(dr, i + 1, &desc, &mt); 3849 3850 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3851 mt->mt_m = NULL; 3852 mt->mt_ni = NULL; 3853 mt->mt_islast = 1; 3854 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3855 &mt->mt_dmap); 3856 if (error) { 3857 device_printf(sc->sc_dev, 3858 "can't create RX buf DMA map\n"); 3859 goto fail1; 3860 } 3861 } 3862 } else { 3863 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3864 &dr->dr_spare_dmap); 3865 if (error) { 3866 device_printf(sc->sc_dev, 3867 "can't create RX buf DMA map\n"); 3868 goto out; /* XXX wrong! */ 3869 } 3870 3871 for (i = 0; i < dr->dr_numslots; i++) { 3872 dr->getdesc(dr, i, &desc, &mt); 3873 3874 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3875 &mt->mt_dmap); 3876 if (error) { 3877 device_printf(sc->sc_dev, 3878 "can't create RX buf DMA map\n"); 3879 goto out; /* XXX wrong! */ 3880 } 3881 error = bwn_dma_newbuf(dr, desc, mt, 1); 3882 if (error) { 3883 device_printf(sc->sc_dev, 3884 "failed to allocate RX buf\n"); 3885 goto out; /* XXX wrong! */ 3886 } 3887 } 3888 3889 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3890 BUS_DMASYNC_PREWRITE); 3891 3892 dr->dr_usedslot = dr->dr_numslots; 3893 } 3894 3895 out: 3896 return (dr); 3897 3898fail2: 3899 free(dr->dr_txhdr_cache, M_DEVBUF); 3900fail1: 3901 free(dr->dr_meta, M_DEVBUF); 3902fail0: 3903 free(dr, M_DEVBUF); 3904 return (NULL); 3905} 3906 3907static void 3908bwn_dma_ringfree(struct bwn_dma_ring **dr) 3909{ 3910 3911 if (dr == NULL) 3912 return; 3913 3914 bwn_dma_free_descbufs(*dr); 3915 bwn_dma_free_ringmemory(*dr); 3916 3917 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3918 free((*dr)->dr_meta, M_DEVBUF); 3919 free(*dr, M_DEVBUF); 3920 3921 *dr = NULL; 3922} 3923 3924static void 3925bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3926 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3927{ 3928 struct bwn_dmadesc32 *desc; 3929 3930 *meta = &(dr->dr_meta[slot]); 3931 desc = dr->dr_ring_descbase; 3932 desc = &(desc[slot]); 3933 3934 *gdesc = (struct bwn_dmadesc_generic *)desc; 3935} 3936 3937static void 3938bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3939 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3940 int start, int end, int irq) 3941{ 3942 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3943 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3944 uint32_t addr, addrext, ctl; 3945 int slot; 3946 3947 slot = (int)(&(desc->dma.dma32) - descbase); 3948 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3949 ("%s:%d: fail", __func__, __LINE__)); 3950 3951 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3952 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3953 addr |= siba_dma_translation(sc->sc_dev); 3954 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3955 if (slot == dr->dr_numslots - 1) 3956 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3957 if (start) 3958 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3959 if (end) 3960 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3961 if (irq) 3962 ctl |= BWN_DMA32_DCTL_IRQ; 3963 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3964 & BWN_DMA32_DCTL_ADDREXT_MASK; 3965 3966 desc->dma.dma32.control = htole32(ctl); 3967 desc->dma.dma32.address = htole32(addr); 3968} 3969 3970static void 3971bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3972{ 3973 3974 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3975 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3976} 3977 3978static void 3979bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3980{ 3981 3982 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3983 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3984} 3985 3986static void 3987bwn_dma_32_resume(struct bwn_dma_ring *dr) 3988{ 3989 3990 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3991 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3992} 3993 3994static int 3995bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3996{ 3997 uint32_t val; 3998 3999 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4000 val &= BWN_DMA32_RXDPTR; 4001 4002 return (val / sizeof(struct bwn_dmadesc32)); 4003} 4004 4005static void 4006bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4007{ 4008 4009 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4010 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4011} 4012 4013static void 4014bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4015 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4016{ 4017 struct bwn_dmadesc64 *desc; 4018 4019 *meta = &(dr->dr_meta[slot]); 4020 desc = dr->dr_ring_descbase; 4021 desc = &(desc[slot]); 4022 4023 *gdesc = (struct bwn_dmadesc_generic *)desc; 4024} 4025 4026static void 4027bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4028 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4029 int start, int end, int irq) 4030{ 4031 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4032 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4033 int slot; 4034 uint32_t ctl0 = 0, ctl1 = 0; 4035 uint32_t addrlo, addrhi; 4036 uint32_t addrext; 4037 4038 slot = (int)(&(desc->dma.dma64) - descbase); 4039 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4040 ("%s:%d: fail", __func__, __LINE__)); 4041 4042 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4043 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4044 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4045 30; 4046 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4047 if (slot == dr->dr_numslots - 1) 4048 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4049 if (start) 4050 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4051 if (end) 4052 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4053 if (irq) 4054 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4055 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4056 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4057 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4058 4059 desc->dma.dma64.control0 = htole32(ctl0); 4060 desc->dma.dma64.control1 = htole32(ctl1); 4061 desc->dma.dma64.address_low = htole32(addrlo); 4062 desc->dma.dma64.address_high = htole32(addrhi); 4063} 4064 4065static void 4066bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4067{ 4068 4069 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4070 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4071} 4072 4073static void 4074bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4075{ 4076 4077 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4078 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4079} 4080 4081static void 4082bwn_dma_64_resume(struct bwn_dma_ring *dr) 4083{ 4084 4085 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4086 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4087} 4088 4089static int 4090bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4091{ 4092 uint32_t val; 4093 4094 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4095 val &= BWN_DMA64_RXSTATDPTR; 4096 4097 return (val / sizeof(struct bwn_dmadesc64)); 4098} 4099 4100static void 4101bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4102{ 4103 4104 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4105 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4106} 4107 4108static int 4109bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4110{ 4111 struct bwn_mac *mac = dr->dr_mac; 4112 struct bwn_dma *dma = &mac->mac_method.dma; 4113 struct bwn_softc *sc = mac->mac_sc; 4114 int error; 4115 4116 error = bus_dma_tag_create(dma->parent_dtag, 4117 BWN_ALIGN, 0, 4118 BUS_SPACE_MAXADDR, 4119 BUS_SPACE_MAXADDR, 4120 NULL, NULL, 4121 BWN_DMA_RINGMEMSIZE, 4122 1, 4123 BUS_SPACE_MAXSIZE_32BIT, 4124 0, 4125 NULL, NULL, 4126 &dr->dr_ring_dtag); 4127 if (error) { 4128 device_printf(sc->sc_dev, 4129 "can't create TX ring DMA tag: TODO frees\n"); 4130 return (-1); 4131 } 4132 4133 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4134 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4135 &dr->dr_ring_dmap); 4136 if (error) { 4137 device_printf(sc->sc_dev, 4138 "can't allocate DMA mem: TODO frees\n"); 4139 return (-1); 4140 } 4141 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4142 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4143 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4144 if (error) { 4145 device_printf(sc->sc_dev, 4146 "can't load DMA mem: TODO free\n"); 4147 return (-1); 4148 } 4149 4150 return (0); 4151} 4152 4153static void 4154bwn_dma_setup(struct bwn_dma_ring *dr) 4155{ 4156 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4157 uint64_t ring64; 4158 uint32_t addrext, ring32, value; 4159 uint32_t trans = siba_dma_translation(sc->sc_dev); 4160 4161 if (dr->dr_tx) { 4162 dr->dr_curslot = -1; 4163 4164 if (dr->dr_type == BWN_DMA_64BIT) { 4165 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4166 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4167 >> 30; 4168 value = BWN_DMA64_TXENABLE; 4169 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4170 & BWN_DMA64_TXADDREXT_MASK; 4171 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4172 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4173 (ring64 & 0xffffffff)); 4174 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4175 ((ring64 >> 32) & 4176 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4177 } else { 4178 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4179 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4180 value = BWN_DMA32_TXENABLE; 4181 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4182 & BWN_DMA32_TXADDREXT_MASK; 4183 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4184 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4185 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4186 } 4187 return; 4188 } 4189 4190 /* 4191 * set for RX 4192 */ 4193 dr->dr_usedslot = dr->dr_numslots; 4194 4195 if (dr->dr_type == BWN_DMA_64BIT) { 4196 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4197 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4198 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4199 value |= BWN_DMA64_RXENABLE; 4200 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4201 & BWN_DMA64_RXADDREXT_MASK; 4202 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4203 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4204 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4205 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4206 | (trans << 1)); 4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4208 sizeof(struct bwn_dmadesc64)); 4209 } else { 4210 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4211 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4212 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4213 value |= BWN_DMA32_RXENABLE; 4214 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4215 & BWN_DMA32_RXADDREXT_MASK; 4216 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4217 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4218 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4219 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4220 sizeof(struct bwn_dmadesc32)); 4221 } 4222} 4223 4224static void 4225bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4226{ 4227 4228 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4229 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4230 dr->dr_ring_dmap); 4231} 4232 4233static void 4234bwn_dma_cleanup(struct bwn_dma_ring *dr) 4235{ 4236 4237 if (dr->dr_tx) { 4238 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4239 if (dr->dr_type == BWN_DMA_64BIT) { 4240 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4241 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4242 } else 4243 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4244 } else { 4245 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4246 if (dr->dr_type == BWN_DMA_64BIT) { 4247 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4248 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4249 } else 4250 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4251 } 4252} 4253 4254static void 4255bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4256{ 4257 struct bwn_dmadesc_generic *desc; 4258 struct bwn_dmadesc_meta *meta; 4259 struct bwn_mac *mac = dr->dr_mac; 4260 struct bwn_dma *dma = &mac->mac_method.dma; 4261 struct bwn_softc *sc = mac->mac_sc; 4262 int i; 4263 4264 if (!dr->dr_usedslot) 4265 return; 4266 for (i = 0; i < dr->dr_numslots; i++) { 4267 dr->getdesc(dr, i, &desc, &meta); 4268 4269 if (meta->mt_m == NULL) { 4270 if (!dr->dr_tx) 4271 device_printf(sc->sc_dev, "%s: not TX?\n", 4272 __func__); 4273 continue; 4274 } 4275 if (dr->dr_tx) { 4276 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4277 bus_dmamap_unload(dr->dr_txring_dtag, 4278 meta->mt_dmap); 4279 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4280 bus_dmamap_unload(dma->txbuf_dtag, 4281 meta->mt_dmap); 4282 } else 4283 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4284 bwn_dma_free_descbuf(dr, meta); 4285 } 4286} 4287 4288static int 4289bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4290 int type) 4291{ 4292 struct bwn_softc *sc = mac->mac_sc; 4293 uint32_t value; 4294 int i; 4295 uint16_t offset; 4296 4297 for (i = 0; i < 10; i++) { 4298 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4299 BWN_DMA32_TXSTATUS; 4300 value = BWN_READ_4(mac, base + offset); 4301 if (type == BWN_DMA_64BIT) { 4302 value &= BWN_DMA64_TXSTAT; 4303 if (value == BWN_DMA64_TXSTAT_DISABLED || 4304 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4305 value == BWN_DMA64_TXSTAT_STOPPED) 4306 break; 4307 } else { 4308 value &= BWN_DMA32_TXSTATE; 4309 if (value == BWN_DMA32_TXSTAT_DISABLED || 4310 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4311 value == BWN_DMA32_TXSTAT_STOPPED) 4312 break; 4313 } 4314 DELAY(1000); 4315 } 4316 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4317 BWN_WRITE_4(mac, base + offset, 0); 4318 for (i = 0; i < 10; i++) { 4319 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4320 BWN_DMA32_TXSTATUS; 4321 value = BWN_READ_4(mac, base + offset); 4322 if (type == BWN_DMA_64BIT) { 4323 value &= BWN_DMA64_TXSTAT; 4324 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4325 i = -1; 4326 break; 4327 } 4328 } else { 4329 value &= BWN_DMA32_TXSTATE; 4330 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4331 i = -1; 4332 break; 4333 } 4334 } 4335 DELAY(1000); 4336 } 4337 if (i != -1) { 4338 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4339 return (ENODEV); 4340 } 4341 DELAY(1000); 4342 4343 return (0); 4344} 4345 4346static int 4347bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4348 int type) 4349{ 4350 struct bwn_softc *sc = mac->mac_sc; 4351 uint32_t value; 4352 int i; 4353 uint16_t offset; 4354 4355 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4356 BWN_WRITE_4(mac, base + offset, 0); 4357 for (i = 0; i < 10; i++) { 4358 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4359 BWN_DMA32_RXSTATUS; 4360 value = BWN_READ_4(mac, base + offset); 4361 if (type == BWN_DMA_64BIT) { 4362 value &= BWN_DMA64_RXSTAT; 4363 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4364 i = -1; 4365 break; 4366 } 4367 } else { 4368 value &= BWN_DMA32_RXSTATE; 4369 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4370 i = -1; 4371 break; 4372 } 4373 } 4374 DELAY(1000); 4375 } 4376 if (i != -1) { 4377 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4378 return (ENODEV); 4379 } 4380 4381 return (0); 4382} 4383 4384static void 4385bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4386 struct bwn_dmadesc_meta *meta) 4387{ 4388 4389 if (meta->mt_m != NULL) { 4390 m_freem(meta->mt_m); 4391 meta->mt_m = NULL; 4392 } 4393 if (meta->mt_ni != NULL) { 4394 ieee80211_free_node(meta->mt_ni); 4395 meta->mt_ni = NULL; 4396 } 4397} 4398 4399static void 4400bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4401{ 4402 struct bwn_rxhdr4 *rxhdr; 4403 unsigned char *frame; 4404 4405 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4406 rxhdr->frame_len = 0; 4407 4408 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4409 sizeof(struct bwn_plcp6) + 2, 4410 ("%s:%d: fail", __func__, __LINE__)); 4411 frame = mtod(m, char *) + dr->dr_frameoffset; 4412 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4413} 4414 4415static uint8_t 4416bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4417{ 4418 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4419 4420 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4421 == 0xff); 4422} 4423 4424static void 4425bwn_wme_init(struct bwn_mac *mac) 4426{ 4427 4428 bwn_wme_load(mac); 4429 4430 /* enable WME support. */ 4431 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4432 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4433 BWN_IFSCTL_USE_EDCF); 4434} 4435 4436static void 4437bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4438{ 4439 struct bwn_softc *sc = mac->mac_sc; 4440 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4441 uint16_t delay; /* microsec */ 4442 4443 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4444 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4445 delay = 500; 4446 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4447 delay = max(delay, (uint16_t)2400); 4448 4449 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4450} 4451 4452static void 4453bwn_bt_enable(struct bwn_mac *mac) 4454{ 4455 struct bwn_softc *sc = mac->mac_sc; 4456 uint64_t hf; 4457 4458 if (bwn_bluetooth == 0) 4459 return; 4460 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4461 return; 4462 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4463 return; 4464 4465 hf = bwn_hf_read(mac); 4466 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4467 hf |= BWN_HF_BT_COEXISTALT; 4468 else 4469 hf |= BWN_HF_BT_COEXIST; 4470 bwn_hf_write(mac, hf); 4471} 4472 4473static void 4474bwn_set_macaddr(struct bwn_mac *mac) 4475{ 4476 4477 bwn_mac_write_bssid(mac); 4478 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4479} 4480 4481static void 4482bwn_clear_keys(struct bwn_mac *mac) 4483{ 4484 int i; 4485 4486 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4487 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4488 ("%s:%d: fail", __func__, __LINE__)); 4489 4490 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4491 NULL, BWN_SEC_KEYSIZE, NULL); 4492 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4493 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4494 NULL, BWN_SEC_KEYSIZE, NULL); 4495 } 4496 mac->mac_key[i].keyconf = NULL; 4497 } 4498} 4499 4500static void 4501bwn_crypt_init(struct bwn_mac *mac) 4502{ 4503 struct bwn_softc *sc = mac->mac_sc; 4504 4505 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4506 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4507 ("%s:%d: fail", __func__, __LINE__)); 4508 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4509 mac->mac_ktp *= 2; 4510 if (siba_get_revid(sc->sc_dev) >= 5) 4511 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4512 bwn_clear_keys(mac); 4513} 4514 4515static void 4516bwn_chip_exit(struct bwn_mac *mac) 4517{ 4518 struct bwn_softc *sc = mac->mac_sc; 4519 4520 bwn_phy_exit(mac); 4521 siba_gpio_set(sc->sc_dev, 0); 4522} 4523 4524static int 4525bwn_fw_fillinfo(struct bwn_mac *mac) 4526{ 4527 int error; 4528 4529 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4530 if (error == 0) 4531 return (0); 4532 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4533 if (error == 0) 4534 return (0); 4535 return (error); 4536} 4537 4538static int 4539bwn_gpio_init(struct bwn_mac *mac) 4540{ 4541 struct bwn_softc *sc = mac->mac_sc; 4542 uint32_t mask = 0x1f, set = 0xf, value; 4543 4544 BWN_WRITE_4(mac, BWN_MACCTL, 4545 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4546 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4547 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4548 4549 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4550 mask |= 0x0060; 4551 set |= 0x0060; 4552 } 4553 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4554 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4555 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4556 mask |= 0x0200; 4557 set |= 0x0200; 4558 } 4559 if (siba_get_revid(sc->sc_dev) >= 2) 4560 mask |= 0x0010; 4561 4562 value = siba_gpio_get(sc->sc_dev); 4563 if (value == -1) 4564 return (0); 4565 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4566 4567 return (0); 4568} 4569 4570static int 4571bwn_fw_loadinitvals(struct bwn_mac *mac) 4572{ 4573#define GETFWOFFSET(fwp, offset) \ 4574 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4575 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4576 const struct bwn_fwhdr *hdr; 4577 struct bwn_fw *fw = &mac->mac_fw; 4578 int error; 4579 4580 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4581 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4582 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4583 if (error) 4584 return (error); 4585 if (fw->initvals_band.fw) { 4586 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4587 error = bwn_fwinitvals_write(mac, 4588 GETFWOFFSET(fw->initvals_band, hdr_len), 4589 be32toh(hdr->size), 4590 fw->initvals_band.fw->datasize - hdr_len); 4591 } 4592 return (error); 4593#undef GETFWOFFSET 4594} 4595 4596static int 4597bwn_phy_init(struct bwn_mac *mac) 4598{ 4599 struct bwn_softc *sc = mac->mac_sc; 4600 int error; 4601 4602 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4603 mac->mac_phy.rf_onoff(mac, 1); 4604 error = mac->mac_phy.init(mac); 4605 if (error) { 4606 device_printf(sc->sc_dev, "PHY init failed\n"); 4607 goto fail0; 4608 } 4609 error = bwn_switch_channel(mac, 4610 mac->mac_phy.get_default_chan(mac)); 4611 if (error) { 4612 device_printf(sc->sc_dev, 4613 "failed to switch default channel\n"); 4614 goto fail1; 4615 } 4616 return (0); 4617fail1: 4618 if (mac->mac_phy.exit) 4619 mac->mac_phy.exit(mac); 4620fail0: 4621 mac->mac_phy.rf_onoff(mac, 0); 4622 4623 return (error); 4624} 4625 4626static void 4627bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4628{ 4629 uint16_t ant; 4630 uint16_t tmp; 4631 4632 ant = bwn_ant2phy(antenna); 4633 4634 /* For ACK/CTS */ 4635 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4636 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4637 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4638 /* For Probe Resposes */ 4639 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4640 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4641 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4642} 4643 4644static void 4645bwn_set_opmode(struct bwn_mac *mac) 4646{ 4647 struct bwn_softc *sc = mac->mac_sc; 4648 struct ifnet *ifp = sc->sc_ifp; 4649 struct ieee80211com *ic = ifp->if_l2com; 4650 uint32_t ctl; 4651 uint16_t cfp_pretbtt; 4652 4653 ctl = BWN_READ_4(mac, BWN_MACCTL); 4654 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4655 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4656 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4657 ctl |= BWN_MACCTL_STA; 4658 4659 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4660 ic->ic_opmode == IEEE80211_M_MBSS) 4661 ctl |= BWN_MACCTL_HOSTAP; 4662 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4663 ctl &= ~BWN_MACCTL_STA; 4664 ctl |= sc->sc_filters; 4665 4666 if (siba_get_revid(sc->sc_dev) <= 4) 4667 ctl |= BWN_MACCTL_PROMISC; 4668 4669 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4670 4671 cfp_pretbtt = 2; 4672 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4673 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4674 siba_get_chiprev(sc->sc_dev) == 3) 4675 cfp_pretbtt = 100; 4676 else 4677 cfp_pretbtt = 50; 4678 } 4679 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4680} 4681 4682static int 4683bwn_dma_gettype(struct bwn_mac *mac) 4684{ 4685 uint32_t tmp; 4686 uint16_t base; 4687 4688 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4689 if (tmp & SIBA_TGSHIGH_DMA64) 4690 return (BWN_DMA_64BIT); 4691 base = bwn_dma_base(0, 0); 4692 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4693 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4694 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4695 return (BWN_DMA_32BIT); 4696 4697 return (BWN_DMA_30BIT); 4698} 4699 4700static void 4701bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4702{ 4703 if (!error) { 4704 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4705 *((bus_addr_t *)arg) = seg->ds_addr; 4706 } 4707} 4708 4709static void 4710bwn_phy_g_init_sub(struct bwn_mac *mac) 4711{ 4712 struct bwn_phy *phy = &mac->mac_phy; 4713 struct bwn_phy_g *pg = &phy->phy_g; 4714 struct bwn_softc *sc = mac->mac_sc; 4715 uint16_t i, tmp; 4716 4717 if (phy->rev == 1) 4718 bwn_phy_init_b5(mac); 4719 else 4720 bwn_phy_init_b6(mac); 4721 4722 if (phy->rev >= 2 || phy->gmode) 4723 bwn_phy_init_a(mac); 4724 4725 if (phy->rev >= 2) { 4726 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4727 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4728 } 4729 if (phy->rev == 2) { 4730 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4731 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4732 } 4733 if (phy->rev > 5) { 4734 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4735 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4736 } 4737 if (phy->gmode || phy->rev >= 2) { 4738 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4739 tmp &= BWN_PHYVER_VERSION; 4740 if (tmp == 3 || tmp == 5) { 4741 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4742 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4743 } 4744 if (tmp == 5) { 4745 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4746 0x1f00); 4747 } 4748 } 4749 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4750 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4751 if (phy->rf_rev == 8) { 4752 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4753 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4754 } 4755 if (BWN_HAS_LOOPBACK(phy)) 4756 bwn_loopback_calcgain(mac); 4757 4758 if (phy->rf_rev != 8) { 4759 if (pg->pg_initval == 0xffff) 4760 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4761 else 4762 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4763 } 4764 bwn_lo_g_init(mac); 4765 if (BWN_HAS_TXMAG(phy)) { 4766 BWN_RF_WRITE(mac, 0x52, 4767 (BWN_RF_READ(mac, 0x52) & 0xff00) 4768 | pg->pg_loctl.tx_bias | 4769 pg->pg_loctl.tx_magn); 4770 } else { 4771 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4772 } 4773 if (phy->rev >= 6) { 4774 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4775 (pg->pg_loctl.tx_bias << 12)); 4776 } 4777 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4778 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4779 else 4780 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4781 if (phy->rev < 2) 4782 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4783 else 4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4785 if (phy->gmode || phy->rev >= 2) { 4786 bwn_lo_g_adjust(mac); 4787 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4788 } 4789 4790 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4791 for (i = 0; i < 64; i++) { 4792 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4793 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4794 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4795 -32), 31)); 4796 } 4797 bwn_nrssi_threshold(mac); 4798 } else if (phy->gmode || phy->rev >= 2) { 4799 if (pg->pg_nrssi[0] == -1000) { 4800 KASSERT(pg->pg_nrssi[1] == -1000, 4801 ("%s:%d: fail", __func__, __LINE__)); 4802 bwn_nrssi_slope_11g(mac); 4803 } else 4804 bwn_nrssi_threshold(mac); 4805 } 4806 if (phy->rf_rev == 8) 4807 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4808 bwn_phy_hwpctl_init(mac); 4809 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4810 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4811 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4812 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4813 } 4814} 4815 4816static uint8_t 4817bwn_has_hwpctl(struct bwn_mac *mac) 4818{ 4819 4820 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4821 return (0); 4822 return (mac->mac_phy.use_hwpctl(mac)); 4823} 4824 4825static void 4826bwn_phy_init_b5(struct bwn_mac *mac) 4827{ 4828 struct bwn_phy *phy = &mac->mac_phy; 4829 struct bwn_phy_g *pg = &phy->phy_g; 4830 struct bwn_softc *sc = mac->mac_sc; 4831 uint16_t offset, value; 4832 uint8_t old_channel; 4833 4834 if (phy->analog == 1) 4835 BWN_RF_SET(mac, 0x007a, 0x0050); 4836 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4837 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4838 value = 0x2120; 4839 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4840 BWN_PHY_WRITE(mac, offset, value); 4841 value += 0x202; 4842 } 4843 } 4844 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4845 if (phy->rf_ver == 0x2050) 4846 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4847 4848 if (phy->gmode || phy->rev >= 2) { 4849 if (phy->rf_ver == 0x2050) { 4850 BWN_RF_SET(mac, 0x007a, 0x0020); 4851 BWN_RF_SET(mac, 0x0051, 0x0004); 4852 } 4853 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4854 4855 BWN_PHY_SET(mac, 0x0802, 0x0100); 4856 BWN_PHY_SET(mac, 0x042b, 0x2000); 4857 4858 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4859 4860 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4861 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4862 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4863 } 4864 4865 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4866 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4867 4868 if (phy->analog == 1) { 4869 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4870 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4871 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4872 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4873 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4874 } else 4875 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4876 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4877 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4878 4879 if (phy->analog == 1) 4880 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4881 else 4882 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4883 4884 if (phy->analog == 0) 4885 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4886 4887 old_channel = phy->chan; 4888 bwn_phy_g_switch_chan(mac, 7, 0); 4889 4890 if (phy->rf_ver != 0x2050) { 4891 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4892 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4893 } 4894 4895 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4896 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4897 4898 if (phy->rf_ver == 0x2050) { 4899 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4900 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4901 } 4902 4903 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4904 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4905 BWN_RF_SET(mac, 0x007a, 0x0007); 4906 4907 bwn_phy_g_switch_chan(mac, old_channel, 0); 4908 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4909 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4910 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4911 4912 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4913 pg->pg_txctl); 4914 4915 if (phy->rf_ver == 0x2050) 4916 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4917 4918 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4919} 4920 4921static void 4922bwn_loopback_calcgain(struct bwn_mac *mac) 4923{ 4924 struct bwn_phy *phy = &mac->mac_phy; 4925 struct bwn_phy_g *pg = &phy->phy_g; 4926 struct bwn_softc *sc = mac->mac_sc; 4927 uint16_t backup_phy[16] = { 0 }; 4928 uint16_t backup_radio[3]; 4929 uint16_t backup_bband; 4930 uint16_t i, j, loop_i_max; 4931 uint16_t trsw_rx; 4932 uint16_t loop1_outer_done, loop1_inner_done; 4933 4934 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4935 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4936 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4937 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4938 if (phy->rev != 1) { 4939 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4940 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4941 } 4942 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4943 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4944 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4945 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4946 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4947 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4948 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4949 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4950 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4951 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4952 backup_bband = pg->pg_bbatt.att; 4953 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4954 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4955 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4956 4957 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4958 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4959 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4960 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4961 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4962 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4963 if (phy->rev != 1) { 4964 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4965 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4966 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4967 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4968 } 4969 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4970 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4971 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4972 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4973 4974 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4975 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4976 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4977 4978 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4979 if (phy->rev != 1) { 4980 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4981 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4982 } 4983 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4984 4985 if (phy->rf_rev == 8) 4986 BWN_RF_WRITE(mac, 0x43, 0x000f); 4987 else { 4988 BWN_RF_WRITE(mac, 0x52, 0); 4989 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4990 } 4991 bwn_phy_g_set_bbatt(mac, 11); 4992 4993 if (phy->rev >= 3) 4994 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4995 else 4996 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4997 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4998 4999 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5000 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5001 5002 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5003 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5004 5005 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5006 if (phy->rev >= 7) { 5007 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5008 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5009 } 5010 } 5011 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5012 5013 j = 0; 5014 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5015 for (i = 0; i < loop_i_max; i++) { 5016 for (j = 0; j < 16; j++) { 5017 BWN_RF_WRITE(mac, 0x43, i); 5018 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5019 (j << 8)); 5020 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5021 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5022 DELAY(20); 5023 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5024 goto done0; 5025 } 5026 } 5027done0: 5028 loop1_outer_done = i; 5029 loop1_inner_done = j; 5030 if (j >= 8) { 5031 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5032 trsw_rx = 0x1b; 5033 for (j = j - 8; j < 16; j++) { 5034 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5035 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5036 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5037 DELAY(20); 5038 trsw_rx -= 3; 5039 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5040 goto done1; 5041 } 5042 } else 5043 trsw_rx = 0x18; 5044done1: 5045 5046 if (phy->rev != 1) { 5047 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5048 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5049 } 5050 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5051 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5052 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5053 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5055 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5056 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5059 5060 bwn_phy_g_set_bbatt(mac, backup_bband); 5061 5062 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5063 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5064 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5065 5066 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5067 DELAY(10); 5068 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5069 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5070 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5071 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5072 5073 pg->pg_max_lb_gain = 5074 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5075 pg->pg_trsw_rx_gain = trsw_rx * 2; 5076} 5077 5078static uint16_t 5079bwn_rf_init_bcm2050(struct bwn_mac *mac) 5080{ 5081 struct bwn_phy *phy = &mac->mac_phy; 5082 uint32_t tmp1 = 0, tmp2 = 0; 5083 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5084 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5085 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5086 static const uint8_t rcc_table[] = { 5087 0x02, 0x03, 0x01, 0x0f, 5088 0x06, 0x07, 0x05, 0x0f, 5089 0x0a, 0x0b, 0x09, 0x0f, 5090 0x0e, 0x0f, 0x0d, 0x0f, 5091 }; 5092 5093 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5094 rfoverval = rfover = cck3 = 0; 5095 radio0 = BWN_RF_READ(mac, 0x43); 5096 radio1 = BWN_RF_READ(mac, 0x51); 5097 radio2 = BWN_RF_READ(mac, 0x52); 5098 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5099 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5100 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5101 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5102 5103 if (phy->type == BWN_PHYTYPE_B) { 5104 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5105 reg0 = BWN_READ_2(mac, 0x3ec); 5106 5107 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5108 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5109 } else if (phy->gmode || phy->rev >= 2) { 5110 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5111 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5112 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5113 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5114 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5115 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5116 5117 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5118 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5119 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5120 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5121 if (BWN_HAS_LOOPBACK(phy)) { 5122 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5123 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5124 if (phy->rev >= 3) 5125 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5126 else 5127 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5128 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5129 } 5130 5131 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5132 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5133 BWN_LPD(0, 1, 1))); 5134 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5135 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5136 } 5137 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5138 5139 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5140 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5141 reg1 = BWN_READ_2(mac, 0x3e6); 5142 reg2 = BWN_READ_2(mac, 0x3f4); 5143 5144 if (phy->analog == 0) 5145 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5146 else { 5147 if (phy->analog >= 2) 5148 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5149 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5150 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5151 } 5152 5153 reg = BWN_RF_READ(mac, 0x60); 5154 index = (reg & 0x001e) >> 1; 5155 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5156 5157 if (phy->type == BWN_PHYTYPE_B) 5158 BWN_RF_WRITE(mac, 0x78, 0x26); 5159 if (phy->gmode || phy->rev >= 2) { 5160 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5161 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5162 BWN_LPD(0, 1, 1))); 5163 } 5164 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5165 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5166 if (phy->gmode || phy->rev >= 2) { 5167 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5168 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5169 BWN_LPD(0, 0, 1))); 5170 } 5171 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5172 BWN_RF_SET(mac, 0x51, 0x0004); 5173 if (phy->rf_rev == 8) 5174 BWN_RF_WRITE(mac, 0x43, 0x1f); 5175 else { 5176 BWN_RF_WRITE(mac, 0x52, 0); 5177 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5178 } 5179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5180 5181 for (i = 0; i < 16; i++) { 5182 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5183 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5184 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5185 if (phy->gmode || phy->rev >= 2) { 5186 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5187 bwn_rf_2050_rfoverval(mac, 5188 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5189 } 5190 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5191 DELAY(10); 5192 if (phy->gmode || phy->rev >= 2) { 5193 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5194 bwn_rf_2050_rfoverval(mac, 5195 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5196 } 5197 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5198 DELAY(10); 5199 if (phy->gmode || phy->rev >= 2) { 5200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5201 bwn_rf_2050_rfoverval(mac, 5202 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5203 } 5204 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5205 DELAY(20); 5206 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5207 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5208 if (phy->gmode || phy->rev >= 2) { 5209 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5210 bwn_rf_2050_rfoverval(mac, 5211 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5212 } 5213 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5214 } 5215 DELAY(10); 5216 5217 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5218 tmp1++; 5219 tmp1 >>= 9; 5220 5221 for (i = 0; i < 16; i++) { 5222 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5223 BWN_RF_WRITE(mac, 0x78, radio78); 5224 DELAY(10); 5225 for (j = 0; j < 16; j++) { 5226 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5227 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5228 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5229 if (phy->gmode || phy->rev >= 2) { 5230 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5231 bwn_rf_2050_rfoverval(mac, 5232 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5233 } 5234 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5235 DELAY(10); 5236 if (phy->gmode || phy->rev >= 2) { 5237 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5238 bwn_rf_2050_rfoverval(mac, 5239 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5240 } 5241 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5242 DELAY(10); 5243 if (phy->gmode || phy->rev >= 2) { 5244 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5245 bwn_rf_2050_rfoverval(mac, 5246 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5247 } 5248 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5249 DELAY(10); 5250 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5251 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5252 if (phy->gmode || phy->rev >= 2) { 5253 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5254 bwn_rf_2050_rfoverval(mac, 5255 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5256 } 5257 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5258 } 5259 tmp2++; 5260 tmp2 >>= 8; 5261 if (tmp1 < tmp2) 5262 break; 5263 } 5264 5265 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5266 BWN_RF_WRITE(mac, 0x51, radio1); 5267 BWN_RF_WRITE(mac, 0x52, radio2); 5268 BWN_RF_WRITE(mac, 0x43, radio0); 5269 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5270 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5271 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5272 BWN_WRITE_2(mac, 0x3e6, reg1); 5273 if (phy->analog != 0) 5274 BWN_WRITE_2(mac, 0x3f4, reg2); 5275 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5276 bwn_spu_workaround(mac, phy->chan); 5277 if (phy->type == BWN_PHYTYPE_B) { 5278 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5279 BWN_WRITE_2(mac, 0x3ec, reg0); 5280 } else if (phy->gmode) { 5281 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5282 BWN_READ_2(mac, BWN_PHY_RADIO) 5283 & 0x7fff); 5284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5285 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5286 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5287 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5288 analogoverval); 5289 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5290 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5291 if (BWN_HAS_LOOPBACK(phy)) { 5292 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5293 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5294 } 5295 } 5296 5297 return ((i > 15) ? radio78 : rcc); 5298} 5299 5300static void 5301bwn_phy_init_b6(struct bwn_mac *mac) 5302{ 5303 struct bwn_phy *phy = &mac->mac_phy; 5304 struct bwn_phy_g *pg = &phy->phy_g; 5305 struct bwn_softc *sc = mac->mac_sc; 5306 uint16_t offset, val; 5307 uint8_t old_channel; 5308 5309 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5310 ("%s:%d: fail", __func__, __LINE__)); 5311 5312 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5313 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5314 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5315 BWN_RF_WRITE(mac, 0x51, 0x37); 5316 BWN_RF_WRITE(mac, 0x52, 0x70); 5317 BWN_RF_WRITE(mac, 0x53, 0xb3); 5318 BWN_RF_WRITE(mac, 0x54, 0x9b); 5319 BWN_RF_WRITE(mac, 0x5a, 0x88); 5320 BWN_RF_WRITE(mac, 0x5b, 0x88); 5321 BWN_RF_WRITE(mac, 0x5d, 0x88); 5322 BWN_RF_WRITE(mac, 0x5e, 0x88); 5323 BWN_RF_WRITE(mac, 0x7d, 0x88); 5324 bwn_hf_write(mac, 5325 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5326 } 5327 if (phy->rf_rev == 8) { 5328 BWN_RF_WRITE(mac, 0x51, 0); 5329 BWN_RF_WRITE(mac, 0x52, 0x40); 5330 BWN_RF_WRITE(mac, 0x53, 0xb7); 5331 BWN_RF_WRITE(mac, 0x54, 0x98); 5332 BWN_RF_WRITE(mac, 0x5a, 0x88); 5333 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5334 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5335 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5336 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5337 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5338 } else { 5339 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5340 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5341 } 5342 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5343 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5344 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5345 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5346 } 5347 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5348 BWN_PHY_WRITE(mac, offset, val); 5349 val -= 0x0202; 5350 } 5351 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5352 BWN_PHY_WRITE(mac, offset, val); 5353 val -= 0x0202; 5354 } 5355 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5356 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5357 val += 0x0202; 5358 } 5359 if (phy->type == BWN_PHYTYPE_G) { 5360 BWN_RF_SET(mac, 0x007a, 0x0020); 5361 BWN_RF_SET(mac, 0x0051, 0x0004); 5362 BWN_PHY_SET(mac, 0x0802, 0x0100); 5363 BWN_PHY_SET(mac, 0x042b, 0x2000); 5364 BWN_PHY_WRITE(mac, 0x5b, 0); 5365 BWN_PHY_WRITE(mac, 0x5c, 0); 5366 } 5367 5368 old_channel = phy->chan; 5369 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5370 5371 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5372 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5373 DELAY(40); 5374 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5375 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5376 BWN_RF_WRITE(mac, 0x50, 0x20); 5377 } 5378 if (phy->rf_rev <= 2) { 5379 BWN_RF_WRITE(mac, 0x7c, 0x20); 5380 BWN_RF_WRITE(mac, 0x5a, 0x70); 5381 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5382 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5383 } 5384 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5385 5386 bwn_phy_g_switch_chan(mac, old_channel, 0); 5387 5388 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5389 if (phy->rf_rev >= 6) 5390 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5391 else 5392 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5393 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5394 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5395 pg->pg_txctl); 5396 if (phy->rf_rev <= 5) 5397 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5398 if (phy->rf_rev <= 2) 5399 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5400 5401 if (phy->analog == 4) { 5402 BWN_WRITE_2(mac, 0x3e4, 9); 5403 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5404 } else 5405 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5406 if (phy->type == BWN_PHYTYPE_B) 5407 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5408 else if (phy->type == BWN_PHYTYPE_G) 5409 BWN_WRITE_2(mac, 0x03e6, 0x0); 5410} 5411 5412static void 5413bwn_phy_init_a(struct bwn_mac *mac) 5414{ 5415 struct bwn_phy *phy = &mac->mac_phy; 5416 struct bwn_softc *sc = mac->mac_sc; 5417 5418 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5419 ("%s:%d: fail", __func__, __LINE__)); 5420 5421 if (phy->rev >= 6) { 5422 if (phy->type == BWN_PHYTYPE_A) 5423 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5424 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5425 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5426 else 5427 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5428 } 5429 5430 bwn_wa_init(mac); 5431 5432 if (phy->type == BWN_PHYTYPE_G && 5433 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5434 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5435} 5436 5437static void 5438bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5439{ 5440 int i; 5441 5442 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5443 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5444} 5445 5446static void 5447bwn_wa_agc(struct bwn_mac *mac) 5448{ 5449 struct bwn_phy *phy = &mac->mac_phy; 5450 5451 if (phy->rev == 1) { 5452 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5453 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5454 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5455 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5460 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5461 } else { 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5466 } 5467 5468 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5469 0x5700); 5470 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5471 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5472 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5473 BWN_RF_SET(mac, 0x7a, 0x0008); 5474 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5475 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5477 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5478 if (phy->rev == 1) 5479 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5480 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5482 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5483 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5489 if (phy->rev == 1) { 5490 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5492 } else { 5493 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5494 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5495 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5496 if (phy->rev >= 6) { 5497 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5498 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5499 (uint16_t)~0xf000, 0x3000); 5500 } 5501 } 5502 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5503 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5504 if (phy->rev == 1) { 5505 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5506 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5507 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5508 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5509 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5510 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5511 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5512 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5513 } else { 5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5518 } 5519 if (phy->rev >= 6) { 5520 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5521 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5522 } 5523 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5524} 5525 5526static void 5527bwn_wa_grev1(struct bwn_mac *mac) 5528{ 5529 struct bwn_phy *phy = &mac->mac_phy; 5530 int i; 5531 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5532 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5533 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5534 5535 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5536 5537 /* init CRSTHRES and ANTDWELL */ 5538 if (phy->rev == 1) { 5539 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5540 } else if (phy->rev == 2) { 5541 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5542 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5543 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5544 } else { 5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5547 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5548 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5549 } 5550 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5551 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5552 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5553 5554 /* XXX support PHY-A??? */ 5555 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5556 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5557 bwn_tab_finefreqg[i]); 5558 5559 /* XXX support PHY-A??? */ 5560 if (phy->rev == 1) 5561 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5563 bwn_tab_noise_g1[i]); 5564 else 5565 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5567 bwn_tab_noise_g2[i]); 5568 5569 5570 for (i = 0; i < N(bwn_tab_rotor); i++) 5571 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5572 bwn_tab_rotor[i]); 5573 5574 /* XXX support PHY-A??? */ 5575 if (phy->rev >= 6) { 5576 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5577 BWN_PHY_ENCORE_EN) 5578 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5579 else 5580 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5581 } else 5582 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5583 5584 for (i = 0; i < N(bwn_tab_retard); i++) 5585 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5586 bwn_tab_retard[i]); 5587 5588 if (phy->rev == 1) { 5589 for (i = 0; i < 16; i++) 5590 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5591 i, 0x0020); 5592 } else { 5593 for (i = 0; i < 32; i++) 5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5595 } 5596 5597 bwn_wa_agc(mac); 5598} 5599 5600static void 5601bwn_wa_grev26789(struct bwn_mac *mac) 5602{ 5603 struct bwn_phy *phy = &mac->mac_phy; 5604 int i; 5605 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5606 uint16_t ofdmrev; 5607 5608 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5609 5610 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5611 5612 /* init CRSTHRES and ANTDWELL */ 5613 if (phy->rev == 1) 5614 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5615 else if (phy->rev == 2) { 5616 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5617 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5618 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5619 } else { 5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5622 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5623 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5624 } 5625 5626 for (i = 0; i < 64; i++) 5627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5628 5629 /* XXX support PHY-A??? */ 5630 if (phy->rev == 1) 5631 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5633 bwn_tab_noise_g1[i]); 5634 else 5635 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5637 bwn_tab_noise_g2[i]); 5638 5639 /* XXX support PHY-A??? */ 5640 if (phy->rev >= 6) { 5641 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5642 BWN_PHY_ENCORE_EN) 5643 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5644 else 5645 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5646 } else 5647 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5648 5649 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5650 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5651 bwn_tab_sigmasqr2[i]); 5652 5653 if (phy->rev == 1) { 5654 for (i = 0; i < 16; i++) 5655 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5656 0x0020); 5657 } else { 5658 for (i = 0; i < 32; i++) 5659 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5660 } 5661 5662 bwn_wa_agc(mac); 5663 5664 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5665 if (ofdmrev > 2) { 5666 if (phy->type == BWN_PHYTYPE_A) 5667 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5668 else 5669 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5670 } else { 5671 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5672 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5673 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5674 } 5675 5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5678} 5679 5680static void 5681bwn_wa_init(struct bwn_mac *mac) 5682{ 5683 struct bwn_phy *phy = &mac->mac_phy; 5684 struct bwn_softc *sc = mac->mac_sc; 5685 5686 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5687 5688 switch (phy->rev) { 5689 case 1: 5690 bwn_wa_grev1(mac); 5691 break; 5692 case 2: 5693 case 6: 5694 case 7: 5695 case 8: 5696 case 9: 5697 bwn_wa_grev26789(mac); 5698 break; 5699 default: 5700 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5701 } 5702 5703 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5704 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5705 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5706 if (phy->rev < 2) { 5707 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5708 0x0002); 5709 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5710 0x0001); 5711 } else { 5712 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5714 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5715 BWN_BFL_EXTLNA) && 5716 (phy->rev >= 7)) { 5717 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5718 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5719 0x0020, 0x0001); 5720 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5721 0x0021, 0x0001); 5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5723 0x0022, 0x0001); 5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5725 0x0023, 0x0000); 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5727 0x0000, 0x0000); 5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5729 0x0003, 0x0002); 5730 } 5731 } 5732 } 5733 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5734 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5735 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5736 } 5737 5738 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5739 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5740} 5741 5742static void 5743bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5744 uint16_t value) 5745{ 5746 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5747 uint16_t addr; 5748 5749 addr = table + offset; 5750 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5751 (addr - 1 != pg->pg_ofdmtab_addr)) { 5752 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5753 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5754 } 5755 pg->pg_ofdmtab_addr = addr; 5756 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5757} 5758 5759static void 5760bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5761 uint32_t value) 5762{ 5763 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5764 uint16_t addr; 5765 5766 addr = table + offset; 5767 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5768 (addr - 1 != pg->pg_ofdmtab_addr)) { 5769 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5770 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5771 } 5772 pg->pg_ofdmtab_addr = addr; 5773 5774 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5775 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5776} 5777 5778static void 5779bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5780 uint16_t value) 5781{ 5782 5783 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5784 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5785} 5786 5787static void 5788bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5789{ 5790 struct bwn_phy *phy = &mac->mac_phy; 5791 struct bwn_softc *sc = mac->mac_sc; 5792 unsigned int i, max_loop; 5793 uint16_t value; 5794 uint32_t buffer[5] = { 5795 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5796 }; 5797 5798 if (ofdm) { 5799 max_loop = 0x1e; 5800 buffer[0] = 0x000201cc; 5801 } else { 5802 max_loop = 0xfa; 5803 buffer[0] = 0x000b846e; 5804 } 5805 5806 BWN_ASSERT_LOCKED(mac->mac_sc); 5807 5808 for (i = 0; i < 5; i++) 5809 bwn_ram_write(mac, i * 4, buffer[i]); 5810 5811 BWN_WRITE_2(mac, 0x0568, 0x0000); 5812 BWN_WRITE_2(mac, 0x07c0, 5813 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5814 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5815 BWN_WRITE_2(mac, 0x050c, value); 5816 if (phy->type == BWN_PHYTYPE_LP) 5817 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5818 BWN_WRITE_2(mac, 0x0508, 0x0000); 5819 BWN_WRITE_2(mac, 0x050a, 0x0000); 5820 BWN_WRITE_2(mac, 0x054c, 0x0000); 5821 BWN_WRITE_2(mac, 0x056a, 0x0014); 5822 BWN_WRITE_2(mac, 0x0568, 0x0826); 5823 BWN_WRITE_2(mac, 0x0500, 0x0000); 5824 if (phy->type == BWN_PHYTYPE_LP) 5825 BWN_WRITE_2(mac, 0x0502, 0x0050); 5826 else 5827 BWN_WRITE_2(mac, 0x0502, 0x0030); 5828 5829 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5830 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5831 for (i = 0x00; i < max_loop; i++) { 5832 value = BWN_READ_2(mac, 0x050e); 5833 if (value & 0x0080) 5834 break; 5835 DELAY(10); 5836 } 5837 for (i = 0x00; i < 0x0a; i++) { 5838 value = BWN_READ_2(mac, 0x050e); 5839 if (value & 0x0400) 5840 break; 5841 DELAY(10); 5842 } 5843 for (i = 0x00; i < 0x19; i++) { 5844 value = BWN_READ_2(mac, 0x0690); 5845 if (!(value & 0x0100)) 5846 break; 5847 DELAY(10); 5848 } 5849 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5850 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5851} 5852 5853static void 5854bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5855{ 5856 uint32_t macctl; 5857 5858 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5859 5860 macctl = BWN_READ_4(mac, BWN_MACCTL); 5861 if (macctl & BWN_MACCTL_BIGENDIAN) 5862 printf("TODO: need swap\n"); 5863 5864 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5865 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5866 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5867} 5868 5869static void 5870bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5871{ 5872 uint16_t value; 5873 5874 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5875 ("%s:%d: fail", __func__, __LINE__)); 5876 5877 value = (uint8_t) (ctl->q); 5878 value |= ((uint8_t) (ctl->i)) << 8; 5879 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5880} 5881 5882static uint16_t 5883bwn_lo_calcfeed(struct bwn_mac *mac, 5884 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5885{ 5886 struct bwn_phy *phy = &mac->mac_phy; 5887 struct bwn_softc *sc = mac->mac_sc; 5888 uint16_t rfover; 5889 uint16_t feedthrough; 5890 5891 if (phy->gmode) { 5892 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5893 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5894 5895 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5896 ("%s:%d: fail", __func__, __LINE__)); 5897 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5898 ("%s:%d: fail", __func__, __LINE__)); 5899 5900 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5901 5902 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5903 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5904 phy->rev > 6) 5905 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5906 5907 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5908 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5909 DELAY(10); 5910 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5911 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5912 DELAY(10); 5913 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5914 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5915 DELAY(10); 5916 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5917 } else { 5918 pga |= BWN_PHY_PGACTL_UNKNOWN; 5919 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5920 DELAY(10); 5921 pga |= BWN_PHY_PGACTL_LOWBANDW; 5922 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5923 DELAY(10); 5924 pga |= BWN_PHY_PGACTL_LPF; 5925 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5926 } 5927 DELAY(21); 5928 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5929 5930 return (feedthrough); 5931} 5932 5933static uint16_t 5934bwn_lo_txctl_regtable(struct bwn_mac *mac, 5935 uint16_t *value, uint16_t *pad_mix_gain) 5936{ 5937 struct bwn_phy *phy = &mac->mac_phy; 5938 uint16_t reg, v, padmix; 5939 5940 if (phy->type == BWN_PHYTYPE_B) { 5941 v = 0x30; 5942 if (phy->rf_rev <= 5) { 5943 reg = 0x43; 5944 padmix = 0; 5945 } else { 5946 reg = 0x52; 5947 padmix = 5; 5948 } 5949 } else { 5950 if (phy->rev >= 2 && phy->rf_rev == 8) { 5951 reg = 0x43; 5952 v = 0x10; 5953 padmix = 2; 5954 } else { 5955 reg = 0x52; 5956 v = 0x30; 5957 padmix = 5; 5958 } 5959 } 5960 if (value) 5961 *value = v; 5962 if (pad_mix_gain) 5963 *pad_mix_gain = padmix; 5964 5965 return (reg); 5966} 5967 5968static void 5969bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5970{ 5971 struct bwn_phy *phy = &mac->mac_phy; 5972 struct bwn_phy_g *pg = &phy->phy_g; 5973 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5974 uint16_t reg, mask; 5975 uint16_t trsw_rx, pga; 5976 uint16_t rf_pctl_reg; 5977 5978 static const uint8_t tx_bias_values[] = { 5979 0x09, 0x08, 0x0a, 0x01, 0x00, 5980 0x02, 0x05, 0x04, 0x06, 5981 }; 5982 static const uint8_t tx_magn_values[] = { 5983 0x70, 0x40, 5984 }; 5985 5986 if (!BWN_HAS_LOOPBACK(phy)) { 5987 rf_pctl_reg = 6; 5988 trsw_rx = 2; 5989 pga = 0; 5990 } else { 5991 int lb_gain; 5992 5993 trsw_rx = 0; 5994 lb_gain = pg->pg_max_lb_gain / 2; 5995 if (lb_gain > 10) { 5996 rf_pctl_reg = 0; 5997 pga = abs(10 - lb_gain) / 6; 5998 pga = MIN(MAX(pga, 0), 15); 5999 } else { 6000 int cmp_val; 6001 int tmp; 6002 6003 pga = 0; 6004 cmp_val = 0x24; 6005 if ((phy->rev >= 2) && 6006 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6007 cmp_val = 0x3c; 6008 tmp = lb_gain; 6009 if ((10 - lb_gain) < cmp_val) 6010 tmp = (10 - lb_gain); 6011 if (tmp < 0) 6012 tmp += 6; 6013 else 6014 tmp += 3; 6015 cmp_val /= 4; 6016 tmp /= 4; 6017 if (tmp >= cmp_val) 6018 rf_pctl_reg = cmp_val; 6019 else 6020 rf_pctl_reg = tmp; 6021 } 6022 } 6023 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6024 bwn_phy_g_set_bbatt(mac, 2); 6025 6026 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6027 mask = ~mask; 6028 BWN_RF_MASK(mac, reg, mask); 6029 6030 if (BWN_HAS_TXMAG(phy)) { 6031 int i, j; 6032 int feedthrough; 6033 int min_feedth = 0xffff; 6034 uint8_t tx_magn, tx_bias; 6035 6036 for (i = 0; i < N(tx_magn_values); i++) { 6037 tx_magn = tx_magn_values[i]; 6038 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6039 for (j = 0; j < N(tx_bias_values); j++) { 6040 tx_bias = tx_bias_values[j]; 6041 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6042 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6043 trsw_rx); 6044 if (feedthrough < min_feedth) { 6045 lo->tx_bias = tx_bias; 6046 lo->tx_magn = tx_magn; 6047 min_feedth = feedthrough; 6048 } 6049 if (lo->tx_bias == 0) 6050 break; 6051 } 6052 BWN_RF_WRITE(mac, 0x52, 6053 (BWN_RF_READ(mac, 0x52) 6054 & 0xff00) | lo->tx_bias | lo-> 6055 tx_magn); 6056 } 6057 } else { 6058 lo->tx_magn = 0; 6059 lo->tx_bias = 0; 6060 BWN_RF_MASK(mac, 0x52, 0xfff0); 6061 } 6062 6063 BWN_GETTIME(lo->txctl_measured_time); 6064} 6065 6066static void 6067bwn_lo_get_powervector(struct bwn_mac *mac) 6068{ 6069 struct bwn_phy *phy = &mac->mac_phy; 6070 struct bwn_phy_g *pg = &phy->phy_g; 6071 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6072 int i; 6073 uint64_t tmp; 6074 uint64_t power_vector = 0; 6075 6076 for (i = 0; i < 8; i += 2) { 6077 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6078 power_vector |= (tmp << (i * 8)); 6079 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6080 } 6081 if (power_vector) 6082 lo->power_vector = power_vector; 6083 6084 BWN_GETTIME(lo->pwr_vec_read_time); 6085} 6086 6087static void 6088bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6089 int use_trsw_rx) 6090{ 6091 struct bwn_phy *phy = &mac->mac_phy; 6092 struct bwn_phy_g *pg = &phy->phy_g; 6093 uint16_t tmp; 6094 6095 if (max_rx_gain < 0) 6096 max_rx_gain = 0; 6097 6098 if (BWN_HAS_LOOPBACK(phy)) { 6099 int trsw_rx = 0; 6100 int trsw_rx_gain; 6101 6102 if (use_trsw_rx) { 6103 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6104 if (max_rx_gain >= trsw_rx_gain) { 6105 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6106 trsw_rx = 0x20; 6107 } 6108 } else 6109 trsw_rx_gain = max_rx_gain; 6110 if (trsw_rx_gain < 9) { 6111 pg->pg_lna_lod_gain = 0; 6112 } else { 6113 pg->pg_lna_lod_gain = 1; 6114 trsw_rx_gain -= 8; 6115 } 6116 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6117 pg->pg_pga_gain = trsw_rx_gain / 3; 6118 if (pg->pg_pga_gain >= 5) { 6119 pg->pg_pga_gain -= 5; 6120 pg->pg_lna_gain = 2; 6121 } else 6122 pg->pg_lna_gain = 0; 6123 } else { 6124 pg->pg_lna_gain = 0; 6125 pg->pg_trsw_rx_gain = 0x20; 6126 if (max_rx_gain >= 0x14) { 6127 pg->pg_lna_lod_gain = 1; 6128 pg->pg_pga_gain = 2; 6129 } else if (max_rx_gain >= 0x12) { 6130 pg->pg_lna_lod_gain = 1; 6131 pg->pg_pga_gain = 1; 6132 } else if (max_rx_gain >= 0xf) { 6133 pg->pg_lna_lod_gain = 1; 6134 pg->pg_pga_gain = 0; 6135 } else { 6136 pg->pg_lna_lod_gain = 0; 6137 pg->pg_pga_gain = 0; 6138 } 6139 } 6140 6141 tmp = BWN_RF_READ(mac, 0x7a); 6142 if (pg->pg_lna_lod_gain == 0) 6143 tmp &= ~0x0008; 6144 else 6145 tmp |= 0x0008; 6146 BWN_RF_WRITE(mac, 0x7a, tmp); 6147} 6148 6149static void 6150bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6151{ 6152 struct bwn_phy *phy = &mac->mac_phy; 6153 struct bwn_phy_g *pg = &phy->phy_g; 6154 struct bwn_softc *sc = mac->mac_sc; 6155 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6156 struct timespec ts; 6157 uint16_t tmp; 6158 6159 if (bwn_has_hwpctl(mac)) { 6160 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6161 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6162 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6163 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6164 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6165 6166 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6167 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6168 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6169 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6170 } 6171 if (phy->type == BWN_PHYTYPE_B && 6172 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6173 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6174 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6175 } 6176 if (phy->rev >= 2) { 6177 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6178 sav->phy_analogoverval = 6179 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6180 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6181 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6182 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6183 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6184 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6185 6186 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6187 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6188 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6189 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6190 if (phy->type == BWN_PHYTYPE_G) { 6191 if ((phy->rev >= 7) && 6192 (siba_sprom_get_bf_lo(sc->sc_dev) & 6193 BWN_BFL_EXTLNA)) { 6194 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6195 } else { 6196 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6197 } 6198 } else { 6199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6200 } 6201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6202 } 6203 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6204 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6205 sav->rf0 = BWN_RF_READ(mac, 0x43); 6206 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6207 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6208 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6209 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6210 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6211 6212 if (!BWN_HAS_TXMAG(phy)) { 6213 sav->rf2 = BWN_RF_READ(mac, 0x52); 6214 sav->rf2 &= 0x00f0; 6215 } 6216 if (phy->type == BWN_PHYTYPE_B) { 6217 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6218 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6219 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6220 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6221 } else { 6222 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6223 | 0x8000); 6224 } 6225 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6226 & 0xf000); 6227 6228 tmp = 6229 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6230 BWN_PHY_WRITE(mac, tmp, 0x007f); 6231 6232 tmp = sav->phy_syncctl; 6233 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6234 tmp = sav->rf1; 6235 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6236 6237 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6238 if (phy->type == BWN_PHYTYPE_G || 6239 (phy->type == BWN_PHYTYPE_B && 6240 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6241 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6242 } else 6243 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6244 if (phy->rev >= 2) 6245 bwn_dummy_transmission(mac, 0, 1); 6246 bwn_phy_g_switch_chan(mac, 6, 0); 6247 BWN_RF_READ(mac, 0x51); 6248 if (phy->type == BWN_PHYTYPE_G) 6249 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6250 6251 nanouptime(&ts); 6252 if (time_before(lo->txctl_measured_time, 6253 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6254 bwn_lo_measure_txctl_values(mac); 6255 6256 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6257 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6258 else { 6259 if (phy->type == BWN_PHYTYPE_B) 6260 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6261 else 6262 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6263 } 6264} 6265 6266static void 6267bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6268{ 6269 struct bwn_phy *phy = &mac->mac_phy; 6270 struct bwn_phy_g *pg = &phy->phy_g; 6271 uint16_t tmp; 6272 6273 if (phy->rev >= 2) { 6274 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6275 tmp = (pg->pg_pga_gain << 8); 6276 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6277 DELAY(5); 6278 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6279 DELAY(2); 6280 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6281 } else { 6282 tmp = (pg->pg_pga_gain | 0xefa0); 6283 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6284 } 6285 if (phy->type == BWN_PHYTYPE_G) { 6286 if (phy->rev >= 3) 6287 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6288 else 6289 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6290 if (phy->rev >= 2) 6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6292 else 6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6294 } 6295 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6296 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6298 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6299 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6300 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6301 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6302 if (!BWN_HAS_TXMAG(phy)) { 6303 tmp = sav->rf2; 6304 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6305 } 6306 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6307 if (phy->type == BWN_PHYTYPE_B && 6308 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6309 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6310 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6311 } 6312 if (phy->rev >= 2) { 6313 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6314 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6315 sav->phy_analogoverval); 6316 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6317 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6318 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6319 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6320 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6321 } 6322 if (bwn_has_hwpctl(mac)) { 6323 tmp = (sav->phy_lomask & 0xbfff); 6324 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6325 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6326 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6327 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6328 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6329 } 6330 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6331} 6332 6333static int 6334bwn_lo_probe_loctl(struct bwn_mac *mac, 6335 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6336{ 6337 struct bwn_phy *phy = &mac->mac_phy; 6338 struct bwn_phy_g *pg = &phy->phy_g; 6339 struct bwn_loctl orig, test; 6340 struct bwn_loctl prev = { -100, -100 }; 6341 static const struct bwn_loctl modifiers[] = { 6342 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6343 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6344 }; 6345 int begin, end, lower = 0, i; 6346 uint16_t feedth; 6347 6348 if (d->curstate == 0) { 6349 begin = 1; 6350 end = 8; 6351 } else if (d->curstate % 2 == 0) { 6352 begin = d->curstate - 1; 6353 end = d->curstate + 1; 6354 } else { 6355 begin = d->curstate - 2; 6356 end = d->curstate + 2; 6357 } 6358 if (begin < 1) 6359 begin += 8; 6360 if (end > 8) 6361 end -= 8; 6362 6363 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6364 i = begin; 6365 d->curstate = i; 6366 while (1) { 6367 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6368 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6369 test.i += modifiers[i - 1].i * d->multipler; 6370 test.q += modifiers[i - 1].q * d->multipler; 6371 if ((test.i != prev.i || test.q != prev.q) && 6372 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6373 bwn_lo_write(mac, &test); 6374 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6375 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6376 if (feedth < d->feedth) { 6377 memcpy(probe, &test, 6378 sizeof(struct bwn_loctl)); 6379 lower = 1; 6380 d->feedth = feedth; 6381 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6382 break; 6383 } 6384 } 6385 memcpy(&prev, &test, sizeof(prev)); 6386 if (i == end) 6387 break; 6388 if (i == 8) 6389 i = 1; 6390 else 6391 i++; 6392 d->curstate = i; 6393 } 6394 6395 return (lower); 6396} 6397 6398static void 6399bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6400{ 6401 struct bwn_phy *phy = &mac->mac_phy; 6402 struct bwn_phy_g *pg = &phy->phy_g; 6403 struct bwn_lo_g_sm d; 6404 struct bwn_loctl probe; 6405 int lower, repeat, cnt = 0; 6406 uint16_t feedth; 6407 6408 d.nmeasure = 0; 6409 d.multipler = 1; 6410 if (BWN_HAS_LOOPBACK(phy)) 6411 d.multipler = 3; 6412 6413 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6414 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6415 6416 do { 6417 bwn_lo_write(mac, &d.loctl); 6418 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6419 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6420 if (feedth < 0x258) { 6421 if (feedth >= 0x12c) 6422 *rxgain += 6; 6423 else 6424 *rxgain += 3; 6425 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6426 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6427 } 6428 d.feedth = feedth; 6429 d.curstate = 0; 6430 do { 6431 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6432 ("%s:%d: fail", __func__, __LINE__)); 6433 memcpy(&probe, &d.loctl, 6434 sizeof(struct bwn_loctl)); 6435 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6436 if (!lower) 6437 break; 6438 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6439 break; 6440 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6441 d.nmeasure++; 6442 } while (d.nmeasure < 24); 6443 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6444 6445 if (BWN_HAS_LOOPBACK(phy)) { 6446 if (d.feedth > 0x1194) 6447 *rxgain -= 6; 6448 else if (d.feedth < 0x5dc) 6449 *rxgain += 3; 6450 if (cnt == 0) { 6451 if (d.feedth <= 0x5dc) { 6452 d.multipler = 1; 6453 cnt++; 6454 } else 6455 d.multipler = 2; 6456 } else if (cnt == 2) 6457 d.multipler = 1; 6458 } 6459 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6460 } while (++cnt < repeat); 6461} 6462 6463static struct bwn_lo_calib * 6464bwn_lo_calibset(struct bwn_mac *mac, 6465 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6466{ 6467 struct bwn_phy *phy = &mac->mac_phy; 6468 struct bwn_phy_g *pg = &phy->phy_g; 6469 struct bwn_loctl loctl = { 0, 0 }; 6470 struct bwn_lo_calib *cal; 6471 struct bwn_lo_g_value sval = { 0 }; 6472 int rxgain; 6473 uint16_t pad, reg, value; 6474 6475 sval.old_channel = phy->chan; 6476 bwn_mac_suspend(mac); 6477 bwn_lo_save(mac, &sval); 6478 6479 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6480 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6481 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6482 6483 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6484 if (rfatt->padmix) 6485 rxgain -= pad; 6486 if (BWN_HAS_LOOPBACK(phy)) 6487 rxgain += pg->pg_max_lb_gain; 6488 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6489 bwn_phy_g_set_bbatt(mac, bbatt->att); 6490 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6491 6492 bwn_lo_restore(mac, &sval); 6493 bwn_mac_enable(mac); 6494 6495 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6496 if (!cal) { 6497 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6498 return (NULL); 6499 } 6500 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6501 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6502 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6503 6504 BWN_GETTIME(cal->calib_time); 6505 6506 return (cal); 6507} 6508 6509static struct bwn_lo_calib * 6510bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6511 const struct bwn_rfatt *rfatt) 6512{ 6513 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6514 struct bwn_lo_calib *c; 6515 6516 TAILQ_FOREACH(c, &lo->calib_list, list) { 6517 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6518 continue; 6519 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6520 continue; 6521 return (c); 6522 } 6523 6524 c = bwn_lo_calibset(mac, bbatt, rfatt); 6525 if (!c) 6526 return (NULL); 6527 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6528 6529 return (c); 6530} 6531 6532static void 6533bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6534{ 6535 struct bwn_phy *phy = &mac->mac_phy; 6536 struct bwn_phy_g *pg = &phy->phy_g; 6537 struct bwn_softc *sc = mac->mac_sc; 6538 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6539 const struct bwn_rfatt *rfatt; 6540 const struct bwn_bbatt *bbatt; 6541 uint64_t pvector; 6542 int i; 6543 int rf_offset, bb_offset; 6544 uint8_t changed = 0; 6545 6546 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6547 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6548 ("%s:%d: fail", __func__, __LINE__)); 6549 6550 pvector = lo->power_vector; 6551 if (!update && !pvector) 6552 return; 6553 6554 bwn_mac_suspend(mac); 6555 6556 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6557 struct bwn_lo_calib *cal; 6558 int idx; 6559 uint16_t val; 6560 6561 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6562 continue; 6563 bb_offset = i / lo->rfatt.len; 6564 rf_offset = i % lo->rfatt.len; 6565 bbatt = &(lo->bbatt.array[bb_offset]); 6566 rfatt = &(lo->rfatt.array[rf_offset]); 6567 6568 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6569 if (!cal) { 6570 device_printf(sc->sc_dev, "LO: Could not " 6571 "calibrate DC table entry\n"); 6572 continue; 6573 } 6574 val = (uint8_t)(cal->ctl.q); 6575 val |= ((uint8_t)(cal->ctl.i)) << 4; 6576 free(cal, M_DEVBUF); 6577 6578 idx = i / 2; 6579 if (i % 2) 6580 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6581 | ((val & 0x00ff) << 8); 6582 else 6583 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6584 | (val & 0x00ff); 6585 changed = 1; 6586 } 6587 if (changed) { 6588 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6589 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6590 } 6591 bwn_mac_enable(mac); 6592} 6593 6594static void 6595bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6596{ 6597 6598 if (!rf->padmix) 6599 return; 6600 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6601 rf->att = 4; 6602} 6603 6604static void 6605bwn_lo_g_adjust(struct bwn_mac *mac) 6606{ 6607 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6608 struct bwn_lo_calib *cal; 6609 struct bwn_rfatt rf; 6610 6611 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6612 bwn_lo_fixup_rfatt(&rf); 6613 6614 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6615 if (!cal) 6616 return; 6617 bwn_lo_write(mac, &cal->ctl); 6618} 6619 6620static void 6621bwn_lo_g_init(struct bwn_mac *mac) 6622{ 6623 6624 if (!bwn_has_hwpctl(mac)) 6625 return; 6626 6627 bwn_lo_get_powervector(mac); 6628 bwn_phy_g_dc_lookup_init(mac, 1); 6629} 6630 6631static void 6632bwn_mac_suspend(struct bwn_mac *mac) 6633{ 6634 struct bwn_softc *sc = mac->mac_sc; 6635 int i; 6636 uint32_t tmp; 6637 6638 KASSERT(mac->mac_suspended >= 0, 6639 ("%s:%d: fail", __func__, __LINE__)); 6640 6641 if (mac->mac_suspended == 0) { 6642 bwn_psctl(mac, BWN_PS_AWAKE); 6643 BWN_WRITE_4(mac, BWN_MACCTL, 6644 BWN_READ_4(mac, BWN_MACCTL) 6645 & ~BWN_MACCTL_ON); 6646 BWN_READ_4(mac, BWN_MACCTL); 6647 for (i = 35; i; i--) { 6648 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6649 if (tmp & BWN_INTR_MAC_SUSPENDED) 6650 goto out; 6651 DELAY(10); 6652 } 6653 for (i = 40; i; i--) { 6654 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6655 if (tmp & BWN_INTR_MAC_SUSPENDED) 6656 goto out; 6657 DELAY(1000); 6658 } 6659 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6660 } 6661out: 6662 mac->mac_suspended++; 6663} 6664 6665static void 6666bwn_mac_enable(struct bwn_mac *mac) 6667{ 6668 struct bwn_softc *sc = mac->mac_sc; 6669 uint16_t state; 6670 6671 state = bwn_shm_read_2(mac, BWN_SHARED, 6672 BWN_SHARED_UCODESTAT); 6673 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6674 state != BWN_SHARED_UCODESTAT_SLEEP) 6675 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6676 6677 mac->mac_suspended--; 6678 KASSERT(mac->mac_suspended >= 0, 6679 ("%s:%d: fail", __func__, __LINE__)); 6680 if (mac->mac_suspended == 0) { 6681 BWN_WRITE_4(mac, BWN_MACCTL, 6682 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6683 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6684 BWN_READ_4(mac, BWN_MACCTL); 6685 BWN_READ_4(mac, BWN_INTR_REASON); 6686 bwn_psctl(mac, 0); 6687 } 6688} 6689 6690static void 6691bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6692{ 6693 struct bwn_softc *sc = mac->mac_sc; 6694 int i; 6695 uint16_t ucstat; 6696 6697 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6698 ("%s:%d: fail", __func__, __LINE__)); 6699 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6700 ("%s:%d: fail", __func__, __LINE__)); 6701 6702 /* XXX forcibly awake and hwps-off */ 6703 6704 BWN_WRITE_4(mac, BWN_MACCTL, 6705 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6706 ~BWN_MACCTL_HWPS); 6707 BWN_READ_4(mac, BWN_MACCTL); 6708 if (siba_get_revid(sc->sc_dev) >= 5) { 6709 for (i = 0; i < 100; i++) { 6710 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6711 BWN_SHARED_UCODESTAT); 6712 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6713 break; 6714 DELAY(10); 6715 } 6716 } 6717} 6718 6719static int16_t 6720bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6721{ 6722 6723 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6724 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6725} 6726 6727static void 6728bwn_nrssi_threshold(struct bwn_mac *mac) 6729{ 6730 struct bwn_phy *phy = &mac->mac_phy; 6731 struct bwn_phy_g *pg = &phy->phy_g; 6732 struct bwn_softc *sc = mac->mac_sc; 6733 int32_t a, b; 6734 int16_t tmp16; 6735 uint16_t tmpu16; 6736 6737 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6738 6739 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6740 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6741 a = 0x13; 6742 b = 0x12; 6743 } else { 6744 a = 0xe; 6745 b = 0x11; 6746 } 6747 6748 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6749 a += (pg->pg_nrssi[0] << 6); 6750 a += (a < 32) ? 31 : 32; 6751 a = a >> 6; 6752 a = MIN(MAX(a, -31), 31); 6753 6754 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6755 b += (pg->pg_nrssi[0] << 6); 6756 if (b < 32) 6757 b += 31; 6758 else 6759 b += 32; 6760 b = b >> 6; 6761 b = MIN(MAX(b, -31), 31); 6762 6763 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6764 tmpu16 |= ((uint32_t)b & 0x0000003f); 6765 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6766 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6767 return; 6768 } 6769 6770 tmp16 = bwn_nrssi_read(mac, 0x20); 6771 if (tmp16 >= 0x20) 6772 tmp16 -= 0x40; 6773 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6774} 6775 6776static void 6777bwn_nrssi_slope_11g(struct bwn_mac *mac) 6778{ 6779#define SAVE_RF_MAX 3 6780#define SAVE_PHY_COMM_MAX 4 6781#define SAVE_PHY3_MAX 8 6782 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6783 { 0x7a, 0x52, 0x43 }; 6784 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6785 { 0x15, 0x5a, 0x59, 0x58 }; 6786 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6787 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6788 0x0801, 0x0060, 0x0014, 0x0478 6789 }; 6790 struct bwn_phy *phy = &mac->mac_phy; 6791 struct bwn_phy_g *pg = &phy->phy_g; 6792 int32_t i, tmp32, phy3_idx = 0; 6793 uint16_t delta, tmp; 6794 uint16_t save_rf[SAVE_RF_MAX]; 6795 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6796 uint16_t save_phy3[SAVE_PHY3_MAX]; 6797 uint16_t ant_div, phy0, chan_ex; 6798 int16_t nrssi0, nrssi1; 6799 6800 KASSERT(phy->type == BWN_PHYTYPE_G, 6801 ("%s:%d: fail", __func__, __LINE__)); 6802 6803 if (phy->rf_rev >= 9) 6804 return; 6805 if (phy->rf_rev == 8) 6806 bwn_nrssi_offset(mac); 6807 6808 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6809 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6810 6811 /* 6812 * Save RF/PHY registers for later restoration 6813 */ 6814 ant_div = BWN_READ_2(mac, 0x03e2); 6815 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6816 for (i = 0; i < SAVE_RF_MAX; ++i) 6817 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6818 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6819 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6820 6821 phy0 = BWN_READ_2(mac, BWN_PHY0); 6822 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6823 if (phy->rev >= 3) { 6824 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6825 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6826 BWN_PHY_WRITE(mac, 0x002e, 0); 6827 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6828 switch (phy->rev) { 6829 case 4: 6830 case 6: 6831 case 7: 6832 BWN_PHY_SET(mac, 0x0478, 0x0100); 6833 BWN_PHY_SET(mac, 0x0801, 0x0040); 6834 break; 6835 case 3: 6836 case 5: 6837 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6838 break; 6839 } 6840 BWN_PHY_SET(mac, 0x0060, 0x0040); 6841 BWN_PHY_SET(mac, 0x0014, 0x0200); 6842 } 6843 /* 6844 * Calculate nrssi0 6845 */ 6846 BWN_RF_SET(mac, 0x007a, 0x0070); 6847 bwn_set_all_gains(mac, 0, 8, 0); 6848 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6849 if (phy->rev >= 2) { 6850 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6851 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6852 } 6853 BWN_RF_SET(mac, 0x007a, 0x0080); 6854 DELAY(20); 6855 6856 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6857 if (nrssi0 >= 0x0020) 6858 nrssi0 -= 0x0040; 6859 6860 /* 6861 * Calculate nrssi1 6862 */ 6863 BWN_RF_MASK(mac, 0x007a, 0x007f); 6864 if (phy->rev >= 2) 6865 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6866 6867 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6868 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6869 BWN_RF_SET(mac, 0x007a, 0x000f); 6870 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6871 if (phy->rev >= 2) { 6872 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6873 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6874 } 6875 6876 bwn_set_all_gains(mac, 3, 0, 1); 6877 if (phy->rf_rev == 8) { 6878 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6879 } else { 6880 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6881 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6882 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6883 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6884 } 6885 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6886 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6887 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6888 DELAY(20); 6889 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6890 6891 /* 6892 * Install calculated narrow RSSI values 6893 */ 6894 if (nrssi1 >= 0x0020) 6895 nrssi1 -= 0x0040; 6896 if (nrssi0 == nrssi1) 6897 pg->pg_nrssi_slope = 0x00010000; 6898 else 6899 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6900 if (nrssi0 >= -4) { 6901 pg->pg_nrssi[0] = nrssi1; 6902 pg->pg_nrssi[1] = nrssi0; 6903 } 6904 6905 /* 6906 * Restore saved RF/PHY registers 6907 */ 6908 if (phy->rev >= 3) { 6909 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6910 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6911 save_phy3[phy3_idx]); 6912 } 6913 } 6914 if (phy->rev >= 2) { 6915 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6916 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6917 } 6918 6919 for (i = 0; i < SAVE_RF_MAX; ++i) 6920 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6921 6922 BWN_WRITE_2(mac, 0x03e2, ant_div); 6923 BWN_WRITE_2(mac, 0x03e6, phy0); 6924 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6925 6926 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6927 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6928 6929 bwn_spu_workaround(mac, phy->chan); 6930 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6931 bwn_set_original_gains(mac); 6932 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6933 if (phy->rev >= 3) { 6934 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6935 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6936 save_phy3[phy3_idx]); 6937 } 6938 } 6939 6940 delta = 0x1f - pg->pg_nrssi[0]; 6941 for (i = 0; i < 64; i++) { 6942 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6943 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6944 pg->pg_nrssi_lt[i] = tmp32; 6945 } 6946 6947 bwn_nrssi_threshold(mac); 6948#undef SAVE_RF_MAX 6949#undef SAVE_PHY_COMM_MAX 6950#undef SAVE_PHY3_MAX 6951} 6952 6953static void 6954bwn_nrssi_offset(struct bwn_mac *mac) 6955{ 6956#define SAVE_RF_MAX 2 6957#define SAVE_PHY_COMM_MAX 10 6958#define SAVE_PHY6_MAX 8 6959 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6960 { 0x7a, 0x43 }; 6961 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6962 0x0001, 0x0811, 0x0812, 0x0814, 6963 0x0815, 0x005a, 0x0059, 0x0058, 6964 0x000a, 0x0003 6965 }; 6966 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6967 0x002e, 0x002f, 0x080f, 0x0810, 6968 0x0801, 0x0060, 0x0014, 0x0478 6969 }; 6970 struct bwn_phy *phy = &mac->mac_phy; 6971 int i, phy6_idx = 0; 6972 uint16_t save_rf[SAVE_RF_MAX]; 6973 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6974 uint16_t save_phy6[SAVE_PHY6_MAX]; 6975 int16_t nrssi; 6976 uint16_t saved = 0xffff; 6977 6978 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6979 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6980 for (i = 0; i < SAVE_RF_MAX; ++i) 6981 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6982 6983 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6984 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6985 BWN_PHY_SET(mac, 0x0811, 0x000c); 6986 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6987 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6988 if (phy->rev >= 6) { 6989 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6990 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6991 6992 BWN_PHY_WRITE(mac, 0x002e, 0); 6993 BWN_PHY_WRITE(mac, 0x002f, 0); 6994 BWN_PHY_WRITE(mac, 0x080f, 0); 6995 BWN_PHY_WRITE(mac, 0x0810, 0); 6996 BWN_PHY_SET(mac, 0x0478, 0x0100); 6997 BWN_PHY_SET(mac, 0x0801, 0x0040); 6998 BWN_PHY_SET(mac, 0x0060, 0x0040); 6999 BWN_PHY_SET(mac, 0x0014, 0x0200); 7000 } 7001 BWN_RF_SET(mac, 0x007a, 0x0070); 7002 BWN_RF_SET(mac, 0x007a, 0x0080); 7003 DELAY(30); 7004 7005 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7006 if (nrssi >= 0x20) 7007 nrssi -= 0x40; 7008 if (nrssi == 31) { 7009 for (i = 7; i >= 4; i--) { 7010 BWN_RF_WRITE(mac, 0x007b, i); 7011 DELAY(20); 7012 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7013 0x003f); 7014 if (nrssi >= 0x20) 7015 nrssi -= 0x40; 7016 if (nrssi < 31 && saved == 0xffff) 7017 saved = i; 7018 } 7019 if (saved == 0xffff) 7020 saved = 4; 7021 } else { 7022 BWN_RF_MASK(mac, 0x007a, 0x007f); 7023 if (phy->rev != 1) { 7024 BWN_PHY_SET(mac, 0x0814, 0x0001); 7025 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7026 } 7027 BWN_PHY_SET(mac, 0x0811, 0x000c); 7028 BWN_PHY_SET(mac, 0x0812, 0x000c); 7029 BWN_PHY_SET(mac, 0x0811, 0x0030); 7030 BWN_PHY_SET(mac, 0x0812, 0x0030); 7031 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7032 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7033 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7034 if (phy->rev == 0) 7035 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7036 else 7037 BWN_PHY_SET(mac, 0x000a, 0x2000); 7038 if (phy->rev != 1) { 7039 BWN_PHY_SET(mac, 0x0814, 0x0004); 7040 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7041 } 7042 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7043 BWN_RF_SET(mac, 0x007a, 0x000f); 7044 bwn_set_all_gains(mac, 3, 0, 1); 7045 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7046 DELAY(30); 7047 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7048 if (nrssi >= 0x20) 7049 nrssi -= 0x40; 7050 if (nrssi == -32) { 7051 for (i = 0; i < 4; i++) { 7052 BWN_RF_WRITE(mac, 0x007b, i); 7053 DELAY(20); 7054 nrssi = (int16_t)((BWN_PHY_READ(mac, 7055 0x047f) >> 8) & 0x003f); 7056 if (nrssi >= 0x20) 7057 nrssi -= 0x40; 7058 if (nrssi > -31 && saved == 0xffff) 7059 saved = i; 7060 } 7061 if (saved == 0xffff) 7062 saved = 3; 7063 } else 7064 saved = 0; 7065 } 7066 BWN_RF_WRITE(mac, 0x007b, saved); 7067 7068 /* 7069 * Restore saved RF/PHY registers 7070 */ 7071 if (phy->rev >= 6) { 7072 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7073 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7074 save_phy6[phy6_idx]); 7075 } 7076 } 7077 if (phy->rev != 1) { 7078 for (i = 3; i < 5; i++) 7079 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7080 save_phy_comm[i]); 7081 } 7082 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7083 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7084 7085 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7086 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7087 7088 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7089 BWN_PHY_SET(mac, 0x0429, 0x8000); 7090 bwn_set_original_gains(mac); 7091 if (phy->rev >= 6) { 7092 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7093 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7094 save_phy6[phy6_idx]); 7095 } 7096 } 7097 7098 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7099 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7100 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7101} 7102 7103static void 7104bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7105 int16_t third) 7106{ 7107 struct bwn_phy *phy = &mac->mac_phy; 7108 uint16_t i; 7109 uint16_t start = 0x08, end = 0x18; 7110 uint16_t tmp; 7111 uint16_t table; 7112 7113 if (phy->rev <= 1) { 7114 start = 0x10; 7115 end = 0x20; 7116 } 7117 7118 table = BWN_OFDMTAB_GAINX; 7119 if (phy->rev <= 1) 7120 table = BWN_OFDMTAB_GAINX_R1; 7121 for (i = 0; i < 4; i++) 7122 bwn_ofdmtab_write_2(mac, table, i, first); 7123 7124 for (i = start; i < end; i++) 7125 bwn_ofdmtab_write_2(mac, table, i, second); 7126 7127 if (third != -1) { 7128 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7129 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7130 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7131 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7132 } 7133 bwn_dummy_transmission(mac, 0, 1); 7134} 7135 7136static void 7137bwn_set_original_gains(struct bwn_mac *mac) 7138{ 7139 struct bwn_phy *phy = &mac->mac_phy; 7140 uint16_t i, tmp; 7141 uint16_t table; 7142 uint16_t start = 0x0008, end = 0x0018; 7143 7144 if (phy->rev <= 1) { 7145 start = 0x0010; 7146 end = 0x0020; 7147 } 7148 7149 table = BWN_OFDMTAB_GAINX; 7150 if (phy->rev <= 1) 7151 table = BWN_OFDMTAB_GAINX_R1; 7152 for (i = 0; i < 4; i++) { 7153 tmp = (i & 0xfffc); 7154 tmp |= (i & 0x0001) << 1; 7155 tmp |= (i & 0x0002) >> 1; 7156 7157 bwn_ofdmtab_write_2(mac, table, i, tmp); 7158 } 7159 7160 for (i = start; i < end; i++) 7161 bwn_ofdmtab_write_2(mac, table, i, i - start); 7162 7163 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7164 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7165 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7166 bwn_dummy_transmission(mac, 0, 1); 7167} 7168 7169static void 7170bwn_phy_hwpctl_init(struct bwn_mac *mac) 7171{ 7172 struct bwn_phy *phy = &mac->mac_phy; 7173 struct bwn_phy_g *pg = &phy->phy_g; 7174 struct bwn_rfatt old_rfatt, rfatt; 7175 struct bwn_bbatt old_bbatt, bbatt; 7176 struct bwn_softc *sc = mac->mac_sc; 7177 uint8_t old_txctl = 0; 7178 7179 KASSERT(phy->type == BWN_PHYTYPE_G, 7180 ("%s:%d: fail", __func__, __LINE__)); 7181 7182 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7183 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7184 return; 7185 7186 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7187 7188 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7189 7190 if (!phy->gmode) 7191 return; 7192 bwn_hwpctl_early_init(mac); 7193 if (pg->pg_curtssi == 0) { 7194 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7195 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7196 } else { 7197 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7198 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7199 old_txctl = pg->pg_txctl; 7200 7201 bbatt.att = 11; 7202 if (phy->rf_rev == 8) { 7203 rfatt.att = 15; 7204 rfatt.padmix = 1; 7205 } else { 7206 rfatt.att = 9; 7207 rfatt.padmix = 0; 7208 } 7209 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7210 } 7211 bwn_dummy_transmission(mac, 0, 1); 7212 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7213 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7214 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7215 else 7216 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7217 &old_rfatt, old_txctl); 7218 } 7219 bwn_hwpctl_init_gphy(mac); 7220 7221 /* clear TSSI */ 7222 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7223 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7224 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7225 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7226} 7227 7228static void 7229bwn_hwpctl_early_init(struct bwn_mac *mac) 7230{ 7231 struct bwn_phy *phy = &mac->mac_phy; 7232 7233 if (!bwn_has_hwpctl(mac)) { 7234 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7235 return; 7236 } 7237 7238 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7239 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7240 BWN_PHY_SET(mac, 0x047c, 0x0002); 7241 BWN_PHY_SET(mac, 0x047a, 0xf000); 7242 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7243 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7244 BWN_PHY_SET(mac, 0x005d, 0x8000); 7245 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7246 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7247 BWN_PHY_SET(mac, 0x0036, 0x0400); 7248 } else { 7249 BWN_PHY_SET(mac, 0x0036, 0x0200); 7250 BWN_PHY_SET(mac, 0x0036, 0x0400); 7251 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7252 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7253 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7254 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7255 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7256 } 7257} 7258 7259static void 7260bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7261{ 7262 struct bwn_phy *phy = &mac->mac_phy; 7263 struct bwn_phy_g *pg = &phy->phy_g; 7264 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7265 int i; 7266 uint16_t nr_written = 0, tmp, value; 7267 uint8_t rf, bb; 7268 7269 if (!bwn_has_hwpctl(mac)) { 7270 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7271 return; 7272 } 7273 7274 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7275 (pg->pg_idletssi - pg->pg_curtssi)); 7276 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7277 (pg->pg_idletssi - pg->pg_curtssi)); 7278 7279 for (i = 0; i < 32; i++) 7280 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7281 for (i = 32; i < 64; i++) 7282 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7283 for (i = 0; i < 64; i += 2) { 7284 value = (uint16_t) pg->pg_tssi2dbm[i]; 7285 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7286 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7287 } 7288 7289 for (rf = 0; rf < lo->rfatt.len; rf++) { 7290 for (bb = 0; bb < lo->bbatt.len; bb++) { 7291 if (nr_written >= 0x40) 7292 return; 7293 tmp = lo->bbatt.array[bb].att; 7294 tmp <<= 8; 7295 if (phy->rf_rev == 8) 7296 tmp |= 0x50; 7297 else 7298 tmp |= 0x40; 7299 tmp |= lo->rfatt.array[rf].att; 7300 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7301 nr_written++; 7302 } 7303 } 7304 7305 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7306 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7307 7308 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7309 BWN_PHY_SET(mac, 0x0478, 0x0800); 7310 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7311 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7312 7313 bwn_phy_g_dc_lookup_init(mac, 1); 7314 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7315} 7316 7317static void 7318bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7319{ 7320 struct bwn_softc *sc = mac->mac_sc; 7321 7322 if (spu != 0) 7323 bwn_spu_workaround(mac, channel); 7324 7325 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7326 7327 if (channel == 14) { 7328 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7329 bwn_hf_write(mac, 7330 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7331 else 7332 bwn_hf_write(mac, 7333 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7334 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7335 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7336 return; 7337 } 7338 7339 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7340 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7341} 7342 7343static uint16_t 7344bwn_phy_g_chan2freq(uint8_t channel) 7345{ 7346 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7347 7348 KASSERT(channel >= 1 && channel <= 14, 7349 ("%s:%d: fail", __func__, __LINE__)); 7350 7351 return (bwn_phy_g_rf_channels[channel - 1]); 7352} 7353 7354static void 7355bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7356 const struct bwn_rfatt *rfatt, uint8_t txctl) 7357{ 7358 struct bwn_phy *phy = &mac->mac_phy; 7359 struct bwn_phy_g *pg = &phy->phy_g; 7360 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7361 uint16_t bb, rf; 7362 uint16_t tx_bias, tx_magn; 7363 7364 bb = bbatt->att; 7365 rf = rfatt->att; 7366 tx_bias = lo->tx_bias; 7367 tx_magn = lo->tx_magn; 7368 if (tx_bias == 0xff) 7369 tx_bias = 0; 7370 7371 pg->pg_txctl = txctl; 7372 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7373 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7374 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7375 bwn_phy_g_set_bbatt(mac, bb); 7376 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7377 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7378 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7379 else { 7380 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7381 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7382 } 7383 if (BWN_HAS_TXMAG(phy)) 7384 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7385 else 7386 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7387 bwn_lo_g_adjust(mac); 7388} 7389 7390static void 7391bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7392 uint16_t bbatt) 7393{ 7394 struct bwn_phy *phy = &mac->mac_phy; 7395 7396 if (phy->analog == 0) { 7397 BWN_WRITE_2(mac, BWN_PHY0, 7398 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7399 return; 7400 } 7401 if (phy->analog > 1) { 7402 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7403 return; 7404 } 7405 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7406} 7407 7408static uint16_t 7409bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7410{ 7411 struct bwn_phy *phy = &mac->mac_phy; 7412 struct bwn_phy_g *pg = &phy->phy_g; 7413 struct bwn_softc *sc = mac->mac_sc; 7414 int max_lb_gain; 7415 uint16_t extlna; 7416 uint16_t i; 7417 7418 if (phy->gmode == 0) 7419 return (0); 7420 7421 if (BWN_HAS_LOOPBACK(phy)) { 7422 max_lb_gain = pg->pg_max_lb_gain; 7423 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7424 if (max_lb_gain >= 0x46) { 7425 extlna = 0x3000; 7426 max_lb_gain -= 0x46; 7427 } else if (max_lb_gain >= 0x3a) { 7428 extlna = 0x1000; 7429 max_lb_gain -= 0x3a; 7430 } else if (max_lb_gain >= 0x2e) { 7431 extlna = 0x2000; 7432 max_lb_gain -= 0x2e; 7433 } else { 7434 extlna = 0; 7435 max_lb_gain -= 0x10; 7436 } 7437 7438 for (i = 0; i < 16; i++) { 7439 max_lb_gain -= (i * 6); 7440 if (max_lb_gain < 6) 7441 break; 7442 } 7443 7444 if ((phy->rev < 7) || 7445 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7446 if (reg == BWN_PHY_RFOVER) { 7447 return (0x1b3); 7448 } else if (reg == BWN_PHY_RFOVERVAL) { 7449 extlna |= (i << 8); 7450 switch (lpd) { 7451 case BWN_LPD(0, 1, 1): 7452 return (0x0f92); 7453 case BWN_LPD(0, 0, 1): 7454 case BWN_LPD(1, 0, 1): 7455 return (0x0092 | extlna); 7456 case BWN_LPD(1, 0, 0): 7457 return (0x0093 | extlna); 7458 } 7459 KASSERT(0 == 1, 7460 ("%s:%d: fail", __func__, __LINE__)); 7461 } 7462 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7463 } else { 7464 if (reg == BWN_PHY_RFOVER) 7465 return (0x9b3); 7466 if (reg == BWN_PHY_RFOVERVAL) { 7467 if (extlna) 7468 extlna |= 0x8000; 7469 extlna |= (i << 8); 7470 switch (lpd) { 7471 case BWN_LPD(0, 1, 1): 7472 return (0x8f92); 7473 case BWN_LPD(0, 0, 1): 7474 return (0x8092 | extlna); 7475 case BWN_LPD(1, 0, 1): 7476 return (0x2092 | extlna); 7477 case BWN_LPD(1, 0, 0): 7478 return (0x2093 | extlna); 7479 } 7480 KASSERT(0 == 1, 7481 ("%s:%d: fail", __func__, __LINE__)); 7482 } 7483 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7484 } 7485 return (0); 7486 } 7487 7488 if ((phy->rev < 7) || 7489 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7490 if (reg == BWN_PHY_RFOVER) { 7491 return (0x1b3); 7492 } else if (reg == BWN_PHY_RFOVERVAL) { 7493 switch (lpd) { 7494 case BWN_LPD(0, 1, 1): 7495 return (0x0fb2); 7496 case BWN_LPD(0, 0, 1): 7497 return (0x00b2); 7498 case BWN_LPD(1, 0, 1): 7499 return (0x30b2); 7500 case BWN_LPD(1, 0, 0): 7501 return (0x30b3); 7502 } 7503 KASSERT(0 == 1, 7504 ("%s:%d: fail", __func__, __LINE__)); 7505 } 7506 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7507 } else { 7508 if (reg == BWN_PHY_RFOVER) { 7509 return (0x9b3); 7510 } else if (reg == BWN_PHY_RFOVERVAL) { 7511 switch (lpd) { 7512 case BWN_LPD(0, 1, 1): 7513 return (0x8fb2); 7514 case BWN_LPD(0, 0, 1): 7515 return (0x80b2); 7516 case BWN_LPD(1, 0, 1): 7517 return (0x20b2); 7518 case BWN_LPD(1, 0, 0): 7519 return (0x20b3); 7520 } 7521 KASSERT(0 == 1, 7522 ("%s:%d: fail", __func__, __LINE__)); 7523 } 7524 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7525 } 7526 return (0); 7527} 7528 7529static void 7530bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7531{ 7532 7533 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7534 return; 7535 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7536 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7537 DELAY(1000); 7538 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7539} 7540 7541static int 7542bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7543{ 7544 struct bwn_softc *sc = mac->mac_sc; 7545 struct bwn_fw *fw = &mac->mac_fw; 7546 const uint8_t rev = siba_get_revid(sc->sc_dev); 7547 const char *filename; 7548 uint32_t high; 7549 int error; 7550 7551 /* microcode */ 7552 if (rev >= 5 && rev <= 10) 7553 filename = "ucode5"; 7554 else if (rev >= 11 && rev <= 12) 7555 filename = "ucode11"; 7556 else if (rev == 13) 7557 filename = "ucode13"; 7558 else if (rev == 14) 7559 filename = "ucode14"; 7560 else if (rev >= 15) 7561 filename = "ucode15"; 7562 else { 7563 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7564 bwn_release_firmware(mac); 7565 return (EOPNOTSUPP); 7566 } 7567 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7568 if (error) { 7569 bwn_release_firmware(mac); 7570 return (error); 7571 } 7572 7573 /* PCM */ 7574 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7575 if (rev >= 5 && rev <= 10) { 7576 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7577 if (error == ENOENT) 7578 fw->no_pcmfile = 1; 7579 else if (error) { 7580 bwn_release_firmware(mac); 7581 return (error); 7582 } 7583 } else if (rev < 11) { 7584 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7585 return (EOPNOTSUPP); 7586 } 7587 7588 /* initvals */ 7589 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7590 switch (mac->mac_phy.type) { 7591 case BWN_PHYTYPE_A: 7592 if (rev < 5 || rev > 10) 7593 goto fail1; 7594 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7595 filename = "a0g1initvals5"; 7596 else 7597 filename = "a0g0initvals5"; 7598 break; 7599 case BWN_PHYTYPE_G: 7600 if (rev >= 5 && rev <= 10) 7601 filename = "b0g0initvals5"; 7602 else if (rev >= 13) 7603 filename = "b0g0initvals13"; 7604 else 7605 goto fail1; 7606 break; 7607 case BWN_PHYTYPE_LP: 7608 if (rev == 13) 7609 filename = "lp0initvals13"; 7610 else if (rev == 14) 7611 filename = "lp0initvals14"; 7612 else if (rev >= 15) 7613 filename = "lp0initvals15"; 7614 else 7615 goto fail1; 7616 break; 7617 case BWN_PHYTYPE_N: 7618 if (rev >= 11 && rev <= 12) 7619 filename = "n0initvals11"; 7620 else 7621 goto fail1; 7622 break; 7623 default: 7624 goto fail1; 7625 } 7626 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7627 if (error) { 7628 bwn_release_firmware(mac); 7629 return (error); 7630 } 7631 7632 /* bandswitch initvals */ 7633 switch (mac->mac_phy.type) { 7634 case BWN_PHYTYPE_A: 7635 if (rev >= 5 && rev <= 10) { 7636 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7637 filename = "a0g1bsinitvals5"; 7638 else 7639 filename = "a0g0bsinitvals5"; 7640 } else if (rev >= 11) 7641 filename = NULL; 7642 else 7643 goto fail1; 7644 break; 7645 case BWN_PHYTYPE_G: 7646 if (rev >= 5 && rev <= 10) 7647 filename = "b0g0bsinitvals5"; 7648 else if (rev >= 11) 7649 filename = NULL; 7650 else 7651 goto fail1; 7652 break; 7653 case BWN_PHYTYPE_LP: 7654 if (rev == 13) 7655 filename = "lp0bsinitvals13"; 7656 else if (rev == 14) 7657 filename = "lp0bsinitvals14"; 7658 else if (rev >= 15) 7659 filename = "lp0bsinitvals15"; 7660 else 7661 goto fail1; 7662 break; 7663 case BWN_PHYTYPE_N: 7664 if (rev >= 11 && rev <= 12) 7665 filename = "n0bsinitvals11"; 7666 else 7667 goto fail1; 7668 break; 7669 default: 7670 goto fail1; 7671 } 7672 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7673 if (error) { 7674 bwn_release_firmware(mac); 7675 return (error); 7676 } 7677 return (0); 7678fail1: 7679 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7680 bwn_release_firmware(mac); 7681 return (EOPNOTSUPP); 7682} 7683 7684static int 7685bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7686 const char *name, struct bwn_fwfile *bfw) 7687{ 7688 const struct bwn_fwhdr *hdr; 7689 struct bwn_softc *sc = mac->mac_sc; 7690 const struct firmware *fw; 7691 char namebuf[64]; 7692 7693 if (name == NULL) { 7694 bwn_do_release_fw(bfw); 7695 return (0); 7696 } 7697 if (bfw->filename != NULL) { 7698 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7699 return (0); 7700 bwn_do_release_fw(bfw); 7701 } 7702 7703 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7704 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7705 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7706 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7707 fw = firmware_get(namebuf); 7708 if (fw == NULL) { 7709 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7710 namebuf); 7711 return (ENOENT); 7712 } 7713 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7714 goto fail; 7715 hdr = (const struct bwn_fwhdr *)(fw->data); 7716 switch (hdr->type) { 7717 case BWN_FWTYPE_UCODE: 7718 case BWN_FWTYPE_PCM: 7719 if (be32toh(hdr->size) != 7720 (fw->datasize - sizeof(struct bwn_fwhdr))) 7721 goto fail; 7722 /* FALLTHROUGH */ 7723 case BWN_FWTYPE_IV: 7724 if (hdr->ver != 1) 7725 goto fail; 7726 break; 7727 default: 7728 goto fail; 7729 } 7730 bfw->filename = name; 7731 bfw->fw = fw; 7732 bfw->type = type; 7733 return (0); 7734fail: 7735 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7736 if (fw != NULL) 7737 firmware_put(fw, FIRMWARE_UNLOAD); 7738 return (EPROTO); 7739} 7740 7741static void 7742bwn_release_firmware(struct bwn_mac *mac) 7743{ 7744 7745 bwn_do_release_fw(&mac->mac_fw.ucode); 7746 bwn_do_release_fw(&mac->mac_fw.pcm); 7747 bwn_do_release_fw(&mac->mac_fw.initvals); 7748 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7749} 7750 7751static void 7752bwn_do_release_fw(struct bwn_fwfile *bfw) 7753{ 7754 7755 if (bfw->fw != NULL) 7756 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7757 bfw->fw = NULL; 7758 bfw->filename = NULL; 7759} 7760 7761static int 7762bwn_fw_loaducode(struct bwn_mac *mac) 7763{ 7764#define GETFWOFFSET(fwp, offset) \ 7765 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7766#define GETFWSIZE(fwp, offset) \ 7767 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7768 struct bwn_softc *sc = mac->mac_sc; 7769 const uint32_t *data; 7770 unsigned int i; 7771 uint32_t ctl; 7772 uint16_t date, fwcaps, time; 7773 int error = 0; 7774 7775 ctl = BWN_READ_4(mac, BWN_MACCTL); 7776 ctl |= BWN_MACCTL_MCODE_JMP0; 7777 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7778 __LINE__)); 7779 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7780 for (i = 0; i < 64; i++) 7781 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7782 for (i = 0; i < 4096; i += 2) 7783 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7784 7785 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7786 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7787 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7788 i++) { 7789 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7790 DELAY(10); 7791 } 7792 7793 if (mac->mac_fw.pcm.fw) { 7794 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7795 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7796 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7797 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7798 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7799 sizeof(struct bwn_fwhdr)); i++) { 7800 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7801 DELAY(10); 7802 } 7803 } 7804 7805 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7806 BWN_WRITE_4(mac, BWN_MACCTL, 7807 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7808 BWN_MACCTL_MCODE_RUN); 7809 7810 for (i = 0; i < 21; i++) { 7811 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7812 break; 7813 if (i >= 20) { 7814 device_printf(sc->sc_dev, "ucode timeout\n"); 7815 error = ENXIO; 7816 goto error; 7817 } 7818 DELAY(50000); 7819 } 7820 BWN_READ_4(mac, BWN_INTR_REASON); 7821 7822 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7823 if (mac->mac_fw.rev <= 0x128) { 7824 device_printf(sc->sc_dev, "the firmware is too old\n"); 7825 error = EOPNOTSUPP; 7826 goto error; 7827 } 7828 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7829 BWN_SHARED_UCODE_PATCH); 7830 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7831 mac->mac_fw.opensource = (date == 0xffff); 7832 if (bwn_wme != 0) 7833 mac->mac_flags |= BWN_MAC_FLAG_WME; 7834 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7835 7836 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7837 if (mac->mac_fw.opensource == 0) { 7838 device_printf(sc->sc_dev, 7839 "firmware version (rev %u patch %u date %#x time %#x)\n", 7840 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7841 if (mac->mac_fw.no_pcmfile) 7842 device_printf(sc->sc_dev, 7843 "no HW crypto acceleration due to pcm5\n"); 7844 } else { 7845 mac->mac_fw.patch = time; 7846 fwcaps = bwn_fwcaps_read(mac); 7847 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7848 device_printf(sc->sc_dev, 7849 "disabling HW crypto acceleration\n"); 7850 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7851 } 7852 if (!(fwcaps & BWN_FWCAPS_WME)) { 7853 device_printf(sc->sc_dev, "disabling WME support\n"); 7854 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7855 } 7856 } 7857 7858 if (BWN_ISOLDFMT(mac)) 7859 device_printf(sc->sc_dev, "using old firmware image\n"); 7860 7861 return (0); 7862 7863error: 7864 BWN_WRITE_4(mac, BWN_MACCTL, 7865 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7866 BWN_MACCTL_MCODE_JMP0); 7867 7868 return (error); 7869#undef GETFWSIZE 7870#undef GETFWOFFSET 7871} 7872 7873/* OpenFirmware only */ 7874static uint16_t 7875bwn_fwcaps_read(struct bwn_mac *mac) 7876{ 7877 7878 KASSERT(mac->mac_fw.opensource == 1, 7879 ("%s:%d: fail", __func__, __LINE__)); 7880 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7881} 7882 7883static int 7884bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7885 size_t count, size_t array_size) 7886{ 7887#define GET_NEXTIV16(iv) \ 7888 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7889 sizeof(uint16_t) + sizeof(uint16_t))) 7890#define GET_NEXTIV32(iv) \ 7891 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7892 sizeof(uint16_t) + sizeof(uint32_t))) 7893 struct bwn_softc *sc = mac->mac_sc; 7894 const struct bwn_fwinitvals *iv; 7895 uint16_t offset; 7896 size_t i; 7897 uint8_t bit32; 7898 7899 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7900 ("%s:%d: fail", __func__, __LINE__)); 7901 iv = ivals; 7902 for (i = 0; i < count; i++) { 7903 if (array_size < sizeof(iv->offset_size)) 7904 goto fail; 7905 array_size -= sizeof(iv->offset_size); 7906 offset = be16toh(iv->offset_size); 7907 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7908 offset &= BWN_FWINITVALS_OFFSET_MASK; 7909 if (offset >= 0x1000) 7910 goto fail; 7911 if (bit32) { 7912 if (array_size < sizeof(iv->data.d32)) 7913 goto fail; 7914 array_size -= sizeof(iv->data.d32); 7915 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7916 iv = GET_NEXTIV32(iv); 7917 } else { 7918 7919 if (array_size < sizeof(iv->data.d16)) 7920 goto fail; 7921 array_size -= sizeof(iv->data.d16); 7922 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7923 7924 iv = GET_NEXTIV16(iv); 7925 } 7926 } 7927 if (array_size != 0) 7928 goto fail; 7929 return (0); 7930fail: 7931 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7932 return (EPROTO); 7933#undef GET_NEXTIV16 7934#undef GET_NEXTIV32 7935} 7936 7937static int 7938bwn_switch_channel(struct bwn_mac *mac, int chan) 7939{ 7940 struct bwn_phy *phy = &(mac->mac_phy); 7941 struct bwn_softc *sc = mac->mac_sc; 7942 struct ifnet *ifp = sc->sc_ifp; 7943 struct ieee80211com *ic = ifp->if_l2com; 7944 uint16_t channelcookie, savedcookie; 7945 int error; 7946 7947 if (chan == 0xffff) 7948 chan = phy->get_default_chan(mac); 7949 7950 channelcookie = chan; 7951 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7952 channelcookie |= 0x100; 7953 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7954 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7955 error = phy->switch_channel(mac, chan); 7956 if (error) 7957 goto fail; 7958 7959 mac->mac_phy.chan = chan; 7960 DELAY(8000); 7961 return (0); 7962fail: 7963 device_printf(sc->sc_dev, "failed to switch channel\n"); 7964 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7965 return (error); 7966} 7967 7968static uint16_t 7969bwn_ant2phy(int antenna) 7970{ 7971 7972 switch (antenna) { 7973 case BWN_ANT0: 7974 return (BWN_TX_PHY_ANT0); 7975 case BWN_ANT1: 7976 return (BWN_TX_PHY_ANT1); 7977 case BWN_ANT2: 7978 return (BWN_TX_PHY_ANT2); 7979 case BWN_ANT3: 7980 return (BWN_TX_PHY_ANT3); 7981 case BWN_ANTAUTO: 7982 return (BWN_TX_PHY_ANT01AUTO); 7983 } 7984 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7985 return (0); 7986} 7987 7988static void 7989bwn_wme_load(struct bwn_mac *mac) 7990{ 7991 struct bwn_softc *sc = mac->mac_sc; 7992 int i; 7993 7994 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7995 ("%s:%d: fail", __func__, __LINE__)); 7996 7997 bwn_mac_suspend(mac); 7998 for (i = 0; i < N(sc->sc_wmeParams); i++) 7999 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8000 bwn_wme_shm_offsets[i]); 8001 bwn_mac_enable(mac); 8002} 8003 8004static void 8005bwn_wme_loadparams(struct bwn_mac *mac, 8006 const struct wmeParams *p, uint16_t shm_offset) 8007{ 8008#define SM(_v, _f) (((_v) << _f##_S) & _f) 8009 struct bwn_softc *sc = mac->mac_sc; 8010 uint16_t params[BWN_NR_WMEPARAMS]; 8011 int slot, tmp; 8012 unsigned int i; 8013 8014 slot = BWN_READ_2(mac, BWN_RNG) & 8015 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8016 8017 memset(¶ms, 0, sizeof(params)); 8018 8019 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8020 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8021 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8022 8023 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8024 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8025 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8026 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8027 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8028 params[BWN_WMEPARAM_BSLOTS] = slot; 8029 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8030 8031 for (i = 0; i < N(params); i++) { 8032 if (i == BWN_WMEPARAM_STATUS) { 8033 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8034 shm_offset + (i * 2)); 8035 tmp |= 0x100; 8036 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8037 tmp); 8038 } else { 8039 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8040 params[i]); 8041 } 8042 } 8043} 8044 8045static void 8046bwn_mac_write_bssid(struct bwn_mac *mac) 8047{ 8048 struct bwn_softc *sc = mac->mac_sc; 8049 uint32_t tmp; 8050 int i; 8051 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8052 8053 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8054 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8055 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8056 IEEE80211_ADDR_LEN); 8057 8058 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8059 tmp = (uint32_t) (mac_bssid[i + 0]); 8060 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8061 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8062 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8063 bwn_ram_write(mac, 0x20 + i, tmp); 8064 } 8065} 8066 8067static void 8068bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8069 const uint8_t *macaddr) 8070{ 8071 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8072 uint16_t data; 8073 8074 if (!mac) 8075 macaddr = zero; 8076 8077 offset |= 0x0020; 8078 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8079 8080 data = macaddr[0]; 8081 data |= macaddr[1] << 8; 8082 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8083 data = macaddr[2]; 8084 data |= macaddr[3] << 8; 8085 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8086 data = macaddr[4]; 8087 data |= macaddr[5] << 8; 8088 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8089} 8090 8091static void 8092bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8093 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8094{ 8095 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8096 uint8_t per_sta_keys_start = 8; 8097 8098 if (BWN_SEC_NEWAPI(mac)) 8099 per_sta_keys_start = 4; 8100 8101 KASSERT(index < mac->mac_max_nr_keys, 8102 ("%s:%d: fail", __func__, __LINE__)); 8103 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8104 ("%s:%d: fail", __func__, __LINE__)); 8105 8106 if (index >= per_sta_keys_start) 8107 bwn_key_macwrite(mac, index, NULL); 8108 if (key) 8109 memcpy(buf, key, key_len); 8110 bwn_key_write(mac, index, algorithm, buf); 8111 if (index >= per_sta_keys_start) 8112 bwn_key_macwrite(mac, index, mac_addr); 8113 8114 mac->mac_key[index].algorithm = algorithm; 8115} 8116 8117static void 8118bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8119{ 8120 struct bwn_softc *sc = mac->mac_sc; 8121 uint32_t addrtmp[2] = { 0, 0 }; 8122 uint8_t start = 8; 8123 8124 if (BWN_SEC_NEWAPI(mac)) 8125 start = 4; 8126 8127 KASSERT(index >= start, 8128 ("%s:%d: fail", __func__, __LINE__)); 8129 index -= start; 8130 8131 if (addr) { 8132 addrtmp[0] = addr[0]; 8133 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8134 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8135 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8136 addrtmp[1] = addr[4]; 8137 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8138 } 8139 8140 if (siba_get_revid(sc->sc_dev) >= 5) { 8141 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8142 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8143 } else { 8144 if (index >= 8) { 8145 bwn_shm_write_4(mac, BWN_SHARED, 8146 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8147 bwn_shm_write_2(mac, BWN_SHARED, 8148 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8149 } 8150 } 8151} 8152 8153static void 8154bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8155 const uint8_t *key) 8156{ 8157 unsigned int i; 8158 uint32_t offset; 8159 uint16_t kidx, value; 8160 8161 kidx = BWN_SEC_KEY2FW(mac, index); 8162 bwn_shm_write_2(mac, BWN_SHARED, 8163 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8164 8165 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8166 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8167 value = key[i]; 8168 value |= (uint16_t)(key[i + 1]) << 8; 8169 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8170 } 8171} 8172 8173static void 8174bwn_phy_exit(struct bwn_mac *mac) 8175{ 8176 8177 mac->mac_phy.rf_onoff(mac, 0); 8178 if (mac->mac_phy.exit != NULL) 8179 mac->mac_phy.exit(mac); 8180} 8181 8182static void 8183bwn_dma_free(struct bwn_mac *mac) 8184{ 8185 struct bwn_dma *dma; 8186 8187 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8188 return; 8189 dma = &mac->mac_method.dma; 8190 8191 bwn_dma_ringfree(&dma->rx); 8192 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8193 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8194 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8195 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8196 bwn_dma_ringfree(&dma->mcast); 8197} 8198 8199static void 8200bwn_core_stop(struct bwn_mac *mac) 8201{ 8202 struct bwn_softc *sc = mac->mac_sc; 8203 8204 BWN_ASSERT_LOCKED(sc); 8205 8206 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8207 return; 8208 8209 callout_stop(&sc->sc_rfswitch_ch); 8210 callout_stop(&sc->sc_task_ch); 8211 callout_stop(&sc->sc_watchdog_ch); 8212 sc->sc_watchdog_timer = 0; 8213 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8214 BWN_READ_4(mac, BWN_INTR_MASK); 8215 bwn_mac_suspend(mac); 8216 8217 mac->mac_status = BWN_MAC_STATUS_INITED; 8218} 8219 8220static int 8221bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8222{ 8223 struct bwn_mac *up_dev = NULL; 8224 struct bwn_mac *down_dev; 8225 struct bwn_mac *mac; 8226 int err, status; 8227 uint8_t gmode; 8228 8229 BWN_ASSERT_LOCKED(sc); 8230 8231 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8232 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8233 mac->mac_phy.supports_2ghz) { 8234 up_dev = mac; 8235 gmode = 1; 8236 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8237 mac->mac_phy.supports_5ghz) { 8238 up_dev = mac; 8239 gmode = 0; 8240 } else { 8241 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8242 return (EINVAL); 8243 } 8244 if (up_dev != NULL) 8245 break; 8246 } 8247 if (up_dev == NULL) { 8248 device_printf(sc->sc_dev, "Could not find a device\n"); 8249 return (ENODEV); 8250 } 8251 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8252 return (0); 8253 8254 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8255 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8256 8257 down_dev = sc->sc_curmac; 8258 status = down_dev->mac_status; 8259 if (status >= BWN_MAC_STATUS_STARTED) 8260 bwn_core_stop(down_dev); 8261 if (status >= BWN_MAC_STATUS_INITED) 8262 bwn_core_exit(down_dev); 8263 8264 if (down_dev != up_dev) 8265 bwn_phy_reset(down_dev); 8266 8267 up_dev->mac_phy.gmode = gmode; 8268 if (status >= BWN_MAC_STATUS_INITED) { 8269 err = bwn_core_init(up_dev); 8270 if (err) { 8271 device_printf(sc->sc_dev, 8272 "fatal: failed to initialize for %s-GHz\n", 8273 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8274 goto fail; 8275 } 8276 } 8277 if (status >= BWN_MAC_STATUS_STARTED) 8278 bwn_core_start(up_dev); 8279 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8280 sc->sc_curmac = up_dev; 8281 8282 return (0); 8283fail: 8284 sc->sc_curmac = NULL; 8285 return (err); 8286} 8287 8288static void 8289bwn_rf_turnon(struct bwn_mac *mac) 8290{ 8291 8292 bwn_mac_suspend(mac); 8293 mac->mac_phy.rf_onoff(mac, 1); 8294 mac->mac_phy.rf_on = 1; 8295 bwn_mac_enable(mac); 8296} 8297 8298static void 8299bwn_rf_turnoff(struct bwn_mac *mac) 8300{ 8301 8302 bwn_mac_suspend(mac); 8303 mac->mac_phy.rf_onoff(mac, 0); 8304 mac->mac_phy.rf_on = 0; 8305 bwn_mac_enable(mac); 8306} 8307 8308static void 8309bwn_phy_reset(struct bwn_mac *mac) 8310{ 8311 struct bwn_softc *sc = mac->mac_sc; 8312 8313 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8314 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8315 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8316 DELAY(1000); 8317 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8318 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8319 BWN_TGSLOW_PHYRESET); 8320 DELAY(1000); 8321} 8322 8323static int 8324bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8325{ 8326 struct bwn_vap *bvp = BWN_VAP(vap); 8327 struct ieee80211com *ic= vap->iv_ic; 8328 struct ifnet *ifp = ic->ic_ifp; 8329 enum ieee80211_state ostate = vap->iv_state; 8330 struct bwn_softc *sc = ic->ic_softc; 8331 struct bwn_mac *mac = sc->sc_curmac; 8332 int error; 8333 8334 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8335 ieee80211_state_name[vap->iv_state], 8336 ieee80211_state_name[nstate]); 8337 8338 error = bvp->bv_newstate(vap, nstate, arg); 8339 if (error != 0) 8340 return (error); 8341 8342 BWN_LOCK(sc); 8343 8344 bwn_led_newstate(mac, nstate); 8345 8346 /* 8347 * Clear the BSSID when we stop a STA 8348 */ 8349 if (vap->iv_opmode == IEEE80211_M_STA) { 8350 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8351 /* 8352 * Clear out the BSSID. If we reassociate to 8353 * the same AP, this will reinialize things 8354 * correctly... 8355 */ 8356 if (ic->ic_opmode == IEEE80211_M_STA && 8357 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8358 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8359 bwn_set_macaddr(mac); 8360 } 8361 } 8362 } 8363 8364 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8365 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8366 /* XXX nothing to do? */ 8367 } else if (nstate == IEEE80211_S_RUN) { 8368 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8369 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8370 bwn_set_opmode(mac); 8371 bwn_set_pretbtt(mac); 8372 bwn_spu_setdelay(mac, 0); 8373 bwn_set_macaddr(mac); 8374 } 8375 8376 BWN_UNLOCK(sc); 8377 8378 return (error); 8379} 8380 8381static void 8382bwn_set_pretbtt(struct bwn_mac *mac) 8383{ 8384 struct bwn_softc *sc = mac->mac_sc; 8385 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8386 uint16_t pretbtt; 8387 8388 if (ic->ic_opmode == IEEE80211_M_IBSS) 8389 pretbtt = 2; 8390 else 8391 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8392 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8393 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8394} 8395 8396static int 8397bwn_intr(void *arg) 8398{ 8399 struct bwn_mac *mac = arg; 8400 struct bwn_softc *sc = mac->mac_sc; 8401 uint32_t reason; 8402 8403 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8404 (sc->sc_flags & BWN_FLAG_INVALID)) 8405 return (FILTER_STRAY); 8406 8407 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8408 if (reason == 0xffffffff) /* shared IRQ */ 8409 return (FILTER_STRAY); 8410 reason &= mac->mac_intr_mask; 8411 if (reason == 0) 8412 return (FILTER_HANDLED); 8413 8414 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8415 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8416 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8417 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8418 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8419 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8420 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8421 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8422 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8423 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8424 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8425 8426 /* Disable interrupts. */ 8427 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8428 8429 mac->mac_reason_intr = reason; 8430 8431 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8432 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8433 8434 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8435 return (FILTER_HANDLED); 8436} 8437 8438static void 8439bwn_intrtask(void *arg, int npending) 8440{ 8441 struct bwn_mac *mac = arg; 8442 struct bwn_softc *sc = mac->mac_sc; 8443 struct ifnet *ifp = sc->sc_ifp; 8444 uint32_t merged = 0; 8445 int i, tx = 0, rx = 0; 8446 8447 BWN_LOCK(sc); 8448 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8449 (sc->sc_flags & BWN_FLAG_INVALID)) { 8450 BWN_UNLOCK(sc); 8451 return; 8452 } 8453 8454 for (i = 0; i < N(mac->mac_reason); i++) 8455 merged |= mac->mac_reason[i]; 8456 8457 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8458 device_printf(sc->sc_dev, "MAC trans error\n"); 8459 8460 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8461 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8462 mac->mac_phy.txerrors--; 8463 if (mac->mac_phy.txerrors == 0) { 8464 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8465 bwn_restart(mac, "PHY TX errors"); 8466 } 8467 } 8468 8469 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8470 if (merged & BWN_DMAINTR_FATALMASK) { 8471 device_printf(sc->sc_dev, 8472 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8473 mac->mac_reason[0], mac->mac_reason[1], 8474 mac->mac_reason[2], mac->mac_reason[3], 8475 mac->mac_reason[4], mac->mac_reason[5]); 8476 bwn_restart(mac, "DMA error"); 8477 BWN_UNLOCK(sc); 8478 return; 8479 } 8480 if (merged & BWN_DMAINTR_NONFATALMASK) { 8481 device_printf(sc->sc_dev, 8482 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8483 mac->mac_reason[0], mac->mac_reason[1], 8484 mac->mac_reason[2], mac->mac_reason[3], 8485 mac->mac_reason[4], mac->mac_reason[5]); 8486 } 8487 } 8488 8489 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8490 bwn_intr_ucode_debug(mac); 8491 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8492 bwn_intr_tbtt_indication(mac); 8493 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8494 bwn_intr_atim_end(mac); 8495 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8496 bwn_intr_beacon(mac); 8497 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8498 bwn_intr_pmq(mac); 8499 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8500 bwn_intr_noise(mac); 8501 8502 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8503 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8504 bwn_dma_rx(mac->mac_method.dma.rx); 8505 rx = 1; 8506 } 8507 } else 8508 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8509 8510 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8511 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8512 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8513 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8514 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8515 8516 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8517 bwn_intr_txeof(mac); 8518 tx = 1; 8519 } 8520 8521 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8522 8523 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8524 int evt = BWN_LED_EVENT_NONE; 8525 8526 if (tx && rx) { 8527 if (sc->sc_rx_rate > sc->sc_tx_rate) 8528 evt = BWN_LED_EVENT_RX; 8529 else 8530 evt = BWN_LED_EVENT_TX; 8531 } else if (tx) { 8532 evt = BWN_LED_EVENT_TX; 8533 } else if (rx) { 8534 evt = BWN_LED_EVENT_RX; 8535 } else if (rx == 0) { 8536 evt = BWN_LED_EVENT_POLL; 8537 } 8538 8539 if (evt != BWN_LED_EVENT_NONE) 8540 bwn_led_event(mac, evt); 8541 } 8542 8543 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8544 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8545 bwn_start_locked(ifp); 8546 } 8547 8548 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8549 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8550 8551 BWN_UNLOCK(sc); 8552} 8553 8554static void 8555bwn_restart(struct bwn_mac *mac, const char *msg) 8556{ 8557 struct bwn_softc *sc = mac->mac_sc; 8558 struct ifnet *ifp = sc->sc_ifp; 8559 struct ieee80211com *ic = ifp->if_l2com; 8560 8561 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8562 return; 8563 8564 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8565 ieee80211_runtask(ic, &mac->mac_hwreset); 8566} 8567 8568static void 8569bwn_intr_ucode_debug(struct bwn_mac *mac) 8570{ 8571 struct bwn_softc *sc = mac->mac_sc; 8572 uint16_t reason; 8573 8574 if (mac->mac_fw.opensource == 0) 8575 return; 8576 8577 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8578 switch (reason) { 8579 case BWN_DEBUGINTR_PANIC: 8580 bwn_handle_fwpanic(mac); 8581 break; 8582 case BWN_DEBUGINTR_DUMP_SHM: 8583 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8584 break; 8585 case BWN_DEBUGINTR_DUMP_REGS: 8586 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8587 break; 8588 case BWN_DEBUGINTR_MARKER: 8589 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8590 break; 8591 default: 8592 device_printf(sc->sc_dev, 8593 "ucode debug unknown reason: %#x\n", reason); 8594 } 8595 8596 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8597 BWN_DEBUGINTR_ACK); 8598} 8599 8600static void 8601bwn_intr_tbtt_indication(struct bwn_mac *mac) 8602{ 8603 struct bwn_softc *sc = mac->mac_sc; 8604 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8605 8606 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8607 bwn_psctl(mac, 0); 8608 if (ic->ic_opmode == IEEE80211_M_IBSS) 8609 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8610} 8611 8612static void 8613bwn_intr_atim_end(struct bwn_mac *mac) 8614{ 8615 8616 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8617 BWN_WRITE_4(mac, BWN_MACCMD, 8618 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8619 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8620 } 8621} 8622 8623static void 8624bwn_intr_beacon(struct bwn_mac *mac) 8625{ 8626 struct bwn_softc *sc = mac->mac_sc; 8627 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8628 uint32_t cmd, beacon0, beacon1; 8629 8630 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8631 ic->ic_opmode == IEEE80211_M_MBSS) 8632 return; 8633 8634 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8635 8636 cmd = BWN_READ_4(mac, BWN_MACCMD); 8637 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8638 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8639 8640 if (beacon0 && beacon1) { 8641 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8642 mac->mac_intr_mask |= BWN_INTR_BEACON; 8643 return; 8644 } 8645 8646 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8647 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8648 bwn_load_beacon0(mac); 8649 bwn_load_beacon1(mac); 8650 cmd = BWN_READ_4(mac, BWN_MACCMD); 8651 cmd |= BWN_MACCMD_BEACON0_VALID; 8652 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8653 } else { 8654 if (!beacon0) { 8655 bwn_load_beacon0(mac); 8656 cmd = BWN_READ_4(mac, BWN_MACCMD); 8657 cmd |= BWN_MACCMD_BEACON0_VALID; 8658 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8659 } else if (!beacon1) { 8660 bwn_load_beacon1(mac); 8661 cmd = BWN_READ_4(mac, BWN_MACCMD); 8662 cmd |= BWN_MACCMD_BEACON1_VALID; 8663 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8664 } 8665 } 8666} 8667 8668static void 8669bwn_intr_pmq(struct bwn_mac *mac) 8670{ 8671 uint32_t tmp; 8672 8673 while (1) { 8674 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8675 if (!(tmp & 0x00000008)) 8676 break; 8677 } 8678 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8679} 8680 8681static void 8682bwn_intr_noise(struct bwn_mac *mac) 8683{ 8684 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8685 uint16_t tmp; 8686 uint8_t noise[4]; 8687 uint8_t i, j; 8688 int32_t average; 8689 8690 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8691 return; 8692 8693 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8694 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8695 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8696 noise[3] == 0x7f) 8697 goto new; 8698 8699 KASSERT(mac->mac_noise.noi_nsamples < 8, 8700 ("%s:%d: fail", __func__, __LINE__)); 8701 i = mac->mac_noise.noi_nsamples; 8702 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8703 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8704 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8705 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8706 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8707 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8708 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8709 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8710 mac->mac_noise.noi_nsamples++; 8711 if (mac->mac_noise.noi_nsamples == 8) { 8712 average = 0; 8713 for (i = 0; i < 8; i++) { 8714 for (j = 0; j < 4; j++) 8715 average += mac->mac_noise.noi_samples[i][j]; 8716 } 8717 average = (((average / 32) * 125) + 64) / 128; 8718 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8719 if (tmp >= 8) 8720 average += 2; 8721 else 8722 average -= 25; 8723 average -= (tmp == 8) ? 72 : 48; 8724 8725 mac->mac_stats.link_noise = average; 8726 mac->mac_noise.noi_running = 0; 8727 return; 8728 } 8729new: 8730 bwn_noise_gensample(mac); 8731} 8732 8733static int 8734bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8735{ 8736 struct bwn_mac *mac = prq->prq_mac; 8737 struct bwn_softc *sc = mac->mac_sc; 8738 unsigned int i; 8739 8740 BWN_ASSERT_LOCKED(sc); 8741 8742 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8743 return (0); 8744 8745 for (i = 0; i < 5000; i++) { 8746 if (bwn_pio_rxeof(prq) == 0) 8747 break; 8748 } 8749 if (i >= 5000) 8750 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8751 return ((i > 0) ? 1 : 0); 8752} 8753 8754static void 8755bwn_dma_rx(struct bwn_dma_ring *dr) 8756{ 8757 int slot, curslot; 8758 8759 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8760 curslot = dr->get_curslot(dr); 8761 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8762 ("%s:%d: fail", __func__, __LINE__)); 8763 8764 slot = dr->dr_curslot; 8765 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8766 bwn_dma_rxeof(dr, &slot); 8767 8768 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8769 BUS_DMASYNC_PREWRITE); 8770 8771 dr->set_curslot(dr, slot); 8772 dr->dr_curslot = slot; 8773} 8774 8775static void 8776bwn_intr_txeof(struct bwn_mac *mac) 8777{ 8778 struct bwn_txstatus stat; 8779 uint32_t stat0, stat1; 8780 uint16_t tmp; 8781 8782 BWN_ASSERT_LOCKED(mac->mac_sc); 8783 8784 while (1) { 8785 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8786 if (!(stat0 & 0x00000001)) 8787 break; 8788 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8789 8790 stat.cookie = (stat0 >> 16); 8791 stat.seq = (stat1 & 0x0000ffff); 8792 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8793 tmp = (stat0 & 0x0000ffff); 8794 stat.framecnt = ((tmp & 0xf000) >> 12); 8795 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8796 stat.sreason = ((tmp & 0x001c) >> 2); 8797 stat.pm = (tmp & 0x0080) ? 1 : 0; 8798 stat.im = (tmp & 0x0040) ? 1 : 0; 8799 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8800 stat.ack = (tmp & 0x0002) ? 1 : 0; 8801 8802 bwn_handle_txeof(mac, &stat); 8803 } 8804} 8805 8806static void 8807bwn_hwreset(void *arg, int npending) 8808{ 8809 struct bwn_mac *mac = arg; 8810 struct bwn_softc *sc = mac->mac_sc; 8811 int error = 0; 8812 int prev_status; 8813 8814 BWN_LOCK(sc); 8815 8816 prev_status = mac->mac_status; 8817 if (prev_status >= BWN_MAC_STATUS_STARTED) 8818 bwn_core_stop(mac); 8819 if (prev_status >= BWN_MAC_STATUS_INITED) 8820 bwn_core_exit(mac); 8821 8822 if (prev_status >= BWN_MAC_STATUS_INITED) { 8823 error = bwn_core_init(mac); 8824 if (error) 8825 goto out; 8826 } 8827 if (prev_status >= BWN_MAC_STATUS_STARTED) 8828 bwn_core_start(mac); 8829out: 8830 if (error) { 8831 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8832 sc->sc_curmac = NULL; 8833 } 8834 BWN_UNLOCK(sc); 8835} 8836 8837static void 8838bwn_handle_fwpanic(struct bwn_mac *mac) 8839{ 8840 struct bwn_softc *sc = mac->mac_sc; 8841 uint16_t reason; 8842 8843 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8844 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8845 8846 if (reason == BWN_FWPANIC_RESTART) 8847 bwn_restart(mac, "ucode panic"); 8848} 8849 8850static void 8851bwn_load_beacon0(struct bwn_mac *mac) 8852{ 8853 8854 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8855} 8856 8857static void 8858bwn_load_beacon1(struct bwn_mac *mac) 8859{ 8860 8861 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8862} 8863 8864static uint32_t 8865bwn_jssi_read(struct bwn_mac *mac) 8866{ 8867 uint32_t val = 0; 8868 8869 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8870 val <<= 16; 8871 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8872 8873 return (val); 8874} 8875 8876static void 8877bwn_noise_gensample(struct bwn_mac *mac) 8878{ 8879 uint32_t jssi = 0x7f7f7f7f; 8880 8881 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8882 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8883 BWN_WRITE_4(mac, BWN_MACCMD, 8884 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8885} 8886 8887static int 8888bwn_dma_freeslot(struct bwn_dma_ring *dr) 8889{ 8890 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8891 8892 return (dr->dr_numslots - dr->dr_usedslot); 8893} 8894 8895static int 8896bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8897{ 8898 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8899 8900 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8901 ("%s:%d: fail", __func__, __LINE__)); 8902 if (slot == dr->dr_numslots - 1) 8903 return (0); 8904 return (slot + 1); 8905} 8906 8907static void 8908bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8909{ 8910 struct bwn_mac *mac = dr->dr_mac; 8911 struct bwn_softc *sc = mac->mac_sc; 8912 struct bwn_dma *dma = &mac->mac_method.dma; 8913 struct bwn_dmadesc_generic *desc; 8914 struct bwn_dmadesc_meta *meta; 8915 struct bwn_rxhdr4 *rxhdr; 8916 struct ifnet *ifp = sc->sc_ifp; 8917 struct mbuf *m; 8918 uint32_t macstat; 8919 int32_t tmp; 8920 int cnt = 0; 8921 uint16_t len; 8922 8923 dr->getdesc(dr, *slot, &desc, &meta); 8924 8925 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8926 m = meta->mt_m; 8927 8928 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8929 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8930 return; 8931 } 8932 8933 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8934 len = le16toh(rxhdr->frame_len); 8935 if (len <= 0) { 8936 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8937 return; 8938 } 8939 if (bwn_dma_check_redzone(dr, m)) { 8940 device_printf(sc->sc_dev, "redzone error.\n"); 8941 bwn_dma_set_redzone(dr, m); 8942 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8943 BUS_DMASYNC_PREWRITE); 8944 return; 8945 } 8946 if (len > dr->dr_rx_bufsize) { 8947 tmp = len; 8948 while (1) { 8949 dr->getdesc(dr, *slot, &desc, &meta); 8950 bwn_dma_set_redzone(dr, meta->mt_m); 8951 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8952 BUS_DMASYNC_PREWRITE); 8953 *slot = bwn_dma_nextslot(dr, *slot); 8954 cnt++; 8955 tmp -= dr->dr_rx_bufsize; 8956 if (tmp <= 0) 8957 break; 8958 } 8959 device_printf(sc->sc_dev, "too small buffer " 8960 "(len %u buffer %u dropped %d)\n", 8961 len, dr->dr_rx_bufsize, cnt); 8962 return; 8963 } 8964 macstat = le32toh(rxhdr->mac_status); 8965 if (macstat & BWN_RX_MAC_FCSERR) { 8966 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8967 device_printf(sc->sc_dev, "RX drop\n"); 8968 return; 8969 } 8970 } 8971 8972 m->m_pkthdr.rcvif = ifp; 8973 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8974 m_adj(m, dr->dr_frameoffset); 8975 8976 bwn_rxeof(dr->dr_mac, m, rxhdr); 8977} 8978 8979static void 8980bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8981{ 8982 struct bwn_dma_ring *dr; 8983 struct bwn_dmadesc_generic *desc; 8984 struct bwn_dmadesc_meta *meta; 8985 struct bwn_pio_txqueue *tq; 8986 struct bwn_pio_txpkt *tp = NULL; 8987 struct bwn_softc *sc = mac->mac_sc; 8988 struct bwn_stats *stats = &mac->mac_stats; 8989 struct ieee80211_node *ni; 8990 struct ieee80211vap *vap; 8991 int retrycnt = 0, slot; 8992 8993 BWN_ASSERT_LOCKED(mac->mac_sc); 8994 8995 if (status->im) 8996 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8997 if (status->ampdu) 8998 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8999 if (status->rtscnt) { 9000 if (status->rtscnt == 0xf) 9001 stats->rtsfail++; 9002 else 9003 stats->rts++; 9004 } 9005 9006 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9007 if (status->ack) { 9008 dr = bwn_dma_parse_cookie(mac, status, 9009 status->cookie, &slot); 9010 if (dr == NULL) { 9011 device_printf(sc->sc_dev, 9012 "failed to parse cookie\n"); 9013 return; 9014 } 9015 while (1) { 9016 dr->getdesc(dr, slot, &desc, &meta); 9017 if (meta->mt_islast) { 9018 ni = meta->mt_ni; 9019 vap = ni->ni_vap; 9020 ieee80211_ratectl_tx_complete(vap, ni, 9021 status->ack ? 9022 IEEE80211_RATECTL_TX_SUCCESS : 9023 IEEE80211_RATECTL_TX_FAILURE, 9024 &retrycnt, 0); 9025 break; 9026 } 9027 slot = bwn_dma_nextslot(dr, slot); 9028 } 9029 } 9030 bwn_dma_handle_txeof(mac, status); 9031 } else { 9032 if (status->ack) { 9033 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9034 if (tq == NULL) { 9035 device_printf(sc->sc_dev, 9036 "failed to parse cookie\n"); 9037 return; 9038 } 9039 ni = tp->tp_ni; 9040 vap = ni->ni_vap; 9041 ieee80211_ratectl_tx_complete(vap, ni, 9042 status->ack ? 9043 IEEE80211_RATECTL_TX_SUCCESS : 9044 IEEE80211_RATECTL_TX_FAILURE, 9045 &retrycnt, 0); 9046 } 9047 bwn_pio_handle_txeof(mac, status); 9048 } 9049 9050 bwn_phy_txpower_check(mac, 0); 9051} 9052 9053static uint8_t 9054bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9055{ 9056 struct bwn_mac *mac = prq->prq_mac; 9057 struct bwn_softc *sc = mac->mac_sc; 9058 struct bwn_rxhdr4 rxhdr; 9059 struct ifnet *ifp = sc->sc_ifp; 9060 struct mbuf *m; 9061 uint32_t ctl32, macstat, v32; 9062 unsigned int i, padding; 9063 uint16_t ctl16, len, totlen, v16; 9064 unsigned char *mp; 9065 char *data; 9066 9067 memset(&rxhdr, 0, sizeof(rxhdr)); 9068 9069 if (prq->prq_rev >= 8) { 9070 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9071 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9072 return (0); 9073 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9074 BWN_PIO8_RXCTL_FRAMEREADY); 9075 for (i = 0; i < 10; i++) { 9076 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9077 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9078 goto ready; 9079 DELAY(10); 9080 } 9081 } else { 9082 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9083 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9084 return (0); 9085 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9086 BWN_PIO_RXCTL_FRAMEREADY); 9087 for (i = 0; i < 10; i++) { 9088 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9089 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9090 goto ready; 9091 DELAY(10); 9092 } 9093 } 9094 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9095 return (1); 9096ready: 9097 if (prq->prq_rev >= 8) 9098 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9099 prq->prq_base + BWN_PIO8_RXDATA); 9100 else 9101 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9102 prq->prq_base + BWN_PIO_RXDATA); 9103 len = le16toh(rxhdr.frame_len); 9104 if (len > 0x700) { 9105 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9106 goto error; 9107 } 9108 if (len == 0) { 9109 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9110 goto error; 9111 } 9112 9113 macstat = le32toh(rxhdr.mac_status); 9114 if (macstat & BWN_RX_MAC_FCSERR) { 9115 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9116 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9117 goto error; 9118 } 9119 } 9120 9121 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9122 totlen = len + padding; 9123 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9124 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9125 if (m == NULL) { 9126 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9127 goto error; 9128 } 9129 mp = mtod(m, unsigned char *); 9130 if (prq->prq_rev >= 8) { 9131 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9132 prq->prq_base + BWN_PIO8_RXDATA); 9133 if (totlen & 3) { 9134 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9135 data = &(mp[totlen - 1]); 9136 switch (totlen & 3) { 9137 case 3: 9138 *data = (v32 >> 16); 9139 data--; 9140 case 2: 9141 *data = (v32 >> 8); 9142 data--; 9143 case 1: 9144 *data = v32; 9145 } 9146 } 9147 } else { 9148 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9149 prq->prq_base + BWN_PIO_RXDATA); 9150 if (totlen & 1) { 9151 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9152 mp[totlen - 1] = v16; 9153 } 9154 } 9155 9156 m->m_pkthdr.rcvif = ifp; 9157 m->m_len = m->m_pkthdr.len = totlen; 9158 9159 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9160 9161 return (1); 9162error: 9163 if (prq->prq_rev >= 8) 9164 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9165 BWN_PIO8_RXCTL_DATAREADY); 9166 else 9167 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9168 return (1); 9169} 9170 9171static int 9172bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9173 struct bwn_dmadesc_meta *meta, int init) 9174{ 9175 struct bwn_mac *mac = dr->dr_mac; 9176 struct bwn_dma *dma = &mac->mac_method.dma; 9177 struct bwn_rxhdr4 *hdr; 9178 bus_dmamap_t map; 9179 bus_addr_t paddr; 9180 struct mbuf *m; 9181 int error; 9182 9183 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9184 if (m == NULL) { 9185 error = ENOBUFS; 9186 9187 /* 9188 * If the NIC is up and running, we need to: 9189 * - Clear RX buffer's header. 9190 * - Restore RX descriptor settings. 9191 */ 9192 if (init) 9193 return (error); 9194 else 9195 goto back; 9196 } 9197 m->m_len = m->m_pkthdr.len = MCLBYTES; 9198 9199 bwn_dma_set_redzone(dr, m); 9200 9201 /* 9202 * Try to load RX buf into temporary DMA map 9203 */ 9204 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9205 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9206 if (error) { 9207 m_freem(m); 9208 9209 /* 9210 * See the comment above 9211 */ 9212 if (init) 9213 return (error); 9214 else 9215 goto back; 9216 } 9217 9218 if (!init) 9219 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9220 meta->mt_m = m; 9221 meta->mt_paddr = paddr; 9222 9223 /* 9224 * Swap RX buf's DMA map with the loaded temporary one 9225 */ 9226 map = meta->mt_dmap; 9227 meta->mt_dmap = dr->dr_spare_dmap; 9228 dr->dr_spare_dmap = map; 9229 9230back: 9231 /* 9232 * Clear RX buf header 9233 */ 9234 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9235 bzero(hdr, sizeof(*hdr)); 9236 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9237 BUS_DMASYNC_PREWRITE); 9238 9239 /* 9240 * Setup RX buf descriptor 9241 */ 9242 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9243 sizeof(*hdr), 0, 0, 0); 9244 return (error); 9245} 9246 9247static void 9248bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9249 bus_size_t mapsz __unused, int error) 9250{ 9251 9252 if (!error) { 9253 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9254 *((bus_addr_t *)arg) = seg->ds_addr; 9255 } 9256} 9257 9258static int 9259bwn_hwrate2ieeerate(int rate) 9260{ 9261 9262 switch (rate) { 9263 case BWN_CCK_RATE_1MB: 9264 return (2); 9265 case BWN_CCK_RATE_2MB: 9266 return (4); 9267 case BWN_CCK_RATE_5MB: 9268 return (11); 9269 case BWN_CCK_RATE_11MB: 9270 return (22); 9271 case BWN_OFDM_RATE_6MB: 9272 return (12); 9273 case BWN_OFDM_RATE_9MB: 9274 return (18); 9275 case BWN_OFDM_RATE_12MB: 9276 return (24); 9277 case BWN_OFDM_RATE_18MB: 9278 return (36); 9279 case BWN_OFDM_RATE_24MB: 9280 return (48); 9281 case BWN_OFDM_RATE_36MB: 9282 return (72); 9283 case BWN_OFDM_RATE_48MB: 9284 return (96); 9285 case BWN_OFDM_RATE_54MB: 9286 return (108); 9287 default: 9288 printf("Ooops\n"); 9289 return (0); 9290 } 9291} 9292 9293static void 9294bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9295{ 9296 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9297 struct bwn_plcp6 *plcp; 9298 struct bwn_softc *sc = mac->mac_sc; 9299 struct ieee80211_frame_min *wh; 9300 struct ieee80211_node *ni; 9301 struct ifnet *ifp = sc->sc_ifp; 9302 struct ieee80211com *ic = ifp->if_l2com; 9303 uint32_t macstat; 9304 int padding, rate, rssi = 0, noise = 0, type; 9305 uint16_t phytype, phystat0, phystat3, chanstat; 9306 unsigned char *mp = mtod(m, unsigned char *); 9307 static int rx_mac_dec_rpt = 0; 9308 9309 BWN_ASSERT_LOCKED(sc); 9310 9311 phystat0 = le16toh(rxhdr->phy_status0); 9312 phystat3 = le16toh(rxhdr->phy_status3); 9313 macstat = le32toh(rxhdr->mac_status); 9314 chanstat = le16toh(rxhdr->channel); 9315 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9316 9317 if (macstat & BWN_RX_MAC_FCSERR) 9318 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9319 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9320 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9321 if (macstat & BWN_RX_MAC_DECERR) 9322 goto drop; 9323 9324 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9325 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9326 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9327 m->m_pkthdr.len); 9328 goto drop; 9329 } 9330 plcp = (struct bwn_plcp6 *)(mp + padding); 9331 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9332 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9333 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9334 m->m_pkthdr.len); 9335 goto drop; 9336 } 9337 wh = mtod(m, struct ieee80211_frame_min *); 9338 9339 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9340 device_printf(sc->sc_dev, 9341 "RX decryption attempted (old %d keyidx %#x)\n", 9342 BWN_ISOLDFMT(mac), 9343 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9344 9345 /* XXX calculating RSSI & noise & antenna */ 9346 9347 if (phystat0 & BWN_RX_PHYST0_OFDM) 9348 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9349 phytype == BWN_PHYTYPE_A); 9350 else 9351 rate = bwn_plcp_get_cckrate(mac, plcp); 9352 if (rate == -1) { 9353 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9354 goto drop; 9355 } 9356 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9357 9358 /* RX radio tap */ 9359 if (ieee80211_radiotap_active(ic)) 9360 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9361 m_adj(m, -IEEE80211_CRC_LEN); 9362 9363 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9364 noise = mac->mac_stats.link_noise; 9365 9366 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 9367 9368 BWN_UNLOCK(sc); 9369 9370 ni = ieee80211_find_rxnode(ic, wh); 9371 if (ni != NULL) { 9372 type = ieee80211_input(ni, m, rssi, noise); 9373 ieee80211_free_node(ni); 9374 } else 9375 type = ieee80211_input_all(ic, m, rssi, noise); 9376 9377 BWN_LOCK(sc); 9378 return; 9379drop: 9380 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9381} 9382 9383static void 9384bwn_dma_handle_txeof(struct bwn_mac *mac, 9385 const struct bwn_txstatus *status) 9386{ 9387 struct bwn_dma *dma = &mac->mac_method.dma; 9388 struct bwn_dma_ring *dr; 9389 struct bwn_dmadesc_generic *desc; 9390 struct bwn_dmadesc_meta *meta; 9391 struct bwn_softc *sc = mac->mac_sc; 9392 struct ieee80211_node *ni; 9393 struct ifnet *ifp = sc->sc_ifp; 9394 struct mbuf *m; 9395 int slot; 9396 9397 BWN_ASSERT_LOCKED(sc); 9398 9399 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9400 if (dr == NULL) { 9401 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9402 return; 9403 } 9404 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9405 9406 while (1) { 9407 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9408 ("%s:%d: fail", __func__, __LINE__)); 9409 dr->getdesc(dr, slot, &desc, &meta); 9410 9411 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9412 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9413 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9414 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9415 9416 if (meta->mt_islast) { 9417 KASSERT(meta->mt_m != NULL, 9418 ("%s:%d: fail", __func__, __LINE__)); 9419 9420 ni = meta->mt_ni; 9421 m = meta->mt_m; 9422 if (ni != NULL) { 9423 /* 9424 * Do any tx complete callback. Note this must 9425 * be done before releasing the node reference. 9426 */ 9427 if (m->m_flags & M_TXCB) 9428 ieee80211_process_callback(ni, m, 0); 9429 ieee80211_free_node(ni); 9430 meta->mt_ni = NULL; 9431 } 9432 m_freem(m); 9433 meta->mt_m = NULL; 9434 } else { 9435 KASSERT(meta->mt_m == NULL, 9436 ("%s:%d: fail", __func__, __LINE__)); 9437 } 9438 9439 dr->dr_usedslot--; 9440 if (meta->mt_islast) { 9441 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9442 break; 9443 } 9444 slot = bwn_dma_nextslot(dr, slot); 9445 } 9446 sc->sc_watchdog_timer = 0; 9447 if (dr->dr_stop) { 9448 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9449 ("%s:%d: fail", __func__, __LINE__)); 9450 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9451 dr->dr_stop = 0; 9452 } 9453} 9454 9455static void 9456bwn_pio_handle_txeof(struct bwn_mac *mac, 9457 const struct bwn_txstatus *status) 9458{ 9459 struct bwn_pio_txqueue *tq; 9460 struct bwn_pio_txpkt *tp = NULL; 9461 struct bwn_softc *sc = mac->mac_sc; 9462 struct ifnet *ifp = sc->sc_ifp; 9463 9464 BWN_ASSERT_LOCKED(sc); 9465 9466 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9467 if (tq == NULL) 9468 return; 9469 9470 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9471 tq->tq_free++; 9472 9473 if (tp->tp_ni != NULL) { 9474 /* 9475 * Do any tx complete callback. Note this must 9476 * be done before releasing the node reference. 9477 */ 9478 if (tp->tp_m->m_flags & M_TXCB) 9479 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9480 ieee80211_free_node(tp->tp_ni); 9481 tp->tp_ni = NULL; 9482 } 9483 m_freem(tp->tp_m); 9484 tp->tp_m = NULL; 9485 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9486 9487 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9488 9489 sc->sc_watchdog_timer = 0; 9490 if (tq->tq_stop) { 9491 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9492 tq->tq_stop = 0; 9493 } 9494} 9495 9496static void 9497bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9498{ 9499 struct bwn_softc *sc = mac->mac_sc; 9500 struct bwn_phy *phy = &mac->mac_phy; 9501 struct ifnet *ifp = sc->sc_ifp; 9502 struct ieee80211com *ic = ifp->if_l2com; 9503 unsigned long now; 9504 int result; 9505 9506 BWN_GETTIME(now); 9507 9508 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9509 return; 9510 phy->nexttime = now + 2 * 1000; 9511 9512 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9513 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9514 return; 9515 9516 if (phy->recalc_txpwr != NULL) { 9517 result = phy->recalc_txpwr(mac, 9518 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9519 if (result == BWN_TXPWR_RES_DONE) 9520 return; 9521 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9522 ("%s: fail", __func__)); 9523 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9524 9525 ieee80211_runtask(ic, &mac->mac_txpower); 9526 } 9527} 9528 9529static uint16_t 9530bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9531{ 9532 9533 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9534} 9535 9536static uint32_t 9537bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9538{ 9539 9540 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9541} 9542 9543static void 9544bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9545{ 9546 9547 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9548} 9549 9550static void 9551bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9552{ 9553 9554 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9555} 9556 9557static int 9558bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9559{ 9560 9561 switch (rate) { 9562 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9563 case 12: 9564 return (BWN_OFDM_RATE_6MB); 9565 case 18: 9566 return (BWN_OFDM_RATE_9MB); 9567 case 24: 9568 return (BWN_OFDM_RATE_12MB); 9569 case 36: 9570 return (BWN_OFDM_RATE_18MB); 9571 case 48: 9572 return (BWN_OFDM_RATE_24MB); 9573 case 72: 9574 return (BWN_OFDM_RATE_36MB); 9575 case 96: 9576 return (BWN_OFDM_RATE_48MB); 9577 case 108: 9578 return (BWN_OFDM_RATE_54MB); 9579 /* CCK rates (NB: not IEEE std, device-specific) */ 9580 case 2: 9581 return (BWN_CCK_RATE_1MB); 9582 case 4: 9583 return (BWN_CCK_RATE_2MB); 9584 case 11: 9585 return (BWN_CCK_RATE_5MB); 9586 case 22: 9587 return (BWN_CCK_RATE_11MB); 9588 } 9589 9590 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9591 return (BWN_CCK_RATE_1MB); 9592} 9593 9594static int 9595bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9596 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9597{ 9598 const struct bwn_phy *phy = &mac->mac_phy; 9599 struct bwn_softc *sc = mac->mac_sc; 9600 struct ieee80211_frame *wh; 9601 struct ieee80211_frame *protwh; 9602 struct ieee80211_frame_cts *cts; 9603 struct ieee80211_frame_rts *rts; 9604 const struct ieee80211_txparam *tp; 9605 struct ieee80211vap *vap = ni->ni_vap; 9606 struct ifnet *ifp = sc->sc_ifp; 9607 struct ieee80211com *ic = ifp->if_l2com; 9608 struct mbuf *mprot; 9609 unsigned int len; 9610 uint32_t macctl = 0; 9611 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9612 uint16_t phyctl = 0; 9613 uint8_t rate, rate_fb; 9614 9615 wh = mtod(m, struct ieee80211_frame *); 9616 memset(txhdr, 0, sizeof(*txhdr)); 9617 9618 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9619 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9620 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9621 9622 /* 9623 * Find TX rate 9624 */ 9625 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9626 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9627 rate = rate_fb = tp->mgmtrate; 9628 else if (ismcast) 9629 rate = rate_fb = tp->mcastrate; 9630 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9631 rate = rate_fb = tp->ucastrate; 9632 else { 9633 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9634 rate = ni->ni_txrate; 9635 9636 if (rix > 0) 9637 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9638 IEEE80211_RATE_VAL; 9639 else 9640 rate_fb = rate; 9641 } 9642 9643 sc->sc_tx_rate = rate; 9644 9645 rate = bwn_ieeerate2hwrate(sc, rate); 9646 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9647 9648 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9649 bwn_plcp_getcck(rate); 9650 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9651 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9652 9653 if ((rate_fb == rate) || 9654 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9655 (*(u_int16_t *)wh->i_dur == htole16(0))) 9656 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9657 else 9658 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9659 m->m_pkthdr.len, rate, isshort); 9660 9661 /* XXX TX encryption */ 9662 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9663 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9664 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9665 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9666 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9667 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9668 9669 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9670 BWN_TX_EFT_FB_CCK; 9671 txhdr->chan = phy->chan; 9672 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9673 BWN_TX_PHY_ENC_CCK; 9674 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9675 rate == BWN_CCK_RATE_11MB)) 9676 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9677 9678 /* XXX TX antenna selection */ 9679 9680 switch (bwn_antenna_sanitize(mac, 0)) { 9681 case 0: 9682 phyctl |= BWN_TX_PHY_ANT01AUTO; 9683 break; 9684 case 1: 9685 phyctl |= BWN_TX_PHY_ANT0; 9686 break; 9687 case 2: 9688 phyctl |= BWN_TX_PHY_ANT1; 9689 break; 9690 case 3: 9691 phyctl |= BWN_TX_PHY_ANT2; 9692 break; 9693 case 4: 9694 phyctl |= BWN_TX_PHY_ANT3; 9695 break; 9696 default: 9697 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9698 } 9699 9700 if (!ismcast) 9701 macctl |= BWN_TX_MAC_ACK; 9702 9703 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9704 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9705 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9706 macctl |= BWN_TX_MAC_LONGFRAME; 9707 9708 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9709 /* XXX RTS rate is always 1MB??? */ 9710 rts_rate = BWN_CCK_RATE_1MB; 9711 rts_rate_fb = bwn_get_fbrate(rts_rate); 9712 9713 protdur = ieee80211_compute_duration(ic->ic_rt, 9714 m->m_pkthdr.len, rate, isshort) + 9715 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9716 9717 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9718 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9719 (txhdr->body.old.rts_frame) : 9720 (txhdr->body.new.rts_frame)); 9721 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9722 protdur); 9723 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9724 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9725 mprot->m_pkthdr.len); 9726 m_freem(mprot); 9727 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9728 len = sizeof(struct ieee80211_frame_cts); 9729 } else { 9730 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9731 (txhdr->body.old.rts_frame) : 9732 (txhdr->body.new.rts_frame)); 9733 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9734 isshort); 9735 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9736 wh->i_addr2, protdur); 9737 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9738 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9739 mprot->m_pkthdr.len); 9740 m_freem(mprot); 9741 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9742 len = sizeof(struct ieee80211_frame_rts); 9743 } 9744 len += IEEE80211_CRC_LEN; 9745 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9746 &txhdr->body.old.rts_plcp : 9747 &txhdr->body.new.rts_plcp), len, rts_rate); 9748 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9749 rts_rate_fb); 9750 9751 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9752 (&txhdr->body.old.rts_frame) : 9753 (&txhdr->body.new.rts_frame)); 9754 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9755 9756 if (BWN_ISOFDMRATE(rts_rate)) { 9757 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9758 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9759 } else { 9760 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9761 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9762 } 9763 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9764 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9765 } 9766 9767 if (BWN_ISOLDFMT(mac)) 9768 txhdr->body.old.cookie = htole16(cookie); 9769 else 9770 txhdr->body.new.cookie = htole16(cookie); 9771 9772 txhdr->macctl = htole32(macctl); 9773 txhdr->phyctl = htole16(phyctl); 9774 9775 /* 9776 * TX radio tap 9777 */ 9778 if (ieee80211_radiotap_active_vap(vap)) { 9779 sc->sc_tx_th.wt_flags = 0; 9780 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9781 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9782 if (isshort && 9783 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9784 rate == BWN_CCK_RATE_11MB)) 9785 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9786 sc->sc_tx_th.wt_rate = rate; 9787 9788 ieee80211_radiotap_tx(vap, m); 9789 } 9790 9791 return (0); 9792} 9793 9794static void 9795bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9796 const uint8_t rate) 9797{ 9798 uint32_t d, plen; 9799 uint8_t *raw = plcp->o.raw; 9800 9801 if (BWN_ISOFDMRATE(rate)) { 9802 d = bwn_plcp_getofdm(rate); 9803 KASSERT(!(octets & 0xf000), 9804 ("%s:%d: fail", __func__, __LINE__)); 9805 d |= (octets << 5); 9806 plcp->o.data = htole32(d); 9807 } else { 9808 plen = octets * 16 / rate; 9809 if ((octets * 16 % rate) > 0) { 9810 plen++; 9811 if ((rate == BWN_CCK_RATE_11MB) 9812 && ((octets * 8 % 11) < 4)) { 9813 raw[1] = 0x84; 9814 } else 9815 raw[1] = 0x04; 9816 } else 9817 raw[1] = 0x04; 9818 plcp->o.data |= htole32(plen << 16); 9819 raw[0] = bwn_plcp_getcck(rate); 9820 } 9821} 9822 9823static uint8_t 9824bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9825{ 9826 struct bwn_softc *sc = mac->mac_sc; 9827 uint8_t mask; 9828 9829 if (n == 0) 9830 return (0); 9831 if (mac->mac_phy.gmode) 9832 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9833 else 9834 mask = siba_sprom_get_ant_a(sc->sc_dev); 9835 if (!(mask & (1 << (n - 1)))) 9836 return (0); 9837 return (n); 9838} 9839 9840static uint8_t 9841bwn_get_fbrate(uint8_t bitrate) 9842{ 9843 switch (bitrate) { 9844 case BWN_CCK_RATE_1MB: 9845 return (BWN_CCK_RATE_1MB); 9846 case BWN_CCK_RATE_2MB: 9847 return (BWN_CCK_RATE_1MB); 9848 case BWN_CCK_RATE_5MB: 9849 return (BWN_CCK_RATE_2MB); 9850 case BWN_CCK_RATE_11MB: 9851 return (BWN_CCK_RATE_5MB); 9852 case BWN_OFDM_RATE_6MB: 9853 return (BWN_CCK_RATE_5MB); 9854 case BWN_OFDM_RATE_9MB: 9855 return (BWN_OFDM_RATE_6MB); 9856 case BWN_OFDM_RATE_12MB: 9857 return (BWN_OFDM_RATE_9MB); 9858 case BWN_OFDM_RATE_18MB: 9859 return (BWN_OFDM_RATE_12MB); 9860 case BWN_OFDM_RATE_24MB: 9861 return (BWN_OFDM_RATE_18MB); 9862 case BWN_OFDM_RATE_36MB: 9863 return (BWN_OFDM_RATE_24MB); 9864 case BWN_OFDM_RATE_48MB: 9865 return (BWN_OFDM_RATE_36MB); 9866 case BWN_OFDM_RATE_54MB: 9867 return (BWN_OFDM_RATE_48MB); 9868 } 9869 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9870 return (0); 9871} 9872 9873static uint32_t 9874bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9875 uint32_t ctl, const void *_data, int len) 9876{ 9877 struct bwn_softc *sc = mac->mac_sc; 9878 uint32_t value = 0; 9879 const uint8_t *data = _data; 9880 9881 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9882 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9883 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9884 9885 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9886 tq->tq_base + BWN_PIO8_TXDATA); 9887 if (len & 3) { 9888 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9889 BWN_PIO8_TXCTL_24_31); 9890 data = &(data[len - 1]); 9891 switch (len & 3) { 9892 case 3: 9893 ctl |= BWN_PIO8_TXCTL_16_23; 9894 value |= (uint32_t)(*data) << 16; 9895 data--; 9896 case 2: 9897 ctl |= BWN_PIO8_TXCTL_8_15; 9898 value |= (uint32_t)(*data) << 8; 9899 data--; 9900 case 1: 9901 value |= (uint32_t)(*data); 9902 } 9903 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9904 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9905 } 9906 9907 return (ctl); 9908} 9909 9910static void 9911bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9912 uint16_t offset, uint32_t value) 9913{ 9914 9915 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9916} 9917 9918static uint16_t 9919bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9920 uint16_t ctl, const void *_data, int len) 9921{ 9922 struct bwn_softc *sc = mac->mac_sc; 9923 const uint8_t *data = _data; 9924 9925 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9926 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9927 9928 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9929 tq->tq_base + BWN_PIO_TXDATA); 9930 if (len & 1) { 9931 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9932 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9933 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9934 } 9935 9936 return (ctl); 9937} 9938 9939static uint16_t 9940bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9941 uint16_t ctl, struct mbuf *m0) 9942{ 9943 int i, j = 0; 9944 uint16_t data = 0; 9945 const uint8_t *buf; 9946 struct mbuf *m = m0; 9947 9948 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9949 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9950 9951 for (; m != NULL; m = m->m_next) { 9952 buf = mtod(m, const uint8_t *); 9953 for (i = 0; i < m->m_len; i++) { 9954 if (!((j++) % 2)) 9955 data |= buf[i]; 9956 else { 9957 data |= (buf[i] << 8); 9958 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9959 data = 0; 9960 } 9961 } 9962 } 9963 if (m0->m_pkthdr.len % 2) { 9964 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9965 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9966 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9967 } 9968 9969 return (ctl); 9970} 9971 9972static void 9973bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9974{ 9975 9976 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9977 return; 9978 BWN_WRITE_2(mac, 0x684, 510 + time); 9979 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9980} 9981 9982static struct bwn_dma_ring * 9983bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9984{ 9985 9986 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9987 return (mac->mac_method.dma.wme[WME_AC_BE]); 9988 9989 switch (prio) { 9990 case 3: 9991 return (mac->mac_method.dma.wme[WME_AC_VO]); 9992 case 2: 9993 return (mac->mac_method.dma.wme[WME_AC_VI]); 9994 case 0: 9995 return (mac->mac_method.dma.wme[WME_AC_BE]); 9996 case 1: 9997 return (mac->mac_method.dma.wme[WME_AC_BK]); 9998 } 9999 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10000 return (NULL); 10001} 10002 10003static int 10004bwn_dma_getslot(struct bwn_dma_ring *dr) 10005{ 10006 int slot; 10007 10008 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10009 10010 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10011 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10012 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10013 10014 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10015 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10016 dr->dr_curslot = slot; 10017 dr->dr_usedslot++; 10018 10019 return (slot); 10020} 10021 10022static int 10023bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10024{ 10025 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10026 unsigned int a, b, c, d; 10027 unsigned int avg; 10028 uint32_t tmp; 10029 10030 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10031 a = tmp & 0xff; 10032 b = (tmp >> 8) & 0xff; 10033 c = (tmp >> 16) & 0xff; 10034 d = (tmp >> 24) & 0xff; 10035 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10036 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10037 return (ENOENT); 10038 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10039 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10040 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10041 10042 if (ofdm) { 10043 a = (a + 32) & 0x3f; 10044 b = (b + 32) & 0x3f; 10045 c = (c + 32) & 0x3f; 10046 d = (d + 32) & 0x3f; 10047 } 10048 10049 avg = (a + b + c + d + 2) / 4; 10050 if (ofdm) { 10051 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10052 & BWN_HF_4DB_CCK_POWERBOOST) 10053 avg = (avg >= 13) ? (avg - 13) : 0; 10054 } 10055 return (avg); 10056} 10057 10058static void 10059bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10060{ 10061 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10062 int rfatt = *rfattp; 10063 int bbatt = *bbattp; 10064 10065 while (1) { 10066 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10067 break; 10068 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10069 break; 10070 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10071 break; 10072 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10073 break; 10074 if (bbatt > lo->bbatt.max) { 10075 bbatt -= 4; 10076 rfatt += 1; 10077 continue; 10078 } 10079 if (bbatt < lo->bbatt.min) { 10080 bbatt += 4; 10081 rfatt -= 1; 10082 continue; 10083 } 10084 if (rfatt > lo->rfatt.max) { 10085 rfatt -= 1; 10086 bbatt += 4; 10087 continue; 10088 } 10089 if (rfatt < lo->rfatt.min) { 10090 rfatt += 1; 10091 bbatt -= 4; 10092 continue; 10093 } 10094 break; 10095 } 10096 10097 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10098 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10099} 10100 10101static void 10102bwn_phy_lock(struct bwn_mac *mac) 10103{ 10104 struct bwn_softc *sc = mac->mac_sc; 10105 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10106 10107 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10108 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10109 10110 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10111 bwn_psctl(mac, BWN_PS_AWAKE); 10112} 10113 10114static void 10115bwn_phy_unlock(struct bwn_mac *mac) 10116{ 10117 struct bwn_softc *sc = mac->mac_sc; 10118 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10119 10120 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10121 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10122 10123 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10124 bwn_psctl(mac, 0); 10125} 10126 10127static void 10128bwn_rf_lock(struct bwn_mac *mac) 10129{ 10130 10131 BWN_WRITE_4(mac, BWN_MACCTL, 10132 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10133 BWN_READ_4(mac, BWN_MACCTL); 10134 DELAY(10); 10135} 10136 10137static void 10138bwn_rf_unlock(struct bwn_mac *mac) 10139{ 10140 10141 BWN_READ_2(mac, BWN_PHYVER); 10142 BWN_WRITE_4(mac, BWN_MACCTL, 10143 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10144} 10145 10146static struct bwn_pio_txqueue * 10147bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10148 struct bwn_pio_txpkt **pack) 10149{ 10150 struct bwn_pio *pio = &mac->mac_method.pio; 10151 struct bwn_pio_txqueue *tq = NULL; 10152 unsigned int index; 10153 10154 switch (cookie & 0xf000) { 10155 case 0x1000: 10156 tq = &pio->wme[WME_AC_BK]; 10157 break; 10158 case 0x2000: 10159 tq = &pio->wme[WME_AC_BE]; 10160 break; 10161 case 0x3000: 10162 tq = &pio->wme[WME_AC_VI]; 10163 break; 10164 case 0x4000: 10165 tq = &pio->wme[WME_AC_VO]; 10166 break; 10167 case 0x5000: 10168 tq = &pio->mcast; 10169 break; 10170 } 10171 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10172 if (tq == NULL) 10173 return (NULL); 10174 index = (cookie & 0x0fff); 10175 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10176 if (index >= N(tq->tq_pkts)) 10177 return (NULL); 10178 *pack = &tq->tq_pkts[index]; 10179 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10180 return (tq); 10181} 10182 10183static void 10184bwn_txpwr(void *arg, int npending) 10185{ 10186 struct bwn_mac *mac = arg; 10187 struct bwn_softc *sc = mac->mac_sc; 10188 10189 BWN_LOCK(sc); 10190 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10191 mac->mac_phy.set_txpwr != NULL) 10192 mac->mac_phy.set_txpwr(mac); 10193 BWN_UNLOCK(sc); 10194} 10195 10196static void 10197bwn_task_15s(struct bwn_mac *mac) 10198{ 10199 uint16_t reg; 10200 10201 if (mac->mac_fw.opensource) { 10202 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10203 if (reg) { 10204 bwn_restart(mac, "fw watchdog"); 10205 return; 10206 } 10207 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10208 } 10209 if (mac->mac_phy.task_15s) 10210 mac->mac_phy.task_15s(mac); 10211 10212 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10213} 10214 10215static void 10216bwn_task_30s(struct bwn_mac *mac) 10217{ 10218 10219 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10220 return; 10221 mac->mac_noise.noi_running = 1; 10222 mac->mac_noise.noi_nsamples = 0; 10223 10224 bwn_noise_gensample(mac); 10225} 10226 10227static void 10228bwn_task_60s(struct bwn_mac *mac) 10229{ 10230 10231 if (mac->mac_phy.task_60s) 10232 mac->mac_phy.task_60s(mac); 10233 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10234} 10235 10236static void 10237bwn_tasks(void *arg) 10238{ 10239 struct bwn_mac *mac = arg; 10240 struct bwn_softc *sc = mac->mac_sc; 10241 10242 BWN_ASSERT_LOCKED(sc); 10243 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10244 return; 10245 10246 if (mac->mac_task_state % 4 == 0) 10247 bwn_task_60s(mac); 10248 if (mac->mac_task_state % 2 == 0) 10249 bwn_task_30s(mac); 10250 bwn_task_15s(mac); 10251 10252 mac->mac_task_state++; 10253 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10254} 10255 10256static int 10257bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10258{ 10259 struct bwn_softc *sc = mac->mac_sc; 10260 10261 KASSERT(a == 0, ("not support APHY\n")); 10262 10263 switch (plcp->o.raw[0] & 0xf) { 10264 case 0xb: 10265 return (BWN_OFDM_RATE_6MB); 10266 case 0xf: 10267 return (BWN_OFDM_RATE_9MB); 10268 case 0xa: 10269 return (BWN_OFDM_RATE_12MB); 10270 case 0xe: 10271 return (BWN_OFDM_RATE_18MB); 10272 case 0x9: 10273 return (BWN_OFDM_RATE_24MB); 10274 case 0xd: 10275 return (BWN_OFDM_RATE_36MB); 10276 case 0x8: 10277 return (BWN_OFDM_RATE_48MB); 10278 case 0xc: 10279 return (BWN_OFDM_RATE_54MB); 10280 } 10281 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10282 plcp->o.raw[0] & 0xf); 10283 return (-1); 10284} 10285 10286static int 10287bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10288{ 10289 struct bwn_softc *sc = mac->mac_sc; 10290 10291 switch (plcp->o.raw[0]) { 10292 case 0x0a: 10293 return (BWN_CCK_RATE_1MB); 10294 case 0x14: 10295 return (BWN_CCK_RATE_2MB); 10296 case 0x37: 10297 return (BWN_CCK_RATE_5MB); 10298 case 0x6e: 10299 return (BWN_CCK_RATE_11MB); 10300 } 10301 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10302 return (-1); 10303} 10304 10305static void 10306bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10307 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10308 int rssi, int noise) 10309{ 10310 struct bwn_softc *sc = mac->mac_sc; 10311 const struct ieee80211_frame_min *wh; 10312 uint64_t tsf; 10313 uint16_t low_mactime_now; 10314 10315 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10316 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10317 10318 wh = mtod(m, const struct ieee80211_frame_min *); 10319 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10320 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10321 10322 bwn_tsf_read(mac, &tsf); 10323 low_mactime_now = tsf; 10324 tsf = tsf & ~0xffffULL; 10325 tsf += le16toh(rxhdr->mac_time); 10326 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10327 tsf -= 0x10000; 10328 10329 sc->sc_rx_th.wr_tsf = tsf; 10330 sc->sc_rx_th.wr_rate = rate; 10331 sc->sc_rx_th.wr_antsignal = rssi; 10332 sc->sc_rx_th.wr_antnoise = noise; 10333} 10334 10335static void 10336bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10337{ 10338 uint32_t low, high; 10339 10340 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10341 ("%s:%d: fail", __func__, __LINE__)); 10342 10343 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10344 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10345 *tsf = high; 10346 *tsf <<= 32; 10347 *tsf |= low; 10348} 10349 10350static int 10351bwn_dma_attach(struct bwn_mac *mac) 10352{ 10353 struct bwn_dma *dma = &mac->mac_method.dma; 10354 struct bwn_softc *sc = mac->mac_sc; 10355 bus_addr_t lowaddr = 0; 10356 int error; 10357 10358 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10359 return (0); 10360 10361 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10362 10363 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10364 10365 dma->dmatype = bwn_dma_gettype(mac); 10366 if (dma->dmatype == BWN_DMA_30BIT) 10367 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10368 else if (dma->dmatype == BWN_DMA_32BIT) 10369 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10370 else 10371 lowaddr = BUS_SPACE_MAXADDR; 10372 10373 /* 10374 * Create top level DMA tag 10375 */ 10376 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10377 BWN_ALIGN, 0, /* alignment, bounds */ 10378 lowaddr, /* lowaddr */ 10379 BUS_SPACE_MAXADDR, /* highaddr */ 10380 NULL, NULL, /* filter, filterarg */ 10381 BUS_SPACE_MAXSIZE, /* maxsize */ 10382 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10383 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10384 0, /* flags */ 10385 NULL, NULL, /* lockfunc, lockarg */ 10386 &dma->parent_dtag); 10387 if (error) { 10388 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10389 return (error); 10390 } 10391 10392 /* 10393 * Create TX/RX mbuf DMA tag 10394 */ 10395 error = bus_dma_tag_create(dma->parent_dtag, 10396 1, 10397 0, 10398 BUS_SPACE_MAXADDR, 10399 BUS_SPACE_MAXADDR, 10400 NULL, NULL, 10401 MCLBYTES, 10402 1, 10403 BUS_SPACE_MAXSIZE_32BIT, 10404 0, 10405 NULL, NULL, 10406 &dma->rxbuf_dtag); 10407 if (error) { 10408 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10409 goto fail0; 10410 } 10411 error = bus_dma_tag_create(dma->parent_dtag, 10412 1, 10413 0, 10414 BUS_SPACE_MAXADDR, 10415 BUS_SPACE_MAXADDR, 10416 NULL, NULL, 10417 MCLBYTES, 10418 1, 10419 BUS_SPACE_MAXSIZE_32BIT, 10420 0, 10421 NULL, NULL, 10422 &dma->txbuf_dtag); 10423 if (error) { 10424 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10425 goto fail1; 10426 } 10427 10428 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10429 if (!dma->wme[WME_AC_BK]) 10430 goto fail2; 10431 10432 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10433 if (!dma->wme[WME_AC_BE]) 10434 goto fail3; 10435 10436 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10437 if (!dma->wme[WME_AC_VI]) 10438 goto fail4; 10439 10440 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10441 if (!dma->wme[WME_AC_VO]) 10442 goto fail5; 10443 10444 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10445 if (!dma->mcast) 10446 goto fail6; 10447 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10448 if (!dma->rx) 10449 goto fail7; 10450 10451 return (error); 10452 10453fail7: bwn_dma_ringfree(&dma->mcast); 10454fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10455fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10456fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10457fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10458fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10459fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10460fail0: bus_dma_tag_destroy(dma->parent_dtag); 10461 return (error); 10462} 10463 10464static struct bwn_dma_ring * 10465bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10466 uint16_t cookie, int *slot) 10467{ 10468 struct bwn_dma *dma = &mac->mac_method.dma; 10469 struct bwn_dma_ring *dr; 10470 struct bwn_softc *sc = mac->mac_sc; 10471 10472 BWN_ASSERT_LOCKED(mac->mac_sc); 10473 10474 switch (cookie & 0xf000) { 10475 case 0x1000: 10476 dr = dma->wme[WME_AC_BK]; 10477 break; 10478 case 0x2000: 10479 dr = dma->wme[WME_AC_BE]; 10480 break; 10481 case 0x3000: 10482 dr = dma->wme[WME_AC_VI]; 10483 break; 10484 case 0x4000: 10485 dr = dma->wme[WME_AC_VO]; 10486 break; 10487 case 0x5000: 10488 dr = dma->mcast; 10489 break; 10490 default: 10491 dr = NULL; 10492 KASSERT(0 == 1, 10493 ("invalid cookie value %d", cookie & 0xf000)); 10494 } 10495 *slot = (cookie & 0x0fff); 10496 if (*slot < 0 || *slot >= dr->dr_numslots) { 10497 /* 10498 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10499 * that it occurs events which have same H/W sequence numbers. 10500 * When it's occurred just prints a WARNING msgs and ignores. 10501 */ 10502 KASSERT(status->seq == dma->lastseq, 10503 ("%s:%d: fail", __func__, __LINE__)); 10504 device_printf(sc->sc_dev, 10505 "out of slot ranges (0 < %d < %d)\n", *slot, 10506 dr->dr_numslots); 10507 return (NULL); 10508 } 10509 dma->lastseq = status->seq; 10510 return (dr); 10511} 10512 10513static void 10514bwn_dma_stop(struct bwn_mac *mac) 10515{ 10516 struct bwn_dma *dma; 10517 10518 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10519 return; 10520 dma = &mac->mac_method.dma; 10521 10522 bwn_dma_ringstop(&dma->rx); 10523 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10524 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10525 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10526 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10527 bwn_dma_ringstop(&dma->mcast); 10528} 10529 10530static void 10531bwn_dma_ringstop(struct bwn_dma_ring **dr) 10532{ 10533 10534 if (dr == NULL) 10535 return; 10536 10537 bwn_dma_cleanup(*dr); 10538} 10539 10540static void 10541bwn_pio_stop(struct bwn_mac *mac) 10542{ 10543 struct bwn_pio *pio; 10544 10545 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10546 return; 10547 pio = &mac->mac_method.pio; 10548 10549 bwn_destroy_queue_tx(&pio->mcast); 10550 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10551 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10552 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10553 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10554} 10555 10556static void 10557bwn_led_attach(struct bwn_mac *mac) 10558{ 10559 struct bwn_softc *sc = mac->mac_sc; 10560 const uint8_t *led_act = NULL; 10561 uint16_t val[BWN_LED_MAX]; 10562 int i; 10563 10564 sc->sc_led_idle = (2350 * hz) / 1000; 10565 sc->sc_led_blink = 1; 10566 10567 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10568 if (siba_get_pci_subvendor(sc->sc_dev) == 10569 bwn_vendor_led_act[i].vid) { 10570 led_act = bwn_vendor_led_act[i].led_act; 10571 break; 10572 } 10573 } 10574 if (led_act == NULL) 10575 led_act = bwn_default_led_act; 10576 10577 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10578 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10579 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10580 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10581 10582 for (i = 0; i < BWN_LED_MAX; ++i) { 10583 struct bwn_led *led = &sc->sc_leds[i]; 10584 10585 if (val[i] == 0xff) { 10586 led->led_act = led_act[i]; 10587 } else { 10588 if (val[i] & BWN_LED_ACT_LOW) 10589 led->led_flags |= BWN_LED_F_ACTLOW; 10590 led->led_act = val[i] & BWN_LED_ACT_MASK; 10591 } 10592 led->led_mask = (1 << i); 10593 10594 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10595 led->led_act == BWN_LED_ACT_BLINK_POLL || 10596 led->led_act == BWN_LED_ACT_BLINK) { 10597 led->led_flags |= BWN_LED_F_BLINK; 10598 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10599 led->led_flags |= BWN_LED_F_POLLABLE; 10600 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10601 led->led_flags |= BWN_LED_F_SLOW; 10602 10603 if (sc->sc_blink_led == NULL) { 10604 sc->sc_blink_led = led; 10605 if (led->led_flags & BWN_LED_F_SLOW) 10606 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10607 } 10608 } 10609 10610 DPRINTF(sc, BWN_DEBUG_LED, 10611 "%dth led, act %d, lowact %d\n", i, 10612 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10613 } 10614 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10615} 10616 10617static __inline uint16_t 10618bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10619{ 10620 10621 if (led->led_flags & BWN_LED_F_ACTLOW) 10622 on = !on; 10623 if (on) 10624 val |= led->led_mask; 10625 else 10626 val &= ~led->led_mask; 10627 return val; 10628} 10629 10630static void 10631bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10632{ 10633 struct bwn_softc *sc = mac->mac_sc; 10634 struct ifnet *ifp = sc->sc_ifp; 10635 struct ieee80211com *ic = ifp->if_l2com; 10636 uint16_t val; 10637 int i; 10638 10639 if (nstate == IEEE80211_S_INIT) { 10640 callout_stop(&sc->sc_led_blink_ch); 10641 sc->sc_led_blinking = 0; 10642 } 10643 10644 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10645 return; 10646 10647 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10648 for (i = 0; i < BWN_LED_MAX; ++i) { 10649 struct bwn_led *led = &sc->sc_leds[i]; 10650 int on; 10651 10652 if (led->led_act == BWN_LED_ACT_UNKN || 10653 led->led_act == BWN_LED_ACT_NULL) 10654 continue; 10655 10656 if ((led->led_flags & BWN_LED_F_BLINK) && 10657 nstate != IEEE80211_S_INIT) 10658 continue; 10659 10660 switch (led->led_act) { 10661 case BWN_LED_ACT_ON: /* Always on */ 10662 on = 1; 10663 break; 10664 case BWN_LED_ACT_OFF: /* Always off */ 10665 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10666 on = 0; 10667 break; 10668 default: 10669 on = 1; 10670 switch (nstate) { 10671 case IEEE80211_S_INIT: 10672 on = 0; 10673 break; 10674 case IEEE80211_S_RUN: 10675 if (led->led_act == BWN_LED_ACT_11G && 10676 ic->ic_curmode != IEEE80211_MODE_11G) 10677 on = 0; 10678 break; 10679 default: 10680 if (led->led_act == BWN_LED_ACT_ASSOC) 10681 on = 0; 10682 break; 10683 } 10684 break; 10685 } 10686 10687 val = bwn_led_onoff(led, val, on); 10688 } 10689 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10690} 10691 10692static void 10693bwn_led_event(struct bwn_mac *mac, int event) 10694{ 10695 struct bwn_softc *sc = mac->mac_sc; 10696 struct bwn_led *led = sc->sc_blink_led; 10697 int rate; 10698 10699 if (event == BWN_LED_EVENT_POLL) { 10700 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10701 return; 10702 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10703 return; 10704 } 10705 10706 sc->sc_led_ticks = ticks; 10707 if (sc->sc_led_blinking) 10708 return; 10709 10710 switch (event) { 10711 case BWN_LED_EVENT_RX: 10712 rate = sc->sc_rx_rate; 10713 break; 10714 case BWN_LED_EVENT_TX: 10715 rate = sc->sc_tx_rate; 10716 break; 10717 case BWN_LED_EVENT_POLL: 10718 rate = 0; 10719 break; 10720 default: 10721 panic("unknown LED event %d\n", event); 10722 break; 10723 } 10724 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10725 bwn_led_duration[rate].off_dur); 10726} 10727 10728static void 10729bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10730{ 10731 struct bwn_softc *sc = mac->mac_sc; 10732 struct bwn_led *led = sc->sc_blink_led; 10733 uint16_t val; 10734 10735 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10736 val = bwn_led_onoff(led, val, 1); 10737 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10738 10739 if (led->led_flags & BWN_LED_F_SLOW) { 10740 BWN_LED_SLOWDOWN(on_dur); 10741 BWN_LED_SLOWDOWN(off_dur); 10742 } 10743 10744 sc->sc_led_blinking = 1; 10745 sc->sc_led_blink_offdur = off_dur; 10746 10747 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10748} 10749 10750static void 10751bwn_led_blink_next(void *arg) 10752{ 10753 struct bwn_mac *mac = arg; 10754 struct bwn_softc *sc = mac->mac_sc; 10755 uint16_t val; 10756 10757 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10758 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10759 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10760 10761 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10762 bwn_led_blink_end, mac); 10763} 10764 10765static void 10766bwn_led_blink_end(void *arg) 10767{ 10768 struct bwn_mac *mac = arg; 10769 struct bwn_softc *sc = mac->mac_sc; 10770 10771 sc->sc_led_blinking = 0; 10772} 10773 10774static int 10775bwn_suspend(device_t dev) 10776{ 10777 struct bwn_softc *sc = device_get_softc(dev); 10778 10779 bwn_stop(sc, 1); 10780 return (0); 10781} 10782 10783static int 10784bwn_resume(device_t dev) 10785{ 10786 struct bwn_softc *sc = device_get_softc(dev); 10787 struct ifnet *ifp = sc->sc_ifp; 10788 10789 if (ifp->if_flags & IFF_UP) 10790 bwn_init(sc); 10791 return (0); 10792} 10793 10794static void 10795bwn_rfswitch(void *arg) 10796{ 10797 struct bwn_softc *sc = arg; 10798 struct bwn_mac *mac = sc->sc_curmac; 10799 int cur = 0, prev = 0; 10800 10801 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10802 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10803 10804 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10805 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10806 & BWN_RF_HWENABLED_HI_MASK)) 10807 cur = 1; 10808 } else { 10809 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10810 & BWN_RF_HWENABLED_LO_MASK) 10811 cur = 1; 10812 } 10813 10814 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10815 prev = 1; 10816 10817 if (cur != prev) { 10818 if (cur) 10819 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10820 else 10821 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10822 10823 device_printf(sc->sc_dev, 10824 "status of RF switch is changed to %s\n", 10825 cur ? "ON" : "OFF"); 10826 if (cur != mac->mac_phy.rf_on) { 10827 if (cur) 10828 bwn_rf_turnon(mac); 10829 else 10830 bwn_rf_turnoff(mac); 10831 } 10832 } 10833 10834 callout_schedule(&sc->sc_rfswitch_ch, hz); 10835} 10836 10837static void 10838bwn_phy_lp_init_pre(struct bwn_mac *mac) 10839{ 10840 struct bwn_phy *phy = &mac->mac_phy; 10841 struct bwn_phy_lp *plp = &phy->phy_lp; 10842 10843 plp->plp_antenna = BWN_ANT_DEFAULT; 10844} 10845 10846static int 10847bwn_phy_lp_init(struct bwn_mac *mac) 10848{ 10849 static const struct bwn_stxtable tables[] = { 10850 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10851 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10852 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10853 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10854 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10855 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10856 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10857 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10858 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10859 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10860 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10861 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10862 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10863 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10864 { 2, 11, 0x40, 0, 0x0f } 10865 }; 10866 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10867 struct bwn_softc *sc = mac->mac_sc; 10868 const struct bwn_stxtable *st; 10869 struct ifnet *ifp = sc->sc_ifp; 10870 struct ieee80211com *ic = ifp->if_l2com; 10871 int i, error; 10872 uint16_t tmp; 10873 10874 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10875 bwn_phy_lp_bbinit(mac); 10876 10877 /* initialize RF */ 10878 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10879 DELAY(1); 10880 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10881 DELAY(1); 10882 10883 if (mac->mac_phy.rf_ver == 0x2062) 10884 bwn_phy_lp_b2062_init(mac); 10885 else { 10886 bwn_phy_lp_b2063_init(mac); 10887 10888 /* synchronize stx table. */ 10889 for (i = 0; i < N(tables); i++) { 10890 st = &tables[i]; 10891 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10892 tmp >>= st->st_rfshift; 10893 tmp <<= st->st_physhift; 10894 BWN_PHY_SETMASK(mac, 10895 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10896 ~(st->st_mask << st->st_physhift), tmp); 10897 } 10898 10899 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10900 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10901 } 10902 10903 /* calibrate RC */ 10904 if (mac->mac_phy.rev >= 2) 10905 bwn_phy_lp_rxcal_r2(mac); 10906 else if (!plp->plp_rccap) { 10907 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10908 bwn_phy_lp_rccal_r12(mac); 10909 } else 10910 bwn_phy_lp_set_rccap(mac); 10911 10912 error = bwn_phy_lp_switch_channel(mac, 7); 10913 if (error) 10914 device_printf(sc->sc_dev, 10915 "failed to change channel 7 (%d)\n", error); 10916 bwn_phy_lp_txpctl_init(mac); 10917 bwn_phy_lp_calib(mac); 10918 return (0); 10919} 10920 10921static uint16_t 10922bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10923{ 10924 10925 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10926 return (BWN_READ_2(mac, BWN_PHYDATA)); 10927} 10928 10929static void 10930bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10931{ 10932 10933 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10934 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10935} 10936 10937static void 10938bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10939 uint16_t set) 10940{ 10941 10942 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10943 BWN_WRITE_2(mac, BWN_PHYDATA, 10944 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10945} 10946 10947static uint16_t 10948bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10949{ 10950 10951 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10952 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10953 reg |= 0x100; 10954 if (mac->mac_phy.rev >= 2) 10955 reg |= 0x200; 10956 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10957 return BWN_READ_2(mac, BWN_RFDATALO); 10958} 10959 10960static void 10961bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10962{ 10963 10964 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10965 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10966 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10967} 10968 10969static void 10970bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10971{ 10972 10973 if (on) { 10974 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10975 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10976 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10977 return; 10978 } 10979 10980 if (mac->mac_phy.rev >= 2) { 10981 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10982 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10983 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10984 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10985 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10986 return; 10987 } 10988 10989 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10990 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10991 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10992 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10993} 10994 10995static int 10996bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10997{ 10998 struct bwn_phy *phy = &mac->mac_phy; 10999 struct bwn_phy_lp *plp = &phy->phy_lp; 11000 int error; 11001 11002 if (phy->rf_ver == 0x2063) { 11003 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11004 if (error) 11005 return (error); 11006 } else { 11007 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11008 if (error) 11009 return (error); 11010 bwn_phy_lp_set_anafilter(mac, chan); 11011 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11012 } 11013 11014 plp->plp_chan = chan; 11015 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11016 return (0); 11017} 11018 11019static uint32_t 11020bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11021{ 11022 struct bwn_softc *sc = mac->mac_sc; 11023 struct ifnet *ifp = sc->sc_ifp; 11024 struct ieee80211com *ic = ifp->if_l2com; 11025 11026 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11027} 11028 11029static void 11030bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11031{ 11032 struct bwn_phy *phy = &mac->mac_phy; 11033 struct bwn_phy_lp *plp = &phy->phy_lp; 11034 11035 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11036 return; 11037 11038 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11039 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11040 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11041 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11042 plp->plp_antenna = antenna; 11043} 11044 11045static void 11046bwn_phy_lp_task_60s(struct bwn_mac *mac) 11047{ 11048 11049 bwn_phy_lp_calib(mac); 11050} 11051 11052static void 11053bwn_phy_lp_readsprom(struct bwn_mac *mac) 11054{ 11055 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11056 struct bwn_softc *sc = mac->mac_sc; 11057 struct ifnet *ifp = sc->sc_ifp; 11058 struct ieee80211com *ic = ifp->if_l2com; 11059 11060 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11061 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11062 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11063 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11064 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11065 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11066 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11067 return; 11068 } 11069 11070 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11071 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11072 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11073 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11074 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11075 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11076 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11077 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11078} 11079 11080static void 11081bwn_phy_lp_bbinit(struct bwn_mac *mac) 11082{ 11083 11084 bwn_phy_lp_tblinit(mac); 11085 if (mac->mac_phy.rev >= 2) 11086 bwn_phy_lp_bbinit_r2(mac); 11087 else 11088 bwn_phy_lp_bbinit_r01(mac); 11089} 11090 11091static void 11092bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11093{ 11094 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11095 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11096 struct bwn_softc *sc = mac->mac_sc; 11097 struct ifnet *ifp = sc->sc_ifp; 11098 struct ieee80211com *ic = ifp->if_l2com; 11099 11100 bwn_phy_lp_set_txgain(mac, 11101 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11102 bwn_phy_lp_set_bbmult(mac, 150); 11103} 11104 11105static void 11106bwn_phy_lp_calib(struct bwn_mac *mac) 11107{ 11108 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11109 struct bwn_softc *sc = mac->mac_sc; 11110 struct ifnet *ifp = sc->sc_ifp; 11111 struct ieee80211com *ic = ifp->if_l2com; 11112 const struct bwn_rxcompco *rc = NULL; 11113 struct bwn_txgain ogain; 11114 int i, omode, oafeovr, orf, obbmult; 11115 uint8_t mode, fc = 0; 11116 11117 if (plp->plp_chanfullcal != plp->plp_chan) { 11118 plp->plp_chanfullcal = plp->plp_chan; 11119 fc = 1; 11120 } 11121 11122 bwn_mac_suspend(mac); 11123 11124 /* BlueTooth Coexistance Override */ 11125 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11126 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11127 11128 if (mac->mac_phy.rev >= 2) 11129 bwn_phy_lp_digflt_save(mac); 11130 bwn_phy_lp_get_txpctlmode(mac); 11131 mode = plp->plp_txpctlmode; 11132 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11133 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11134 bwn_phy_lp_bugfix(mac); 11135 if (mac->mac_phy.rev >= 2 && fc == 1) { 11136 bwn_phy_lp_get_txpctlmode(mac); 11137 omode = plp->plp_txpctlmode; 11138 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11139 if (oafeovr) 11140 ogain = bwn_phy_lp_get_txgain(mac); 11141 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11142 obbmult = bwn_phy_lp_get_bbmult(mac); 11143 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11144 if (oafeovr) 11145 bwn_phy_lp_set_txgain(mac, &ogain); 11146 bwn_phy_lp_set_bbmult(mac, obbmult); 11147 bwn_phy_lp_set_txpctlmode(mac, omode); 11148 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11149 } 11150 bwn_phy_lp_set_txpctlmode(mac, mode); 11151 if (mac->mac_phy.rev >= 2) 11152 bwn_phy_lp_digflt_restore(mac); 11153 11154 /* do RX IQ Calculation; assumes that noise is true. */ 11155 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11156 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11157 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11158 rc = &bwn_rxcompco_5354[i]; 11159 } 11160 } else if (mac->mac_phy.rev >= 2) 11161 rc = &bwn_rxcompco_r2; 11162 else { 11163 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11164 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11165 rc = &bwn_rxcompco_r12[i]; 11166 } 11167 } 11168 if (rc == NULL) 11169 goto fail; 11170 11171 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11172 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11173 11174 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11175 11176 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11177 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11178 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11179 } else { 11180 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11181 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11182 } 11183 11184 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11185 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11186 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11187 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11188 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11189 bwn_phy_lp_set_deaf(mac, 0); 11190 /* XXX no checking return value? */ 11191 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11192 bwn_phy_lp_clear_deaf(mac, 0); 11193 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11194 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11195 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11196 11197 /* disable RX GAIN override. */ 11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11201 if (mac->mac_phy.rev >= 2) { 11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11203 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11205 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11206 } 11207 } else { 11208 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11209 } 11210 11211 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11212 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11213fail: 11214 bwn_mac_enable(mac); 11215} 11216 11217static void 11218bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11219{ 11220 11221 if (on) { 11222 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11223 return; 11224 } 11225 11226 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11227 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11228} 11229 11230static int 11231bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11232{ 11233 static const struct bwn_b206x_chan *bc = NULL; 11234 struct bwn_softc *sc = mac->mac_sc; 11235 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11236 tmp[6]; 11237 uint16_t old, scale, tmp16; 11238 int i, div; 11239 11240 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11241 if (bwn_b2063_chantable[i].bc_chan == chan) { 11242 bc = &bwn_b2063_chantable[i]; 11243 break; 11244 } 11245 } 11246 if (bc == NULL) 11247 return (EINVAL); 11248 11249 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11250 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11251 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11252 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11253 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11254 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11255 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11256 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11258 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11259 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11260 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11261 11262 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11263 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11264 11265 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11266 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11267 freqref = freqxtal * 3; 11268 div = (freqxtal <= 26000000 ? 1 : 2); 11269 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11270 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11271 999999) / 1000000) + 1; 11272 11273 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11274 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11275 0xfff8, timeout >> 2); 11276 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11277 0xff9f,timeout << 5); 11278 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11279 11280 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11281 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11282 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11283 11284 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11285 (timeoutref + 1)) - 1; 11286 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11287 0xf0, count >> 8); 11288 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11289 11290 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11291 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11292 while (tmp[1] >= freqref) { 11293 tmp[0]++; 11294 tmp[1] -= freqref; 11295 } 11296 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11297 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11298 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11299 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11300 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11301 11302 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11303 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11305 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11306 11307 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11308 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11309 11310 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11311 scale = 1; 11312 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11313 } else { 11314 scale = 0; 11315 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11316 } 11317 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11318 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11319 11320 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11321 (scale + 1); 11322 if (tmp[5] > 150) 11323 tmp[5] = 0; 11324 11325 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11326 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11327 11328 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11329 if (freqxtal > 26000000) 11330 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11331 else 11332 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11333 11334 if (val[0] == 45) 11335 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11336 else 11337 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11338 11339 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11340 DELAY(1); 11341 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11342 11343 /* VCO Calibration */ 11344 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11345 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11346 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11347 DELAY(1); 11348 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11349 DELAY(1); 11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11351 DELAY(1); 11352 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11353 DELAY(300); 11354 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11355 11356 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11357 return (0); 11358} 11359 11360static int 11361bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11362{ 11363 struct bwn_softc *sc = mac->mac_sc; 11364 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11365 const struct bwn_b206x_chan *bc = NULL; 11366 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11367 uint32_t tmp[9]; 11368 int i; 11369 11370 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11371 if (bwn_b2062_chantable[i].bc_chan == chan) { 11372 bc = &bwn_b2062_chantable[i]; 11373 break; 11374 } 11375 } 11376 11377 if (bc == NULL) 11378 return (EINVAL); 11379 11380 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11381 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11382 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11383 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11384 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11385 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11388 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11389 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11390 11391 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11392 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11393 bwn_phy_lp_b2062_reset_pllbias(mac); 11394 tmp[0] = freqxtal / 1000; 11395 tmp[1] = plp->plp_div * 1000; 11396 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11397 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11398 tmp[2] *= 2; 11399 tmp[3] = 48 * tmp[0]; 11400 tmp[5] = tmp[2] / tmp[3]; 11401 tmp[6] = tmp[2] % tmp[3]; 11402 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11403 tmp[4] = tmp[6] * 0x100; 11404 tmp[5] = tmp[4] / tmp[3]; 11405 tmp[6] = tmp[4] % tmp[3]; 11406 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11407 tmp[4] = tmp[6] * 0x100; 11408 tmp[5] = tmp[4] / tmp[3]; 11409 tmp[6] = tmp[4] % tmp[3]; 11410 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11411 tmp[4] = tmp[6] * 0x100; 11412 tmp[5] = tmp[4] / tmp[3]; 11413 tmp[6] = tmp[4] % tmp[3]; 11414 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11415 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11416 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11417 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11419 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11420 11421 bwn_phy_lp_b2062_vco_calib(mac); 11422 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11424 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11425 bwn_phy_lp_b2062_reset_pllbias(mac); 11426 bwn_phy_lp_b2062_vco_calib(mac); 11427 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11428 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11429 return (EIO); 11430 } 11431 } 11432 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11433 return (0); 11434} 11435 11436static void 11437bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11438{ 11439 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11440 uint16_t tmp = (channel == 14); 11441 11442 if (mac->mac_phy.rev < 2) { 11443 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11444 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11445 bwn_phy_lp_set_rccap(mac); 11446 return; 11447 } 11448 11449 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11450} 11451 11452static void 11453bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11454{ 11455 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11456 struct bwn_softc *sc = mac->mac_sc; 11457 struct ifnet *ifp = sc->sc_ifp; 11458 struct ieee80211com *ic = ifp->if_l2com; 11459 uint16_t iso, tmp[3]; 11460 11461 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11462 11463 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11464 iso = plp->plp_txisoband_m; 11465 else if (freq <= 5320) 11466 iso = plp->plp_txisoband_l; 11467 else if (freq <= 5700) 11468 iso = plp->plp_txisoband_m; 11469 else 11470 iso = plp->plp_txisoband_h; 11471 11472 tmp[0] = ((iso - 26) / 12) << 12; 11473 tmp[1] = tmp[0] + 0x1000; 11474 tmp[2] = tmp[0] + 0x2000; 11475 11476 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11477 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11478} 11479 11480static void 11481bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11482{ 11483 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11484 int i; 11485 static const uint16_t addr[] = { 11486 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11487 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11488 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11489 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11490 BWN_PHY_OFDM(0xcf), 11491 }; 11492 static const uint16_t val[] = { 11493 0xde5e, 0xe832, 0xe331, 0x4d26, 11494 0x0026, 0x1420, 0x0020, 0xfe08, 11495 0x0008, 11496 }; 11497 11498 for (i = 0; i < N(addr); i++) { 11499 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11500 BWN_PHY_WRITE(mac, addr[i], val[i]); 11501 } 11502} 11503 11504static void 11505bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11506{ 11507 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11508 struct bwn_softc *sc = mac->mac_sc; 11509 uint16_t ctl; 11510 11511 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11512 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11513 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11514 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11515 break; 11516 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11517 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11518 break; 11519 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11520 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11521 break; 11522 default: 11523 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11524 device_printf(sc->sc_dev, "unknown command mode\n"); 11525 break; 11526 } 11527} 11528 11529static void 11530bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11531{ 11532 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11533 uint16_t ctl; 11534 uint8_t old; 11535 11536 bwn_phy_lp_get_txpctlmode(mac); 11537 old = plp->plp_txpctlmode; 11538 if (old == mode) 11539 return; 11540 plp->plp_txpctlmode = mode; 11541 11542 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11543 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11544 plp->plp_tssiidx); 11545 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11546 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11547 11548 /* disable TX GAIN override */ 11549 if (mac->mac_phy.rev < 2) 11550 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11551 else { 11552 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11553 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11554 } 11555 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11556 11557 plp->plp_txpwridx = -1; 11558 } 11559 if (mac->mac_phy.rev >= 2) { 11560 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11561 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11562 else 11563 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11564 } 11565 11566 /* writes TX Power Control mode */ 11567 switch (plp->plp_txpctlmode) { 11568 case BWN_PHYLP_TXPCTL_OFF: 11569 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11570 break; 11571 case BWN_PHYLP_TXPCTL_ON_HW: 11572 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11573 break; 11574 case BWN_PHYLP_TXPCTL_ON_SW: 11575 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11576 break; 11577 default: 11578 ctl = 0; 11579 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11580 } 11581 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11582 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11583} 11584 11585static void 11586bwn_phy_lp_bugfix(struct bwn_mac *mac) 11587{ 11588 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11589 struct bwn_softc *sc = mac->mac_sc; 11590 const unsigned int size = 256; 11591 struct bwn_txgain tg; 11592 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11593 uint16_t tssinpt, tssiidx, value[2]; 11594 uint8_t mode; 11595 int8_t txpwridx; 11596 11597 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11598 M_NOWAIT | M_ZERO); 11599 if (tabs == NULL) { 11600 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11601 return; 11602 } 11603 11604 bwn_phy_lp_get_txpctlmode(mac); 11605 mode = plp->plp_txpctlmode; 11606 txpwridx = plp->plp_txpwridx; 11607 tssinpt = plp->plp_tssinpt; 11608 tssiidx = plp->plp_tssiidx; 11609 11610 bwn_tab_read_multi(mac, 11611 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11612 BWN_TAB_4(7, 0x140), size, tabs); 11613 11614 bwn_phy_lp_tblinit(mac); 11615 bwn_phy_lp_bbinit(mac); 11616 bwn_phy_lp_txpctl_init(mac); 11617 bwn_phy_lp_rf_onoff(mac, 1); 11618 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11619 11620 bwn_tab_write_multi(mac, 11621 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11622 BWN_TAB_4(7, 0x140), size, tabs); 11623 11624 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11625 plp->plp_tssinpt = tssinpt; 11626 plp->plp_tssiidx = tssiidx; 11627 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11628 if (txpwridx != -1) { 11629 /* set TX power by index */ 11630 plp->plp_txpwridx = txpwridx; 11631 bwn_phy_lp_get_txpctlmode(mac); 11632 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11633 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11634 if (mac->mac_phy.rev >= 2) { 11635 rxcomp = bwn_tab_read(mac, 11636 BWN_TAB_4(7, txpwridx + 320)); 11637 txgain = bwn_tab_read(mac, 11638 BWN_TAB_4(7, txpwridx + 192)); 11639 tg.tg_pad = (txgain >> 16) & 0xff; 11640 tg.tg_gm = txgain & 0xff; 11641 tg.tg_pga = (txgain >> 8) & 0xff; 11642 tg.tg_dac = (rxcomp >> 28) & 0xff; 11643 bwn_phy_lp_set_txgain(mac, &tg); 11644 } else { 11645 rxcomp = bwn_tab_read(mac, 11646 BWN_TAB_4(10, txpwridx + 320)); 11647 txgain = bwn_tab_read(mac, 11648 BWN_TAB_4(10, txpwridx + 192)); 11649 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11650 0xf800, (txgain >> 4) & 0x7fff); 11651 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11652 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11653 } 11654 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11655 11656 /* set TX IQCC */ 11657 value[0] = (rxcomp >> 10) & 0x3ff; 11658 value[1] = rxcomp & 0x3ff; 11659 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11660 11661 coeff = bwn_tab_read(mac, 11662 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11663 BWN_TAB_4(10, txpwridx + 448)); 11664 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11665 if (mac->mac_phy.rev >= 2) { 11666 rfpwr = bwn_tab_read(mac, 11667 BWN_TAB_4(7, txpwridx + 576)); 11668 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11669 rfpwr & 0xffff); 11670 } 11671 bwn_phy_lp_set_txgain_override(mac); 11672 } 11673 if (plp->plp_rccap) 11674 bwn_phy_lp_set_rccap(mac); 11675 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11676 bwn_phy_lp_set_txpctlmode(mac, mode); 11677 free(tabs, M_DEVBUF); 11678} 11679 11680static void 11681bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11682{ 11683 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11684 int i; 11685 static const uint16_t addr[] = { 11686 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11687 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11688 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11689 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11690 BWN_PHY_OFDM(0xcf), 11691 }; 11692 11693 for (i = 0; i < N(addr); i++) 11694 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11695} 11696 11697static void 11698bwn_phy_lp_tblinit(struct bwn_mac *mac) 11699{ 11700 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11701 11702 if (mac->mac_phy.rev < 2) { 11703 bwn_phy_lp_tblinit_r01(mac); 11704 bwn_phy_lp_tblinit_txgain(mac); 11705 bwn_phy_lp_set_gaintbl(mac, freq); 11706 return; 11707 } 11708 11709 bwn_phy_lp_tblinit_r2(mac); 11710 bwn_phy_lp_tblinit_txgain(mac); 11711} 11712 11713struct bwn_wpair { 11714 uint16_t reg; 11715 uint16_t value; 11716}; 11717 11718struct bwn_smpair { 11719 uint16_t offset; 11720 uint16_t mask; 11721 uint16_t set; 11722}; 11723 11724static void 11725bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11726{ 11727 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11728 struct bwn_softc *sc = mac->mac_sc; 11729 struct ifnet *ifp = sc->sc_ifp; 11730 struct ieee80211com *ic = ifp->if_l2com; 11731 static const struct bwn_wpair v1[] = { 11732 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11733 { BWN_PHY_AFE_CTL, 0x8800 }, 11734 { BWN_PHY_AFE_CTL_OVR, 0 }, 11735 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11736 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11737 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11738 { BWN_PHY_OFDM(0xf9), 0 }, 11739 { BWN_PHY_TR_LOOKUP_1, 0 } 11740 }; 11741 static const struct bwn_smpair v2[] = { 11742 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11743 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11744 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11745 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11746 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11747 }; 11748 static const struct bwn_smpair v3[] = { 11749 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11750 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11751 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11752 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11753 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11754 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11755 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11756 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11757 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11758 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11759 11760 }; 11761 int i; 11762 11763 for (i = 0; i < N(v1); i++) 11764 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11765 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11766 for (i = 0; i < N(v2); i++) 11767 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11768 11769 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11770 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11771 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11772 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11773 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11774 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11775 } else { 11776 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11777 } 11778 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11779 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11780 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11781 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11782 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11783 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11784 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11785 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11786 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11788 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11789 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11790 (siba_get_chiprev(sc->sc_dev) == 0)) { 11791 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11792 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11793 } else { 11794 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11795 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11796 } 11797 for (i = 0; i < N(v3); i++) 11798 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11799 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11800 (siba_get_chiprev(sc->sc_dev) == 0)) { 11801 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11802 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11803 } 11804 11805 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11806 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11807 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11808 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11809 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11810 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11811 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11812 } else 11813 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11814 11815 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11816 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11817 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11818 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11819 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11820 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11821 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11822 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11823 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11824 11825 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11826 (siba_get_chiprev(sc->sc_dev) == 0)) { 11827 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11828 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11829 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11830 } 11831 11832 bwn_phy_lp_digflt_save(mac); 11833} 11834 11835static void 11836bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11837{ 11838 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11839 struct bwn_softc *sc = mac->mac_sc; 11840 struct ifnet *ifp = sc->sc_ifp; 11841 struct ieee80211com *ic = ifp->if_l2com; 11842 static const struct bwn_smpair v1[] = { 11843 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11844 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11845 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11846 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11847 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11848 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11849 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11850 }; 11851 static const struct bwn_smpair v2[] = { 11852 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11853 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11854 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11855 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11856 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11857 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11858 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11859 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11860 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11861 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11862 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11863 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11864 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11865 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11866 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11867 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11868 }; 11869 static const struct bwn_smpair v3[] = { 11870 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11871 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11872 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11873 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11874 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11875 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11876 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11877 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11878 }; 11879 static const struct bwn_smpair v4[] = { 11880 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11881 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11882 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11883 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11884 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11885 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11886 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11887 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11888 }; 11889 static const struct bwn_smpair v5[] = { 11890 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11891 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11892 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11893 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11894 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11895 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11896 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11897 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11898 }; 11899 int i; 11900 uint16_t tmp, tmp2; 11901 11902 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11903 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11904 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11905 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11906 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11907 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11908 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11909 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11910 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11911 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11912 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11913 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11914 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11915 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11916 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11917 for (i = 0; i < N(v1); i++) 11918 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11919 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11920 0xff00, plp->plp_rxpwroffset); 11921 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11922 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11923 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11924 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11925 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11926 if (mac->mac_phy.rev == 0) 11927 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11928 0xffcf, 0x0010); 11929 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11930 } else { 11931 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11932 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11933 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11934 } 11935 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11936 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11937 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11938 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11939 else 11940 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11941 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11942 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11943 0xfff9, (plp->plp_bxarch << 1)); 11944 if (mac->mac_phy.rev == 1 && 11945 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11946 for (i = 0; i < N(v2); i++) 11947 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11948 v2[i].set); 11949 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11950 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11951 ((mac->mac_phy.rev == 0) && 11952 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11953 for (i = 0; i < N(v3); i++) 11954 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11955 v3[i].set); 11956 } else if (mac->mac_phy.rev == 1 || 11957 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11958 for (i = 0; i < N(v4); i++) 11959 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11960 v4[i].set); 11961 } else { 11962 for (i = 0; i < N(v5); i++) 11963 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11964 v5[i].set); 11965 } 11966 if (mac->mac_phy.rev == 1 && 11967 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11968 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11969 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11970 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11971 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11972 } 11973 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11974 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11975 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11976 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11977 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11978 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11979 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11980 } 11981 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11982 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11983 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11984 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11985 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11986 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11987 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11988 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11989 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11990 } else { 11991 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11992 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11993 } 11994 if (mac->mac_phy.rev == 1) { 11995 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11996 tmp2 = (tmp & 0x03e0) >> 5; 11997 tmp2 |= tmp2 << 5; 11998 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11999 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12000 tmp2 = (tmp & 0x1f00) >> 8; 12001 tmp2 |= tmp2 << 5; 12002 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12003 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12004 tmp2 = tmp & 0x00ff; 12005 tmp2 |= tmp << 8; 12006 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12007 } 12008} 12009 12010struct bwn_b2062_freq { 12011 uint16_t freq; 12012 uint8_t value[6]; 12013}; 12014 12015static void 12016bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12017{ 12018#define CALC_CTL7(freq, div) \ 12019 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12020#define CALC_CTL18(freq, div) \ 12021 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12022#define CALC_CTL19(freq, div) \ 12023 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12024 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12025 struct bwn_softc *sc = mac->mac_sc; 12026 struct ifnet *ifp = sc->sc_ifp; 12027 struct ieee80211com *ic = ifp->if_l2com; 12028 static const struct bwn_b2062_freq freqdata_tab[] = { 12029 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12030 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12031 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12032 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12033 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12034 { 19200, { 1, 1, 1, 1, 14, 9 } } 12035 }; 12036 static const struct bwn_wpair v1[] = { 12037 { BWN_B2062_N_TXCTL3, 0 }, 12038 { BWN_B2062_N_TXCTL4, 0 }, 12039 { BWN_B2062_N_TXCTL5, 0 }, 12040 { BWN_B2062_N_TXCTL6, 0 }, 12041 { BWN_B2062_N_PDNCTL0, 0x40 }, 12042 { BWN_B2062_N_PDNCTL0, 0 }, 12043 { BWN_B2062_N_CALIB_TS, 0x10 }, 12044 { BWN_B2062_N_CALIB_TS, 0 } 12045 }; 12046 const struct bwn_b2062_freq *f = NULL; 12047 uint32_t xtalfreq, ref; 12048 unsigned int i; 12049 12050 bwn_phy_lp_b2062_tblinit(mac); 12051 12052 for (i = 0; i < N(v1); i++) 12053 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12054 if (mac->mac_phy.rev > 0) 12055 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12056 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12057 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12058 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12059 else 12060 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12061 12062 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12063 ("%s:%d: fail", __func__, __LINE__)); 12064 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12065 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12066 12067 if (xtalfreq <= 30000000) { 12068 plp->plp_div = 1; 12069 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12070 } else { 12071 plp->plp_div = 2; 12072 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12073 } 12074 12075 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12076 CALC_CTL7(xtalfreq, plp->plp_div)); 12077 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12078 CALC_CTL18(xtalfreq, plp->plp_div)); 12079 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12080 CALC_CTL19(xtalfreq, plp->plp_div)); 12081 12082 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12083 ref &= 0xffff; 12084 for (i = 0; i < N(freqdata_tab); i++) { 12085 if (ref < freqdata_tab[i].freq) { 12086 f = &freqdata_tab[i]; 12087 break; 12088 } 12089 } 12090 if (f == NULL) 12091 f = &freqdata_tab[N(freqdata_tab) - 1]; 12092 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12093 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12094 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12095 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12096 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12097 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12098#undef CALC_CTL7 12099#undef CALC_CTL18 12100#undef CALC_CTL19 12101} 12102 12103static void 12104bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12105{ 12106 12107 bwn_phy_lp_b2063_tblinit(mac); 12108 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12109 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12110 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12111 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12112 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12113 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12114 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12115 if (mac->mac_phy.rev == 2) { 12116 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12117 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12118 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12119 } else { 12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12122 } 12123} 12124 12125static void 12126bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12127{ 12128 struct bwn_softc *sc = mac->mac_sc; 12129 static const struct bwn_wpair v1[] = { 12130 { BWN_B2063_RX_BB_SP8, 0x0 }, 12131 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12132 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12133 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12134 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12135 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12136 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12137 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12138 }; 12139 static const struct bwn_wpair v2[] = { 12140 { BWN_B2063_TX_BB_SP3, 0x0 }, 12141 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12142 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12143 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12144 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12145 }; 12146 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12147 int i; 12148 uint8_t tmp; 12149 12150 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12151 12152 for (i = 0; i < 2; i++) 12153 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12154 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12155 for (i = 2; i < N(v1); i++) 12156 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12157 for (i = 0; i < 10000; i++) { 12158 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12159 break; 12160 DELAY(1000); 12161 } 12162 12163 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12164 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12165 12166 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12167 12168 for (i = 0; i < N(v2); i++) 12169 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12170 if (freqxtal == 24000000) { 12171 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12172 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12173 } else { 12174 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12175 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12176 } 12177 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12178 for (i = 0; i < 10000; i++) { 12179 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12180 break; 12181 DELAY(1000); 12182 } 12183 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12184 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12185 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12186} 12187 12188static void 12189bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12190{ 12191 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12192 struct bwn_softc *sc = mac->mac_sc; 12193 struct bwn_phy_lp_iq_est ie; 12194 struct bwn_txgain tx_gains; 12195 static const uint32_t pwrtbl[21] = { 12196 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12197 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12198 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12199 0x0004c, 0x0002c, 0x0001a, 12200 }; 12201 uint32_t npwr, ipwr, sqpwr, tmp; 12202 int loopback, i, j, sum, error; 12203 uint16_t save[7]; 12204 uint8_t txo, bbmult, txpctlmode; 12205 12206 error = bwn_phy_lp_switch_channel(mac, 7); 12207 if (error) 12208 device_printf(sc->sc_dev, 12209 "failed to change channel to 7 (%d)\n", error); 12210 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12211 bbmult = bwn_phy_lp_get_bbmult(mac); 12212 if (txo) 12213 tx_gains = bwn_phy_lp_get_txgain(mac); 12214 12215 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12216 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12217 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12218 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12219 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12220 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12221 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12222 12223 bwn_phy_lp_get_txpctlmode(mac); 12224 txpctlmode = plp->plp_txpctlmode; 12225 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12226 12227 /* disable CRS */ 12228 bwn_phy_lp_set_deaf(mac, 1); 12229 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12230 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12231 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12232 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12233 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12234 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12236 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12238 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12240 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12241 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12244 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12245 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12246 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12247 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12249 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12250 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12251 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12252 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12253 12254 loopback = bwn_phy_lp_loopback(mac); 12255 if (loopback == -1) 12256 goto done; 12257 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12258 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12259 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12260 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12261 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12262 12263 tmp = 0; 12264 memset(&ie, 0, sizeof(ie)); 12265 for (i = 128; i <= 159; i++) { 12266 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12267 sum = 0; 12268 for (j = 5; j <= 25; j++) { 12269 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12270 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12271 goto done; 12272 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12273 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12274 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12275 12); 12276 sum += ((ipwr - npwr) * (ipwr - npwr)); 12277 if ((i == 128) || (sum < tmp)) { 12278 plp->plp_rccap = i; 12279 tmp = sum; 12280 } 12281 } 12282 } 12283 bwn_phy_lp_ddfs_turnoff(mac); 12284done: 12285 /* restore CRS */ 12286 bwn_phy_lp_clear_deaf(mac, 1); 12287 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12288 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12289 12290 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12291 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12292 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12293 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12294 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12297 12298 bwn_phy_lp_set_bbmult(mac, bbmult); 12299 if (txo) 12300 bwn_phy_lp_set_txgain(mac, &tx_gains); 12301 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12302 if (plp->plp_rccap) 12303 bwn_phy_lp_set_rccap(mac); 12304} 12305 12306static void 12307bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12308{ 12309 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12310 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12311 12312 if (mac->mac_phy.rev == 1) 12313 rc_cap = MIN(rc_cap + 5, 15); 12314 12315 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12316 MAX(plp->plp_rccap - 4, 0x80)); 12317 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12318 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12319 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12320} 12321 12322static uint32_t 12323bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12324{ 12325 uint32_t i, q, r; 12326 12327 if (div == 0) 12328 return (0); 12329 12330 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12331 q <<= 1; 12332 if (r << 1 >= div) { 12333 q++; 12334 r = (r << 1) - div; 12335 } 12336 } 12337 if (r << 1 >= div) 12338 q++; 12339 return (q); 12340} 12341 12342static void 12343bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12344{ 12345 struct bwn_softc *sc = mac->mac_sc; 12346 12347 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12348 DELAY(20); 12349 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12350 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12351 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12352 } else { 12353 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12354 } 12355 DELAY(5); 12356} 12357 12358static void 12359bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12360{ 12361 12362 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12363 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12364 DELAY(200); 12365} 12366 12367static void 12368bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12369{ 12370#define FLAG_A 0x01 12371#define FLAG_G 0x02 12372 struct bwn_softc *sc = mac->mac_sc; 12373 struct ifnet *ifp = sc->sc_ifp; 12374 struct ieee80211com *ic = ifp->if_l2com; 12375 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12376 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12377 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12378 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12379 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12380 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12381 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12382 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12383 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12384 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12385 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12386 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12387 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12389 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12391 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12423 }; 12424 const struct bwn_b206x_rfinit_entry *br; 12425 unsigned int i; 12426 12427 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12428 br = &bwn_b2062_init_tab[i]; 12429 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12430 if (br->br_flags & FLAG_G) 12431 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12432 } else { 12433 if (br->br_flags & FLAG_A) 12434 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12435 } 12436 } 12437#undef FLAG_A 12438#undef FLAG_B 12439} 12440 12441static void 12442bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12443{ 12444#define FLAG_A 0x01 12445#define FLAG_G 0x02 12446 struct bwn_softc *sc = mac->mac_sc; 12447 struct ifnet *ifp = sc->sc_ifp; 12448 struct ieee80211com *ic = ifp->if_l2com; 12449 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12450 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12451 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12452 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12453 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12454 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12455 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12456 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12457 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12462 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12463 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12464 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12465 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12466 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12467 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12468 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12469 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12470 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12471 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12472 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12473 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12474 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12475 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12483 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12487 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12491 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12492 }; 12493 const struct bwn_b206x_rfinit_entry *br; 12494 unsigned int i; 12495 12496 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12497 br = &bwn_b2063_init_tab[i]; 12498 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12499 if (br->br_flags & FLAG_G) 12500 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12501 } else { 12502 if (br->br_flags & FLAG_A) 12503 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12504 } 12505 } 12506#undef FLAG_A 12507#undef FLAG_B 12508} 12509 12510static void 12511bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12512 int count, void *_data) 12513{ 12514 unsigned int i; 12515 uint32_t offset, type; 12516 uint8_t *data = _data; 12517 12518 type = BWN_TAB_GETTYPE(typenoffset); 12519 offset = BWN_TAB_GETOFFSET(typenoffset); 12520 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12521 12522 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12523 12524 for (i = 0; i < count; i++) { 12525 switch (type) { 12526 case BWN_TAB_8BIT: 12527 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12528 data++; 12529 break; 12530 case BWN_TAB_16BIT: 12531 *((uint16_t *)data) = BWN_PHY_READ(mac, 12532 BWN_PHY_TABLEDATALO); 12533 data += 2; 12534 break; 12535 case BWN_TAB_32BIT: 12536 *((uint32_t *)data) = BWN_PHY_READ(mac, 12537 BWN_PHY_TABLEDATAHI); 12538 *((uint32_t *)data) <<= 16; 12539 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12540 BWN_PHY_TABLEDATALO); 12541 data += 4; 12542 break; 12543 default: 12544 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12545 } 12546 } 12547} 12548 12549static void 12550bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12551 int count, const void *_data) 12552{ 12553 uint32_t offset, type, value; 12554 const uint8_t *data = _data; 12555 unsigned int i; 12556 12557 type = BWN_TAB_GETTYPE(typenoffset); 12558 offset = BWN_TAB_GETOFFSET(typenoffset); 12559 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12560 12561 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12562 12563 for (i = 0; i < count; i++) { 12564 switch (type) { 12565 case BWN_TAB_8BIT: 12566 value = *data; 12567 data++; 12568 KASSERT(!(value & ~0xff), 12569 ("%s:%d: fail", __func__, __LINE__)); 12570 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12571 break; 12572 case BWN_TAB_16BIT: 12573 value = *((const uint16_t *)data); 12574 data += 2; 12575 KASSERT(!(value & ~0xffff), 12576 ("%s:%d: fail", __func__, __LINE__)); 12577 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12578 break; 12579 case BWN_TAB_32BIT: 12580 value = *((const uint32_t *)data); 12581 data += 4; 12582 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12583 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12584 break; 12585 default: 12586 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12587 } 12588 } 12589} 12590 12591static struct bwn_txgain 12592bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12593{ 12594 struct bwn_txgain tg; 12595 uint16_t tmp; 12596 12597 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12598 if (mac->mac_phy.rev < 2) { 12599 tmp = BWN_PHY_READ(mac, 12600 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12601 tg.tg_gm = tmp & 0x0007; 12602 tg.tg_pga = (tmp & 0x0078) >> 3; 12603 tg.tg_pad = (tmp & 0x780) >> 7; 12604 return (tg); 12605 } 12606 12607 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12608 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12609 tg.tg_gm = tmp & 0xff; 12610 tg.tg_pga = (tmp >> 8) & 0xff; 12611 return (tg); 12612} 12613 12614static uint8_t 12615bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12616{ 12617 12618 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12619} 12620 12621static void 12622bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12623{ 12624 uint16_t pa; 12625 12626 if (mac->mac_phy.rev < 2) { 12627 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12628 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12629 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12630 bwn_phy_lp_set_txgain_override(mac); 12631 return; 12632 } 12633 12634 pa = bwn_phy_lp_get_pa_gain(mac); 12635 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12636 (tg->tg_pga << 8) | tg->tg_gm); 12637 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12638 tg->tg_pad | (pa << 6)); 12639 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12640 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12641 tg->tg_pad | (pa << 8)); 12642 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12643 bwn_phy_lp_set_txgain_override(mac); 12644} 12645 12646static void 12647bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12648{ 12649 12650 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12651} 12652 12653static void 12654bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12655{ 12656 uint16_t trsw = (tx << 1) | rx; 12657 12658 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12659 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12660} 12661 12662static void 12663bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12664{ 12665 struct bwn_softc *sc = mac->mac_sc; 12666 struct ifnet *ifp = sc->sc_ifp; 12667 struct ieee80211com *ic = ifp->if_l2com; 12668 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12669 12670 if (mac->mac_phy.rev < 2) { 12671 trsw = gain & 0x1; 12672 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12673 ext_lna = (gain & 2) >> 1; 12674 12675 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12676 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12677 0xfbff, ext_lna << 10); 12678 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12679 0xf7ff, ext_lna << 11); 12680 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12681 } else { 12682 low_gain = gain & 0xffff; 12683 high_gain = (gain >> 16) & 0xf; 12684 ext_lna = (gain >> 21) & 0x1; 12685 trsw = ~(gain >> 20) & 0x1; 12686 12687 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12688 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12689 0xfdff, ext_lna << 9); 12690 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12691 0xfbff, ext_lna << 10); 12692 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12693 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12694 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12695 tmp = (gain >> 2) & 0x3; 12696 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12697 0xe7ff, tmp<<11); 12698 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12699 tmp << 3); 12700 } 12701 } 12702 12703 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12704 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12705 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12706 if (mac->mac_phy.rev >= 2) { 12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12708 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12710 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12711 } 12712 return; 12713 } 12714 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12715} 12716 12717static void 12718bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12719{ 12720 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12721 12722 if (user) 12723 plp->plp_crsusr_off = 1; 12724 else 12725 plp->plp_crssys_off = 1; 12726 12727 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12728} 12729 12730static void 12731bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12732{ 12733 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12734 struct bwn_softc *sc = mac->mac_sc; 12735 struct ifnet *ifp = sc->sc_ifp; 12736 struct ieee80211com *ic = ifp->if_l2com; 12737 12738 if (user) 12739 plp->plp_crsusr_off = 0; 12740 else 12741 plp->plp_crssys_off = 0; 12742 12743 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12744 return; 12745 12746 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12747 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12748 else 12749 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12750} 12751 12752static unsigned int 12753bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12754{ 12755 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12756 static uint8_t sqrt_table[256] = { 12757 10, 14, 17, 20, 22, 24, 26, 28, 12758 30, 31, 33, 34, 36, 37, 38, 40, 12759 41, 42, 43, 44, 45, 46, 47, 48, 12760 50, 50, 51, 52, 53, 54, 55, 56, 12761 57, 58, 59, 60, 60, 61, 62, 63, 12762 64, 64, 65, 66, 67, 67, 68, 69, 12763 70, 70, 71, 72, 72, 73, 74, 74, 12764 75, 76, 76, 77, 78, 78, 79, 80, 12765 80, 81, 81, 82, 83, 83, 84, 84, 12766 85, 86, 86, 87, 87, 88, 88, 89, 12767 90, 90, 91, 91, 92, 92, 93, 93, 12768 94, 94, 95, 95, 96, 96, 97, 97, 12769 98, 98, 99, 100, 100, 100, 101, 101, 12770 102, 102, 103, 103, 104, 104, 105, 105, 12771 106, 106, 107, 107, 108, 108, 109, 109, 12772 110, 110, 110, 111, 111, 112, 112, 113, 12773 113, 114, 114, 114, 115, 115, 116, 116, 12774 117, 117, 117, 118, 118, 119, 119, 120, 12775 120, 120, 121, 121, 122, 122, 122, 123, 12776 123, 124, 124, 124, 125, 125, 126, 126, 12777 126, 127, 127, 128, 128, 128, 129, 129, 12778 130, 130, 130, 131, 131, 131, 132, 132, 12779 133, 133, 133, 134, 134, 134, 135, 135, 12780 136, 136, 136, 137, 137, 137, 138, 138, 12781 138, 139, 139, 140, 140, 140, 141, 141, 12782 141, 142, 142, 142, 143, 143, 143, 144, 12783 144, 144, 145, 145, 145, 146, 146, 146, 12784 147, 147, 147, 148, 148, 148, 149, 149, 12785 150, 150, 150, 150, 151, 151, 151, 152, 12786 152, 152, 153, 153, 153, 154, 154, 154, 12787 155, 155, 155, 156, 156, 156, 157, 157, 12788 157, 158, 158, 158, 159, 159, 159, 160 12789 }; 12790 12791 if (x == 0) 12792 return (0); 12793 if (x >= 256) { 12794 unsigned int tmp; 12795 12796 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12797 /* do nothing */ ; 12798 return (tmp); 12799 } 12800 return (sqrt_table[x - 1] / 10); 12801} 12802 12803static int 12804bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12805{ 12806#define CALC_COEFF(_v, _x, _y, _z) do { \ 12807 int _t; \ 12808 _t = _x - 20; \ 12809 if (_t >= 0) { \ 12810 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12811 } else { \ 12812 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12813 } \ 12814} while (0) 12815#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12816 int _t; \ 12817 _t = _x - 11; \ 12818 if (_t >= 0) \ 12819 _v = (_y << (31 - _x)) / (_z >> _t); \ 12820 else \ 12821 _v = (_y << (31 - _x)) / (_z << -_t); \ 12822} while (0) 12823 struct bwn_phy_lp_iq_est ie; 12824 uint16_t v0, v1; 12825 int tmp[2], ret; 12826 12827 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12828 v0 = v1 >> 8; 12829 v1 |= 0xff; 12830 12831 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12832 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12833 12834 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12835 if (ret == 0) 12836 goto done; 12837 12838 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12839 ret = 0; 12840 goto done; 12841 } 12842 12843 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12844 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12845 12846 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12847 v0 = tmp[0] >> 3; 12848 v1 = tmp[1] >> 4; 12849done: 12850 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12851 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12852 return ret; 12853#undef CALC_COEFF 12854#undef CALC_COEFF2 12855} 12856 12857static void 12858bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12859{ 12860 static const uint16_t noisescale[] = { 12861 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12862 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12863 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12864 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12865 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12866 }; 12867 static const uint16_t crsgainnft[] = { 12868 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12869 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12870 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12871 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12872 0x013d, 12873 }; 12874 static const uint16_t filterctl[] = { 12875 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12876 0xff53, 0x0127, 12877 }; 12878 static const uint32_t psctl[] = { 12879 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12880 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12881 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12882 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12883 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12884 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12885 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12886 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12887 }; 12888 static const uint16_t ofdmcckgain_r0[] = { 12889 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12890 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12891 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12892 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12893 0x755d, 12894 }; 12895 static const uint16_t ofdmcckgain_r1[] = { 12896 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12897 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12898 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12899 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12900 0x755d, 12901 }; 12902 static const uint16_t gaindelta[] = { 12903 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12904 0x0000, 12905 }; 12906 static const uint32_t txpwrctl[] = { 12907 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12908 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12909 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12910 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12911 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12912 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12913 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12914 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12915 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12916 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12917 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12918 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12919 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12920 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12921 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12922 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12923 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12946 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12947 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12948 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12949 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12950 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12951 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12952 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12953 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12954 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12955 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12956 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12957 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12958 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12959 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12960 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12961 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12962 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12963 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12964 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12965 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12966 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12967 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12968 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12969 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12970 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12971 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12972 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12973 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12974 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12996 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12997 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12998 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12999 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13000 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13001 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13002 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13003 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13004 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13005 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13006 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13007 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13008 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13009 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13010 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13011 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13012 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13013 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13014 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13015 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13016 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13017 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13018 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13019 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13020 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13021 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13022 0x00000702, 13023 }; 13024 13025 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13026 13027 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13028 bwn_tab_sigsq_tbl); 13029 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13030 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13031 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13032 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13033 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13034 bwn_tab_pllfrac_tbl); 13035 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13036 bwn_tabl_iqlocal_tbl); 13037 if (mac->mac_phy.rev == 0) { 13038 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13039 ofdmcckgain_r0); 13040 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13041 ofdmcckgain_r0); 13042 } else { 13043 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13044 ofdmcckgain_r1); 13045 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13046 ofdmcckgain_r1); 13047 } 13048 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13049 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13050} 13051 13052static void 13053bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13054{ 13055 struct bwn_softc *sc = mac->mac_sc; 13056 int i; 13057 static const uint16_t noisescale[] = { 13058 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13059 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13060 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13061 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13065 }; 13066 static const uint32_t filterctl[] = { 13067 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13068 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13069 }; 13070 static const uint32_t psctl[] = { 13071 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13072 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13073 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13074 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13075 }; 13076 static const uint32_t gainidx[] = { 13077 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13078 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13079 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13080 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13081 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13082 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13083 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13084 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13085 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13086 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13087 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13088 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13089 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13090 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13091 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13092 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13093 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13094 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13095 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13096 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13097 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13098 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13099 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13100 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13101 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13102 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13103 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13104 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13105 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13106 0x0000001a, 0x64ca55ad, 0x0000001a 13107 }; 13108 static const uint16_t auxgainidx[] = { 13109 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13110 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13111 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13112 0x0004, 0x0016 13113 }; 13114 static const uint16_t swctl[] = { 13115 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13116 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13117 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13118 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13119 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13121 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13122 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13123 }; 13124 static const uint8_t hf[] = { 13125 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13126 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13127 }; 13128 static const uint32_t gainval[] = { 13129 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13130 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13131 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13132 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13133 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13134 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13135 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13136 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13137 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13138 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13139 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13140 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13142 0x000000f1, 0x00000000, 0x00000000 13143 }; 13144 static const uint16_t gain[] = { 13145 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13146 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13147 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13148 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13149 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13150 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13151 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13152 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13153 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13154 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13157 }; 13158 static const uint32_t papdeps[] = { 13159 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13160 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13161 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13162 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13163 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13164 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13165 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13166 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13167 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13168 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13169 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13170 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13171 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13172 }; 13173 static const uint32_t papdmult[] = { 13174 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13175 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13176 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13177 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13178 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13179 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13180 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13181 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13182 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13183 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13184 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13185 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13186 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13187 }; 13188 static const uint32_t gainidx_a0[] = { 13189 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13190 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13191 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13192 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13193 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13194 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13195 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13196 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13197 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13198 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13199 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13200 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13201 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13202 }; 13203 static const uint16_t auxgainidx_a0[] = { 13204 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13205 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13206 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13207 0x0002, 0x0014 13208 }; 13209 static const uint32_t gainval_a0[] = { 13210 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13211 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13212 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13213 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13214 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13215 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13216 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13217 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13218 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13219 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13220 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13221 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13223 0x000000f7, 0x00000000, 0x00000000 13224 }; 13225 static const uint16_t gain_a0[] = { 13226 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13227 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13228 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13229 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13230 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13231 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13232 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13233 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13234 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13235 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13238 }; 13239 13240 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13241 13242 for (i = 0; i < 704; i++) 13243 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13244 13245 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13246 bwn_tab_sigsq_tbl); 13247 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13248 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13249 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13250 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13251 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13252 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13253 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13254 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13255 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13256 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13257 bwn_tab_pllfrac_tbl); 13258 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13259 bwn_tabl_iqlocal_tbl); 13260 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13261 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13262 13263 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13264 (siba_get_chiprev(sc->sc_dev) == 0)) { 13265 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13266 gainidx_a0); 13267 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13268 auxgainidx_a0); 13269 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13270 gainval_a0); 13271 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13272 } 13273} 13274 13275static void 13276bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13277{ 13278 struct bwn_softc *sc = mac->mac_sc; 13279 struct ifnet *ifp = sc->sc_ifp; 13280 struct ieee80211com *ic = ifp->if_l2com; 13281 static struct bwn_txgain_entry txgain_r2[] = { 13282 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13283 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13284 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13285 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13286 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13287 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13288 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13289 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13290 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13291 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13292 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13293 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13294 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13295 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13296 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13297 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13298 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13299 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13300 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13301 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13302 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13303 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13304 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13305 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13306 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13307 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13308 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13309 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13310 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13311 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13312 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13313 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13314 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13315 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13316 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13317 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13318 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13319 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13320 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13321 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13322 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13323 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13324 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13325 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13326 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13327 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13328 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13329 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13330 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13331 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13332 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13333 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13334 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13335 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13336 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13337 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13338 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13339 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13340 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13341 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13342 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13343 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13344 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13345 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13346 }; 13347 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13348 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13349 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13350 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13351 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13352 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13353 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13354 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13355 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13356 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13357 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13358 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13359 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13360 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13361 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13362 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13363 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13364 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13365 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13366 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13367 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13368 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13369 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13370 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13371 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13372 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13373 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13374 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13375 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13376 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13377 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13378 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13379 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13380 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13381 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13382 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13383 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13384 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13385 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13386 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13387 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13388 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13389 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13390 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13391 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13392 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13393 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13394 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13395 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13396 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13397 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13398 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13399 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13400 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13401 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13402 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13403 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13404 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13405 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13406 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13407 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13408 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13409 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13410 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13411 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13412 }; 13413 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13414 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13415 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13416 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13417 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13418 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13419 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13420 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13421 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13422 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13423 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13424 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13425 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13426 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13427 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13428 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13429 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13430 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13431 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13432 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13433 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13434 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13435 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13436 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13437 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13438 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13439 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13440 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13441 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13442 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13443 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13444 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13445 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13446 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13447 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13448 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13449 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13450 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13451 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13452 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13453 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13454 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13455 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13456 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13457 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13458 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13459 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13460 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13461 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13462 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13463 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13464 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13465 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13466 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13467 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13468 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13469 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13470 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13471 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13472 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13473 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13474 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13475 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13476 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13477 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13478 }; 13479 static struct bwn_txgain_entry txgain_r0[] = { 13480 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13481 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13482 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13483 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13484 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13485 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13486 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13487 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13488 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13489 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13490 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13491 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13492 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13493 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13494 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13495 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13496 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13497 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13498 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13499 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13500 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13501 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13502 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13503 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13504 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13505 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13506 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13507 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13508 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13509 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13510 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13511 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13512 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13513 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13514 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13515 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13516 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13517 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13518 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13519 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13520 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13521 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13522 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13523 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13524 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13525 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13526 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13527 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13528 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13529 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13530 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13531 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13532 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13533 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13534 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13535 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13536 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13537 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13538 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13539 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13540 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13541 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13542 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13543 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13544 }; 13545 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13546 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13547 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13548 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13549 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13550 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13551 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13552 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13553 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13554 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13555 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13556 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13557 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13558 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13559 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13560 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13561 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13562 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13563 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13564 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13565 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13566 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13567 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13568 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13569 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13570 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13571 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13572 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13573 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13574 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13575 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13576 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13577 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13578 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13579 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13580 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13581 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13582 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13583 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13584 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13585 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13586 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13587 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13588 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13589 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13590 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13591 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13592 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13593 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13594 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13595 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13596 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13597 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13598 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13599 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13600 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13601 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13602 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13603 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13604 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13605 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13606 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13607 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13608 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13609 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13610 }; 13611 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13612 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13613 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13614 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13615 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13616 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13617 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13618 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13619 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13620 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13621 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13622 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13623 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13624 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13625 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13626 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13627 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13628 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13629 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13630 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13631 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13632 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13633 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13634 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13635 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13636 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13637 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13638 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13639 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13640 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13641 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13642 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13643 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13644 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13645 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13646 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13647 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13648 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13649 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13650 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13651 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13652 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13653 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13654 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13655 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13656 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13657 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13658 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13659 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13660 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13661 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13662 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13663 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13664 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13665 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13666 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13667 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13668 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13669 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13670 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13671 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13672 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13673 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13674 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13675 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13676 }; 13677 static struct bwn_txgain_entry txgain_r1[] = { 13678 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13679 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13680 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13681 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13682 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13683 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13684 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13685 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13686 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13687 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13688 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13689 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13690 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13691 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13692 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13693 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13694 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13695 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13696 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13697 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13698 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13699 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13700 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13701 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13702 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13703 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13704 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13705 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13706 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13707 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13708 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13709 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13710 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13711 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13712 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13713 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13714 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13715 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13716 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13717 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13718 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13719 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13720 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13721 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13722 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13723 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13724 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13725 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13726 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13727 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13728 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13729 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13730 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13731 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13732 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13733 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13734 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13735 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13736 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13737 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13738 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13739 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13740 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13741 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13742 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13743 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13744 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13745 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13746 { 7, 11, 6, 0, 71 } 13747 }; 13748 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13749 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13750 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13751 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13752 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13753 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13754 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13755 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13756 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13757 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13758 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13759 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13760 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13761 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13762 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13763 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13764 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13765 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13766 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13767 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13768 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13769 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13770 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13771 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13772 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13773 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13774 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13775 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13776 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13777 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13778 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13779 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13780 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13781 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13782 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13783 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13784 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13785 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13786 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13787 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13788 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13789 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13790 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13791 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13792 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13793 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13794 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13795 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13796 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13797 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13798 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13799 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13800 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13801 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13802 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13803 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13804 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13805 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13806 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13807 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13808 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13809 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13810 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13811 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13812 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13813 }; 13814 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13815 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13816 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13817 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13818 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13819 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13820 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13821 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13822 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13823 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13824 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13825 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13826 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13827 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13828 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13829 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13830 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13831 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13832 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13833 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13834 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13835 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13836 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13837 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13838 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13839 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13840 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13841 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13842 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13843 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13844 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13845 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13846 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13847 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13848 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13849 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13850 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13851 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13852 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13853 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13854 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13855 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13856 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13857 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13858 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13859 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13860 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13861 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13862 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13863 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13864 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13865 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13866 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13867 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13868 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13869 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13870 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13871 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13872 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13873 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13874 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13875 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13876 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13877 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13878 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13879 }; 13880 13881 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13882 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13883 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13884 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13885 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13886 txgain_2ghz_r2); 13887 else 13888 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13889 txgain_5ghz_r2); 13890 return; 13891 } 13892 13893 if (mac->mac_phy.rev == 0) { 13894 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13895 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13896 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13897 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13898 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13899 txgain_2ghz_r0); 13900 else 13901 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13902 txgain_5ghz_r0); 13903 return; 13904 } 13905 13906 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13907 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13908 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13909 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13910 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13911 else 13912 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13913} 13914 13915static void 13916bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13917{ 13918 uint32_t offset, type; 13919 13920 type = BWN_TAB_GETTYPE(typeoffset); 13921 offset = BWN_TAB_GETOFFSET(typeoffset); 13922 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13923 13924 switch (type) { 13925 case BWN_TAB_8BIT: 13926 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13927 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13928 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13929 break; 13930 case BWN_TAB_16BIT: 13931 KASSERT(!(value & ~0xffff), 13932 ("%s:%d: fail", __func__, __LINE__)); 13933 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13934 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13935 break; 13936 case BWN_TAB_32BIT: 13937 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13939 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13940 break; 13941 default: 13942 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13943 } 13944} 13945 13946static int 13947bwn_phy_lp_loopback(struct bwn_mac *mac) 13948{ 13949 struct bwn_phy_lp_iq_est ie; 13950 int i, index = -1; 13951 uint32_t tmp; 13952 13953 memset(&ie, 0, sizeof(ie)); 13954 13955 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13956 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13957 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13958 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13959 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13960 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13961 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13962 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13965 for (i = 0; i < 32; i++) { 13966 bwn_phy_lp_set_rxgain_idx(mac, i); 13967 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13968 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13969 continue; 13970 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13971 if ((tmp > 4000) && (tmp < 10000)) { 13972 index = i; 13973 break; 13974 } 13975 } 13976 bwn_phy_lp_ddfs_turnoff(mac); 13977 return (index); 13978} 13979 13980static void 13981bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13982{ 13983 13984 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13985} 13986 13987static void 13988bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13989 int incr1, int incr2, int scale_idx) 13990{ 13991 13992 bwn_phy_lp_ddfs_turnoff(mac); 13993 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13994 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13995 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13996 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13997 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13998 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14000 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14001 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14002 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14003} 14004 14005static uint8_t 14006bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14007 struct bwn_phy_lp_iq_est *ie) 14008{ 14009 int i; 14010 14011 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14012 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14013 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14014 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14015 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14016 14017 for (i = 0; i < 500; i++) { 14018 if (!(BWN_PHY_READ(mac, 14019 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14020 break; 14021 DELAY(1000); 14022 } 14023 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14024 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14025 return 0; 14026 } 14027 14028 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14029 ie->ie_iqprod <<= 16; 14030 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14031 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14032 ie->ie_ipwr <<= 16; 14033 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14034 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14035 ie->ie_qpwr <<= 16; 14036 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14037 14038 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14039 return 1; 14040} 14041 14042static uint32_t 14043bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14044{ 14045 uint32_t offset, type, value; 14046 14047 type = BWN_TAB_GETTYPE(typeoffset); 14048 offset = BWN_TAB_GETOFFSET(typeoffset); 14049 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14050 14051 switch (type) { 14052 case BWN_TAB_8BIT: 14053 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14054 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14055 break; 14056 case BWN_TAB_16BIT: 14057 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14058 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14059 break; 14060 case BWN_TAB_32BIT: 14061 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14062 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14063 value <<= 16; 14064 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14065 break; 14066 default: 14067 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14068 value = 0; 14069 } 14070 14071 return (value); 14072} 14073 14074static void 14075bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14076{ 14077 14078 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14079 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14080} 14081 14082static void 14083bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14084{ 14085 uint16_t ctl; 14086 14087 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14088 ctl |= dac << 7; 14089 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14090} 14091 14092static void 14093bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14094{ 14095 14096 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14097 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14098} 14099 14100static void 14101bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14102{ 14103 14104 if (mac->mac_phy.rev < 2) 14105 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14106 else { 14107 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14108 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14109 } 14110 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14111} 14112 14113static uint16_t 14114bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14115{ 14116 14117 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14118} 14119 14120static uint8_t 14121bwn_nbits(int32_t val) 14122{ 14123 uint32_t tmp; 14124 uint8_t nbits = 0; 14125 14126 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14127 nbits++; 14128 return (nbits); 14129} 14130 14131static void 14132bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14133 struct bwn_txgain_entry *table) 14134{ 14135 int i; 14136 14137 for (i = offset; i < count; i++) 14138 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14139} 14140 14141static void 14142bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14143 struct bwn_txgain_entry data) 14144{ 14145 14146 if (mac->mac_phy.rev >= 2) 14147 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14148 else 14149 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14150} 14151 14152static void 14153bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14154 struct bwn_txgain_entry te) 14155{ 14156 struct bwn_softc *sc = mac->mac_sc; 14157 struct ifnet *ifp = sc->sc_ifp; 14158 struct ieee80211com *ic = ifp->if_l2com; 14159 uint32_t tmp; 14160 14161 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14162 14163 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14164 if (mac->mac_phy.rev >= 3) { 14165 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14166 (0x10 << 24) : (0x70 << 24)); 14167 } else { 14168 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14169 (0x14 << 24) : (0x7f << 24)); 14170 } 14171 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14172 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14173 te.te_bbmult << 20 | te.te_dac << 28); 14174} 14175 14176static void 14177bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14178 struct bwn_txgain_entry te) 14179{ 14180 14181 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14182 14183 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14184 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14185 te.te_dac); 14186 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14187} 14188 14189static void 14190bwn_sysctl_node(struct bwn_softc *sc) 14191{ 14192 device_t dev = sc->sc_dev; 14193 struct bwn_mac *mac; 14194 struct bwn_stats *stats; 14195 14196 /* XXX assume that count of MAC is only 1. */ 14197 14198 if ((mac = sc->sc_curmac) == NULL) 14199 return; 14200 stats = &mac->mac_stats; 14201 14202 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14203 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14204 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14205 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14206 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14207 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14208 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14209 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14210 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14211 14212#ifdef BWN_DEBUG 14213 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14214 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14215 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14216#endif 14217} 14218 14219static device_method_t bwn_methods[] = { 14220 /* Device interface */ 14221 DEVMETHOD(device_probe, bwn_probe), 14222 DEVMETHOD(device_attach, bwn_attach), 14223 DEVMETHOD(device_detach, bwn_detach), 14224 DEVMETHOD(device_suspend, bwn_suspend), 14225 DEVMETHOD(device_resume, bwn_resume), 14226 DEVMETHOD_END 14227}; 14228static driver_t bwn_driver = { 14229 "bwn", 14230 bwn_methods, 14231 sizeof(struct bwn_softc) 14232}; 14233static devclass_t bwn_devclass; 14234DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14235MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14236MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14237MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14238MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14239