if_bwn.c revision 204437
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 204437 2010-02-27 23:42:32Z weongyo $"); 32 33/* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/module.h> 40#include <sys/kernel.h> 41#include <sys/endian.h> 42#include <sys/errno.h> 43#include <sys/firmware.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <machine/bus.h> 47#include <machine/resource.h> 48#include <sys/bus.h> 49#include <sys/rman.h> 50#include <sys/socket.h> 51#include <sys/sockio.h> 52 53#include <net/ethernet.h> 54#include <net/if.h> 55#include <net/if_arp.h> 56#include <net/if_dl.h> 57#include <net/if_llc.h> 58#include <net/if_media.h> 59#include <net/if_types.h> 60 61#include <dev/pci/pcivar.h> 62#include <dev/pci/pcireg.h> 63#include <dev/siba/siba_ids.h> 64#include <dev/siba/sibareg.h> 65#include <dev/siba/sibavar.h> 66 67#include <net80211/ieee80211_var.h> 68#include <net80211/ieee80211_radiotap.h> 69#include <net80211/ieee80211_regdomain.h> 70#include <net80211/ieee80211_amrr.h> 71#include <net80211/ieee80211_phy.h> 72 73#include <dev/bwn/if_bwnreg.h> 74#include <dev/bwn/if_bwnvar.h> 75 76SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters"); 77 78/* 79 * Tunable & sysctl variables. 80 */ 81 82#ifdef BWN_DEBUG 83static int bwn_debug = 0; 84SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 85 "Broadcom debugging printfs"); 86TUNABLE_INT("hw.bwn.debug", &bwn_debug); 87enum { 88 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 89 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 90 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 91 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 92 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 93 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 94 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 95 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 96 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 97 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 98 BWN_DEBUG_NODE = 0x00000400, /* node management */ 99 BWN_DEBUG_LED = 0x00000800, /* led management */ 100 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 101 BWN_DEBUG_LO = 0x00002000, /* LO */ 102 BWN_DEBUG_FW = 0x00004000, /* firmware */ 103 BWN_DEBUG_WME = 0x00008000, /* WME */ 104 BWN_DEBUG_RF = 0x00010000, /* RF */ 105 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 106 BWN_DEBUG_ANY = 0xffffffff 107}; 108#define DPRINTF(sc, m, fmt, ...) do { \ 109 if (sc->sc_debug & (m)) \ 110 printf(fmt, __VA_ARGS__); \ 111} while (0) 112#else 113#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 114#endif 115 116static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 117SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 118 "uses Bad Frames Preemption"); 119static int bwn_bluetooth = 1; 120SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 121 "turns on Bluetooth Coexistence"); 122static int bwn_hwpctl = 0; 123SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 124 "uses H/W power control"); 125static int bwn_msi_disable = 0; /* MSI disabled */ 126TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 127static int bwn_usedma = 1; 128SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 129 "uses DMA"); 130TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 131static int bwn_wme = 1; 132SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 133 "uses WME support"); 134 135static int bwn_attach_pre(struct bwn_softc *); 136static int bwn_attach_post(struct bwn_softc *); 137static void bwn_sprom_bugfixes(struct siba_softc *); 138static void bwn_init(void *); 139static int bwn_init_locked(struct bwn_softc *); 140static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 141static void bwn_start(struct ifnet *); 142static int bwn_attach_core(struct bwn_mac *); 143static void bwn_reset_core(struct bwn_mac *, uint32_t); 144static int bwn_phy_getinfo(struct bwn_mac *, int); 145static int bwn_chiptest(struct bwn_mac *); 146static int bwn_setup_channels(struct bwn_mac *, int, int); 147static int bwn_phy_g_attach(struct bwn_mac *); 148static void bwn_phy_g_detach(struct bwn_mac *); 149static void bwn_phy_g_init_pre(struct bwn_mac *); 150static int bwn_phy_g_prepare_hw(struct bwn_mac *); 151static int bwn_phy_g_init(struct bwn_mac *); 152static void bwn_phy_g_exit(struct bwn_mac *); 153static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 154static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 155 uint16_t); 156static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 157static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 158 uint16_t); 159static int bwn_phy_g_hwpctl(struct bwn_mac *); 160static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 161static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 162static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 163static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 164static int bwn_phy_g_im(struct bwn_mac *, int); 165static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 166static void bwn_phy_g_set_txpwr(struct bwn_mac *); 167static void bwn_phy_g_task_15s(struct bwn_mac *); 168static void bwn_phy_g_task_60s(struct bwn_mac *); 169static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 170static void bwn_phy_switch_analog(struct bwn_mac *, int); 171static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 172static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 173 uint16_t); 174static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 175static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 176 uint32_t); 177static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 178 uint16_t); 179static void bwn_addchannels(struct ieee80211_channel [], int, int *, 180 const struct bwn_channelinfo *, int); 181static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 182 const struct ieee80211_bpf_params *); 183static void bwn_newassoc(struct ieee80211_node *, int); 184static void bwn_updateslot(struct ifnet *); 185static void bwn_update_promisc(struct ifnet *); 186static void bwn_wme_init(struct bwn_mac *); 187static int bwn_wme_update(struct ieee80211com *); 188static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *, 189 const uint8_t [IEEE80211_ADDR_LEN]); 190static void bwn_wme_clear(struct bwn_softc *); 191static void bwn_wme_load(struct bwn_mac *); 192static void bwn_wme_loadparams(struct bwn_mac *, 193 const struct wmeParams *, uint16_t); 194static void bwn_node_cleanup(struct ieee80211_node *); 195static void bwn_scan_start(struct ieee80211com *); 196static void bwn_scan_end(struct ieee80211com *); 197static void bwn_set_channel(struct ieee80211com *); 198static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 199 const char [IFNAMSIZ], int, int, 200 int, const uint8_t [IEEE80211_ADDR_LEN], 201 const uint8_t [IEEE80211_ADDR_LEN]); 202static void bwn_vap_delete(struct ieee80211vap *); 203static void bwn_stop(struct bwn_softc *, int); 204static void bwn_stop_locked(struct bwn_softc *, int); 205static int bwn_core_init(struct bwn_mac *); 206static void bwn_core_start(struct bwn_mac *); 207static void bwn_core_exit(struct bwn_mac *); 208static void bwn_fix_imcfglobug(struct bwn_mac *); 209static void bwn_bt_disable(struct bwn_mac *); 210static int bwn_chip_init(struct bwn_mac *); 211static uint64_t bwn_hf_read(struct bwn_mac *); 212static void bwn_hf_write(struct bwn_mac *, uint64_t); 213static void bwn_set_txretry(struct bwn_mac *, int, int); 214static void bwn_rate_init(struct bwn_mac *); 215static void bwn_set_phytxctl(struct bwn_mac *); 216static void bwn_spu_setdelay(struct bwn_mac *, int); 217static void bwn_bt_enable(struct bwn_mac *); 218static void bwn_set_macaddr(struct bwn_mac *); 219static void bwn_crypt_init(struct bwn_mac *); 220static void bwn_chip_exit(struct bwn_mac *); 221static int bwn_fw_fillinfo(struct bwn_mac *); 222static int bwn_fw_loaducode(struct bwn_mac *); 223static int bwn_gpio_init(struct bwn_mac *); 224static int bwn_fw_loadinitvals(struct bwn_mac *); 225static int bwn_phy_init(struct bwn_mac *); 226static void bwn_set_txantenna(struct bwn_mac *, int); 227static void bwn_set_opmode(struct bwn_mac *); 228static void bwn_gpio_cleanup(struct bwn_mac *); 229static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 230static uint8_t bwn_plcp_getcck(const uint8_t); 231static uint8_t bwn_plcp_getofdm(const uint8_t); 232static void bwn_pio_init(struct bwn_mac *); 233static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 234static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 235 int); 236static void bwn_pio_setupqueue_rx(struct bwn_mac *, 237 struct bwn_pio_rxqueue *, int); 238static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 239static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 240 uint16_t); 241static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 242static int bwn_pio_rx(struct bwn_pio_rxqueue *); 243static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 244static void bwn_pio_handle_txeof(struct bwn_mac *, 245 const struct bwn_txstatus *); 246static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 247static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 248static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 249 uint16_t); 250static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 251 uint32_t); 252static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 253 struct mbuf *); 254static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 255static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 256 struct bwn_pio_txqueue *, uint32_t, const void *, int); 257static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 258 uint16_t, uint32_t); 259static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 260 struct bwn_pio_txqueue *, uint16_t, const void *, int); 261static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 262 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 263static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 264 uint16_t, struct bwn_pio_txpkt **); 265static void bwn_dma_init(struct bwn_mac *); 266static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 267static int bwn_dma_mask2type(uint64_t); 268static uint64_t bwn_dma_mask(struct bwn_mac *); 269static uint16_t bwn_dma_base(int, int); 270static void bwn_dma_ringfree(struct bwn_dma_ring **); 271static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 272 int, struct bwn_dmadesc_generic **, 273 struct bwn_dmadesc_meta **); 274static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 275 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 276 int, int); 277static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 278static void bwn_dma_32_suspend(struct bwn_dma_ring *); 279static void bwn_dma_32_resume(struct bwn_dma_ring *); 280static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 281static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 282static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 283 int, struct bwn_dmadesc_generic **, 284 struct bwn_dmadesc_meta **); 285static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 286 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 287 int, int); 288static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 289static void bwn_dma_64_suspend(struct bwn_dma_ring *); 290static void bwn_dma_64_resume(struct bwn_dma_ring *); 291static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 292static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 293static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 294static void bwn_dma_setup(struct bwn_dma_ring *); 295static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 296static void bwn_dma_cleanup(struct bwn_dma_ring *); 297static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 298static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 299static void bwn_dma_rx(struct bwn_dma_ring *); 300static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 301static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 302 struct bwn_dmadesc_meta *); 303static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 304static int bwn_dma_gettype(struct bwn_mac *); 305static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 306static int bwn_dma_freeslot(struct bwn_dma_ring *); 307static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 308static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 309static int bwn_dma_newbuf(struct bwn_dma_ring *, 310 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 311 int); 312static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 313 bus_size_t, int); 314static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 315static void bwn_dma_handle_txeof(struct bwn_mac *, 316 const struct bwn_txstatus *); 317static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 318 struct mbuf *); 319static int bwn_dma_getslot(struct bwn_dma_ring *); 320static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 321 uint8_t); 322static int bwn_dma_attach(struct bwn_mac *); 323static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 324 int, int, int); 325static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 326 const struct bwn_txstatus *, uint16_t, int *); 327static void bwn_dma_free(struct bwn_mac *); 328static void bwn_phy_g_init_sub(struct bwn_mac *); 329static uint8_t bwn_has_hwpctl(struct bwn_mac *); 330static void bwn_phy_init_b5(struct bwn_mac *); 331static void bwn_phy_init_b6(struct bwn_mac *); 332static void bwn_phy_init_a(struct bwn_mac *); 333static void bwn_loopback_calcgain(struct bwn_mac *); 334static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 335static void bwn_lo_g_init(struct bwn_mac *); 336static void bwn_lo_g_adjust(struct bwn_mac *); 337static void bwn_lo_get_powervector(struct bwn_mac *); 338static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 339 const struct bwn_bbatt *, const struct bwn_rfatt *); 340static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 341static void bwn_phy_hwpctl_init(struct bwn_mac *); 342static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 343static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 344 const struct bwn_bbatt *, const struct bwn_rfatt *, 345 uint8_t); 346static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 347static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 348static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 349static void bwn_wa_init(struct bwn_mac *); 350static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 351 uint16_t); 352static void bwn_dummy_transmission(struct bwn_mac *, int, int); 353static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 354 uint32_t); 355static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 356 uint16_t); 357static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 358static void bwn_mac_suspend(struct bwn_mac *); 359static void bwn_mac_enable(struct bwn_mac *); 360static void bwn_psctl(struct bwn_mac *, uint32_t); 361static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 362static void bwn_nrssi_offset(struct bwn_mac *); 363static void bwn_nrssi_threshold(struct bwn_mac *); 364static void bwn_nrssi_slope_11g(struct bwn_mac *); 365static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 366 int16_t); 367static void bwn_set_original_gains(struct bwn_mac *); 368static void bwn_hwpctl_early_init(struct bwn_mac *); 369static void bwn_hwpctl_init_gphy(struct bwn_mac *); 370static uint16_t bwn_phy_g_chan2freq(uint8_t); 371static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 372static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 373 const char *, struct bwn_fwfile *); 374static void bwn_release_firmware(struct bwn_mac *); 375static void bwn_do_release_fw(struct bwn_fwfile *); 376static uint16_t bwn_fwcaps_read(struct bwn_mac *); 377static int bwn_fwinitvals_write(struct bwn_mac *, 378 const struct bwn_fwinitvals *, size_t, size_t); 379static int bwn_switch_channel(struct bwn_mac *, int); 380static uint16_t bwn_ant2phy(int); 381static void bwn_mac_write_bssid(struct bwn_mac *); 382static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 383 const uint8_t *); 384static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 385 const uint8_t *, size_t, const uint8_t *); 386static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 387 const uint8_t *); 388static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 389 const uint8_t *); 390static void bwn_phy_exit(struct bwn_mac *); 391static void bwn_core_stop(struct bwn_mac *); 392static int bwn_switch_band(struct bwn_softc *, 393 struct ieee80211_channel *); 394static void bwn_phy_reset(struct bwn_mac *); 395static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 396static void bwn_set_pretbtt(struct bwn_mac *); 397static int bwn_intr(void *); 398static void bwn_intrtask(void *, int); 399static void bwn_restart(struct bwn_mac *, const char *); 400static void bwn_intr_ucode_debug(struct bwn_mac *); 401static void bwn_intr_tbtt_indication(struct bwn_mac *); 402static void bwn_intr_atim_end(struct bwn_mac *); 403static void bwn_intr_beacon(struct bwn_mac *); 404static void bwn_intr_pmq(struct bwn_mac *); 405static void bwn_intr_noise(struct bwn_mac *); 406static void bwn_intr_txeof(struct bwn_mac *); 407static void bwn_hwreset(void *, int); 408static void bwn_handle_fwpanic(struct bwn_mac *); 409static void bwn_load_beacon0(struct bwn_mac *); 410static void bwn_load_beacon1(struct bwn_mac *); 411static uint32_t bwn_jssi_read(struct bwn_mac *); 412static void bwn_noise_gensample(struct bwn_mac *); 413static void bwn_handle_txeof(struct bwn_mac *, 414 const struct bwn_txstatus *); 415static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 416static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 417static void bwn_start_locked(struct ifnet *); 418static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 419 struct mbuf *); 420static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 421static int bwn_set_txhdr(struct bwn_mac *, 422 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 423 uint16_t); 424static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 425 const uint8_t); 426static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 427static uint8_t bwn_get_fbrate(uint8_t); 428static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 429static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 430static void bwn_phy_lock(struct bwn_mac *); 431static void bwn_phy_unlock(struct bwn_mac *); 432static void bwn_rf_lock(struct bwn_mac *); 433static void bwn_rf_unlock(struct bwn_mac *); 434static void bwn_txpwr(void *, int); 435static void bwn_tasks(void *); 436static void bwn_task_15s(struct bwn_mac *); 437static void bwn_task_30s(struct bwn_mac *); 438static void bwn_task_60s(struct bwn_mac *); 439static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 440 uint8_t); 441static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 442static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 443 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 444 int, int); 445static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 446static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 447static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 448static void bwn_watchdog(void *); 449static void bwn_dma_stop(struct bwn_mac *); 450static void bwn_pio_stop(struct bwn_mac *); 451static void bwn_dma_ringstop(struct bwn_dma_ring **); 452static void bwn_led_attach(struct bwn_mac *); 453static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 454static void bwn_led_event(struct bwn_mac *, int); 455static void bwn_led_blink_start(struct bwn_mac *, int, int); 456static void bwn_led_blink_next(void *); 457static void bwn_led_blink_end(void *); 458static void bwn_rfswitch(void *); 459static void bwn_rf_turnon(struct bwn_mac *); 460static void bwn_rf_turnoff(struct bwn_mac *); 461static void bwn_phy_lp_init_pre(struct bwn_mac *); 462static int bwn_phy_lp_init(struct bwn_mac *); 463static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 464static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 465static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 466 uint16_t); 467static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 468static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 469static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 470static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 471static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 472static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 473static void bwn_phy_lp_task_60s(struct bwn_mac *); 474static void bwn_phy_lp_readsprom(struct bwn_mac *); 475static void bwn_phy_lp_bbinit(struct bwn_mac *); 476static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 477static void bwn_phy_lp_calib(struct bwn_mac *); 478static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 479static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 480static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 481static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 482static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 483static void bwn_phy_lp_digflt_save(struct bwn_mac *); 484static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 485static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 486static void bwn_phy_lp_bugfix(struct bwn_mac *); 487static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 488static void bwn_phy_lp_tblinit(struct bwn_mac *); 489static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 490static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 491static void bwn_phy_lp_b2062_init(struct bwn_mac *); 492static void bwn_phy_lp_b2063_init(struct bwn_mac *); 493static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 494static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 495static void bwn_phy_lp_set_rccap(struct bwn_mac *); 496static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 497static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 498static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 499static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 500 const void *); 501static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 502static struct bwn_txgain 503 bwn_phy_lp_get_txgain(struct bwn_mac *); 504static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 505static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 506static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 507static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 508static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 509static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 510static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 511static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 512static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 513static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 514static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 515static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 516static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 517static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 518static int bwn_phy_lp_loopback(struct bwn_mac *); 519static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 520static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 521 int); 522static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 523 struct bwn_phy_lp_iq_est *); 524static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 525static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 526static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 527static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 528static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 529static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 530static uint8_t bwn_nbits(int32_t); 531static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 532 struct bwn_txgain_entry *); 533static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 534 struct bwn_txgain_entry); 535static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 536 struct bwn_txgain_entry); 537static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 538 struct bwn_txgain_entry); 539static void bwn_sysctl_node(struct bwn_softc *); 540 541static struct resource_spec bwn_res_spec_legacy[] = { 542 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 543 { -1, 0, 0 } 544}; 545 546static struct resource_spec bwn_res_spec_msi[] = { 547 { SYS_RES_IRQ, 1, RF_ACTIVE }, 548 { -1, 0, 0 } 549}; 550 551static const struct bwn_channelinfo bwn_chantable_bg = { 552 .channels = { 553 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 554 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 555 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 556 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 557 { 2472, 13, 30 }, { 2484, 14, 30 } }, 558 .nchannels = 14 559}; 560 561static const struct bwn_channelinfo bwn_chantable_a = { 562 .channels = { 563 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 564 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 565 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 566 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 567 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 568 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 569 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 570 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 571 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 572 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 573 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 574 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 575 { 6080, 216, 30 } }, 576 .nchannels = 37 577}; 578 579static const struct bwn_channelinfo bwn_chantable_n = { 580 .channels = { 581 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 582 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 583 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 584 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 585 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 586 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 587 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 588 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 589 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 590 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 591 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 592 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 593 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 594 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 595 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 596 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 597 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 598 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 599 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 600 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 601 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 602 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 603 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 604 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 605 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 606 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 607 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 608 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 609 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 610 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 611 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 612 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 613 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 614 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 615 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 616 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 617 { 6130, 226, 30 }, { 6140, 228, 30 } }, 618 .nchannels = 110 619}; 620 621static const uint8_t bwn_b2063_chantable_data[33][12] = { 622 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 623 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 624 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 625 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 626 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 627 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 628 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 629 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 630 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 631 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 632 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 633 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 634 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 635 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 636 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 637 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 638 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 639 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 640 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 641 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 642 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 643 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 644 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 645 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 646 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 647 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 648 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 649 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 650 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 651 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 652 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 653 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 654 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 655}; 656 657static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 658 { 1, 2412, bwn_b2063_chantable_data[0] }, 659 { 2, 2417, bwn_b2063_chantable_data[0] }, 660 { 3, 2422, bwn_b2063_chantable_data[0] }, 661 { 4, 2427, bwn_b2063_chantable_data[1] }, 662 { 5, 2432, bwn_b2063_chantable_data[1] }, 663 { 6, 2437, bwn_b2063_chantable_data[1] }, 664 { 7, 2442, bwn_b2063_chantable_data[1] }, 665 { 8, 2447, bwn_b2063_chantable_data[1] }, 666 { 9, 2452, bwn_b2063_chantable_data[2] }, 667 { 10, 2457, bwn_b2063_chantable_data[2] }, 668 { 11, 2462, bwn_b2063_chantable_data[3] }, 669 { 12, 2467, bwn_b2063_chantable_data[3] }, 670 { 13, 2472, bwn_b2063_chantable_data[3] }, 671 { 14, 2484, bwn_b2063_chantable_data[4] }, 672 { 34, 5170, bwn_b2063_chantable_data[5] }, 673 { 36, 5180, bwn_b2063_chantable_data[6] }, 674 { 38, 5190, bwn_b2063_chantable_data[7] }, 675 { 40, 5200, bwn_b2063_chantable_data[8] }, 676 { 42, 5210, bwn_b2063_chantable_data[9] }, 677 { 44, 5220, bwn_b2063_chantable_data[10] }, 678 { 46, 5230, bwn_b2063_chantable_data[11] }, 679 { 48, 5240, bwn_b2063_chantable_data[12] }, 680 { 52, 5260, bwn_b2063_chantable_data[13] }, 681 { 56, 5280, bwn_b2063_chantable_data[14] }, 682 { 60, 5300, bwn_b2063_chantable_data[14] }, 683 { 64, 5320, bwn_b2063_chantable_data[15] }, 684 { 100, 5500, bwn_b2063_chantable_data[16] }, 685 { 104, 5520, bwn_b2063_chantable_data[17] }, 686 { 108, 5540, bwn_b2063_chantable_data[18] }, 687 { 112, 5560, bwn_b2063_chantable_data[19] }, 688 { 116, 5580, bwn_b2063_chantable_data[20] }, 689 { 120, 5600, bwn_b2063_chantable_data[21] }, 690 { 124, 5620, bwn_b2063_chantable_data[21] }, 691 { 128, 5640, bwn_b2063_chantable_data[22] }, 692 { 132, 5660, bwn_b2063_chantable_data[22] }, 693 { 136, 5680, bwn_b2063_chantable_data[22] }, 694 { 140, 5700, bwn_b2063_chantable_data[23] }, 695 { 149, 5745, bwn_b2063_chantable_data[23] }, 696 { 153, 5765, bwn_b2063_chantable_data[23] }, 697 { 157, 5785, bwn_b2063_chantable_data[23] }, 698 { 161, 5805, bwn_b2063_chantable_data[23] }, 699 { 165, 5825, bwn_b2063_chantable_data[23] }, 700 { 184, 4920, bwn_b2063_chantable_data[24] }, 701 { 188, 4940, bwn_b2063_chantable_data[25] }, 702 { 192, 4960, bwn_b2063_chantable_data[26] }, 703 { 196, 4980, bwn_b2063_chantable_data[27] }, 704 { 200, 5000, bwn_b2063_chantable_data[28] }, 705 { 204, 5020, bwn_b2063_chantable_data[29] }, 706 { 208, 5040, bwn_b2063_chantable_data[30] }, 707 { 212, 5060, bwn_b2063_chantable_data[31] }, 708 { 216, 5080, bwn_b2063_chantable_data[32] } 709}; 710 711static const uint8_t bwn_b2062_chantable_data[22][12] = { 712 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 713 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 719 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 720 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 721 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 722 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 723 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 724 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 725 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 727 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 728 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 729 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 730 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 731 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 732 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 733 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 734}; 735 736static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 737 { 1, 2412, bwn_b2062_chantable_data[0] }, 738 { 2, 2417, bwn_b2062_chantable_data[0] }, 739 { 3, 2422, bwn_b2062_chantable_data[0] }, 740 { 4, 2427, bwn_b2062_chantable_data[0] }, 741 { 5, 2432, bwn_b2062_chantable_data[0] }, 742 { 6, 2437, bwn_b2062_chantable_data[0] }, 743 { 7, 2442, bwn_b2062_chantable_data[0] }, 744 { 8, 2447, bwn_b2062_chantable_data[0] }, 745 { 9, 2452, bwn_b2062_chantable_data[0] }, 746 { 10, 2457, bwn_b2062_chantable_data[0] }, 747 { 11, 2462, bwn_b2062_chantable_data[0] }, 748 { 12, 2467, bwn_b2062_chantable_data[0] }, 749 { 13, 2472, bwn_b2062_chantable_data[0] }, 750 { 14, 2484, bwn_b2062_chantable_data[0] }, 751 { 34, 5170, bwn_b2062_chantable_data[1] }, 752 { 38, 5190, bwn_b2062_chantable_data[2] }, 753 { 42, 5210, bwn_b2062_chantable_data[2] }, 754 { 46, 5230, bwn_b2062_chantable_data[3] }, 755 { 36, 5180, bwn_b2062_chantable_data[4] }, 756 { 40, 5200, bwn_b2062_chantable_data[5] }, 757 { 44, 5220, bwn_b2062_chantable_data[6] }, 758 { 48, 5240, bwn_b2062_chantable_data[3] }, 759 { 52, 5260, bwn_b2062_chantable_data[3] }, 760 { 56, 5280, bwn_b2062_chantable_data[3] }, 761 { 60, 5300, bwn_b2062_chantable_data[7] }, 762 { 64, 5320, bwn_b2062_chantable_data[8] }, 763 { 100, 5500, bwn_b2062_chantable_data[9] }, 764 { 104, 5520, bwn_b2062_chantable_data[10] }, 765 { 108, 5540, bwn_b2062_chantable_data[10] }, 766 { 112, 5560, bwn_b2062_chantable_data[10] }, 767 { 116, 5580, bwn_b2062_chantable_data[11] }, 768 { 120, 5600, bwn_b2062_chantable_data[12] }, 769 { 124, 5620, bwn_b2062_chantable_data[12] }, 770 { 128, 5640, bwn_b2062_chantable_data[12] }, 771 { 132, 5660, bwn_b2062_chantable_data[12] }, 772 { 136, 5680, bwn_b2062_chantable_data[12] }, 773 { 140, 5700, bwn_b2062_chantable_data[12] }, 774 { 149, 5745, bwn_b2062_chantable_data[12] }, 775 { 153, 5765, bwn_b2062_chantable_data[12] }, 776 { 157, 5785, bwn_b2062_chantable_data[12] }, 777 { 161, 5805, bwn_b2062_chantable_data[12] }, 778 { 165, 5825, bwn_b2062_chantable_data[12] }, 779 { 184, 4920, bwn_b2062_chantable_data[13] }, 780 { 188, 4940, bwn_b2062_chantable_data[14] }, 781 { 192, 4960, bwn_b2062_chantable_data[15] }, 782 { 196, 4980, bwn_b2062_chantable_data[16] }, 783 { 200, 5000, bwn_b2062_chantable_data[17] }, 784 { 204, 5020, bwn_b2062_chantable_data[18] }, 785 { 208, 5040, bwn_b2062_chantable_data[19] }, 786 { 212, 5060, bwn_b2062_chantable_data[20] }, 787 { 216, 5080, bwn_b2062_chantable_data[21] } 788}; 789 790/* for LP PHY */ 791static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 792 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 793 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 794 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 795 { 13, -66, 13 }, { 14, -66, 13 }, 796}; 797 798/* for LP PHY */ 799static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 800 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 801 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 802 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 803 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 804 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 805 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 806 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 807 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 808 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 809 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 810 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 811 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 812 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 813}; 814 815static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 816 817static const uint8_t bwn_tab_sigsq_tbl[] = { 818 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 819 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 820 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 821 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 822 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 823 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 824}; 825 826static const uint8_t bwn_tab_pllfrac_tbl[] = { 827 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 828 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 829}; 830 831static const uint16_t bwn_tabl_iqlocal_tbl[] = { 832 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 833 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 836 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 837 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 839 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 840 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 841 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 842 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 843 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 844}; 845 846static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 847static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 848static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 849static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 850static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 851const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 852 853#define VENDOR_LED_ACT(vendor) \ 854{ \ 855 .vid = PCI_VENDOR_##vendor, \ 856 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 857} 858 859static const struct { 860 uint16_t vid; 861 uint8_t led_act[BWN_LED_MAX]; 862} bwn_vendor_led_act[] = { 863 VENDOR_LED_ACT(COMPAQ), 864 VENDOR_LED_ACT(ASUSTEK) 865}; 866 867static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 868 { BWN_VENDOR_LED_ACT_DEFAULT }; 869 870#undef VENDOR_LED_ACT 871 872static const struct { 873 int on_dur; 874 int off_dur; 875} bwn_led_duration[109] = { 876 [0] = { 400, 100 }, 877 [2] = { 150, 75 }, 878 [4] = { 90, 45 }, 879 [11] = { 66, 34 }, 880 [12] = { 53, 26 }, 881 [18] = { 42, 21 }, 882 [22] = { 35, 17 }, 883 [24] = { 32, 16 }, 884 [36] = { 21, 10 }, 885 [48] = { 16, 8 }, 886 [72] = { 11, 5 }, 887 [96] = { 9, 4 }, 888 [108] = { 7, 3 } 889}; 890 891static const uint16_t bwn_wme_shm_offsets[] = { 892 [0] = BWN_WME_BESTEFFORT, 893 [1] = BWN_WME_BACKGROUND, 894 [2] = BWN_WME_VOICE, 895 [3] = BWN_WME_VIDEO, 896}; 897 898static const struct siba_devid bwn_devs[] = { 899 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 900 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 901 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 902 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 903 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 904 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 905 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 906 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 907 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 908}; 909 910static int 911bwn_probe(device_t dev) 912{ 913 struct siba_dev_softc *sd = device_get_ivars(dev); 914 int i; 915 916 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 917 if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor && 918 sd->sd_id.sd_device == bwn_devs[i].sd_device && 919 sd->sd_id.sd_rev == bwn_devs[i].sd_rev) 920 return (BUS_PROBE_DEFAULT); 921 } 922 923 return (ENXIO); 924} 925 926static int 927bwn_attach(device_t dev) 928{ 929 struct bwn_mac *mac; 930 struct bwn_softc *sc = device_get_softc(dev); 931 struct siba_dev_softc *sd = device_get_ivars(dev); 932 struct siba_softc *siba = sd->sd_bus; 933 int error, i, msic, reg; 934 935 sc->sc_dev = dev; 936 sc->sc_sd = sd; 937#ifdef BWN_DEBUG 938 sc->sc_debug = bwn_debug; 939#endif 940 941 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 942 error = bwn_attach_pre(sc); 943 if (error != 0) 944 return (error); 945 bwn_sprom_bugfixes(sd->sd_bus); 946 sc->sc_flags |= BWN_FLAG_ATTACHED; 947 } 948 949 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 950 if (siba->siba_pci_did != 0x4313 && 951 siba->siba_pci_did != 0x431a && 952 siba->siba_pci_did != 0x4321) { 953 device_printf(sc->sc_dev, 954 "skip 802.11 cores\n"); 955 return (ENODEV); 956 } 957 } 958 959 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 960 M_NOWAIT | M_ZERO); 961 if (mac == NULL) 962 return (ENOMEM); 963 mac->mac_sc = sc; 964 mac->mac_sd = sd; 965 mac->mac_status = BWN_MAC_STATUS_UNINIT; 966 if (bwn_bfp != 0) 967 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 968 969 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 970 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 971 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 972 973 error = bwn_attach_core(mac); 974 if (error) 975 goto fail0; 976 bwn_led_attach(mac); 977 978 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 979 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 980 sd->sd_bus->siba_chipid, sd->sd_id.sd_rev, 981 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 982 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 983 mac->mac_phy.rf_rev); 984 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 985 device_printf(sc->sc_dev, "DMA (%d bits)\n", 986 mac->mac_method.dma.dmatype); 987 else 988 device_printf(sc->sc_dev, "PIO\n"); 989 990 /* 991 * setup PCI resources and interrupt. 992 */ 993 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) { 994 msic = pci_msi_count(dev); 995 if (bootverbose) 996 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 997 } else 998 msic = 0; 999 1000 mac->mac_intr_spec = bwn_res_spec_legacy; 1001 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 1002 if (pci_alloc_msi(dev, &msic) == 0) { 1003 device_printf(sc->sc_dev, 1004 "Using %d MSI messages\n", msic); 1005 mac->mac_intr_spec = bwn_res_spec_msi; 1006 mac->mac_msi = 1; 1007 } 1008 } 1009 1010 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1011 mac->mac_res_irq); 1012 if (error) { 1013 device_printf(sc->sc_dev, 1014 "couldn't allocate IRQ resources (%d)\n", error); 1015 goto fail1; 1016 } 1017 1018 if (mac->mac_msi == 0) 1019 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1020 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1021 &mac->mac_intrhand[0]); 1022 else { 1023 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1024 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1025 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1026 &mac->mac_intrhand[i]); 1027 if (error != 0) { 1028 device_printf(sc->sc_dev, 1029 "couldn't setup interrupt (%d)\n", error); 1030 break; 1031 } 1032 } 1033 } 1034 1035 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1036 1037 /* 1038 * calls attach-post routine 1039 */ 1040 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1041 bwn_attach_post(sc); 1042 1043 return (0); 1044fail1: 1045 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1046 pci_release_msi(dev); 1047fail0: 1048 free(mac, M_DEVBUF); 1049 return (error); 1050} 1051 1052static int 1053bwn_is_valid_ether_addr(uint8_t *addr) 1054{ 1055 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1056 1057 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1058 return (FALSE); 1059 1060 return (TRUE); 1061} 1062 1063static int 1064bwn_attach_post(struct bwn_softc *sc) 1065{ 1066 struct ieee80211com *ic; 1067 struct ifnet *ifp = sc->sc_ifp; 1068 struct siba_dev_softc *sd = sc->sc_sd; 1069 struct siba_sprom *sprom = &sd->sd_bus->siba_sprom; 1070 1071 ic = ifp->if_l2com; 1072 ic->ic_ifp = ifp; 1073 /* XXX not right but it's not used anywhere important */ 1074 ic->ic_phytype = IEEE80211_T_OFDM; 1075 ic->ic_opmode = IEEE80211_M_STA; 1076 ic->ic_caps = 1077 IEEE80211_C_STA /* station mode supported */ 1078 | IEEE80211_C_MONITOR /* monitor mode */ 1079 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1080 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1081 | IEEE80211_C_SHSLOT /* short slot time supported */ 1082 | IEEE80211_C_WME /* WME/WMM supported */ 1083 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1084 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1085 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1086 ; 1087 1088 /* call MI attach routine. */ 1089 ieee80211_ifattach(ic, 1090 bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a : 1091 sprom->mac_80211bg); 1092 1093 ic->ic_headroom = sizeof(struct bwn_txhdr); 1094 1095 /* override default methods */ 1096 ic->ic_raw_xmit = bwn_raw_xmit; 1097 ic->ic_newassoc = bwn_newassoc; 1098 ic->ic_updateslot = bwn_updateslot; 1099 ic->ic_update_promisc = bwn_update_promisc; 1100 ic->ic_wme.wme_update = bwn_wme_update; 1101 1102 ic->ic_node_alloc = bwn_node_alloc; 1103 sc->sc_node_cleanup = ic->ic_node_cleanup; 1104 ic->ic_node_cleanup = bwn_node_cleanup; 1105 1106 ic->ic_scan_start = bwn_scan_start; 1107 ic->ic_scan_end = bwn_scan_end; 1108 ic->ic_set_channel = bwn_set_channel; 1109 1110 ic->ic_vap_create = bwn_vap_create; 1111 ic->ic_vap_delete = bwn_vap_delete; 1112 1113 ieee80211_radiotap_attach(ic, 1114 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1115 BWN_TX_RADIOTAP_PRESENT, 1116 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1117 BWN_RX_RADIOTAP_PRESENT); 1118 1119 bwn_sysctl_node(sc); 1120 1121 if (bootverbose) 1122 ieee80211_announce(ic); 1123 return (0); 1124} 1125 1126static void 1127bwn_phy_detach(struct bwn_mac *mac) 1128{ 1129 1130 if (mac->mac_phy.detach != NULL) 1131 mac->mac_phy.detach(mac); 1132} 1133 1134static int 1135bwn_detach(device_t dev) 1136{ 1137 struct bwn_softc *sc = device_get_softc(dev); 1138 struct bwn_mac *mac = sc->sc_curmac; 1139 struct ifnet *ifp = sc->sc_ifp; 1140 struct ieee80211com *ic = ifp->if_l2com; 1141 int i; 1142 1143 sc->sc_flags |= BWN_FLAG_INVALID; 1144 1145 if (device_is_attached(sc->sc_dev)) { 1146 bwn_stop(sc, 1); 1147 bwn_dma_free(mac); 1148 callout_drain(&sc->sc_led_blink_ch); 1149 callout_drain(&sc->sc_rfswitch_ch); 1150 callout_drain(&sc->sc_task_ch); 1151 callout_drain(&sc->sc_watchdog_ch); 1152 bwn_phy_detach(mac); 1153 if (ifp != NULL) { 1154 ieee80211_draintask(ic, &mac->mac_hwreset); 1155 ieee80211_draintask(ic, &mac->mac_txpower); 1156 ieee80211_ifdetach(ic); 1157 if_free(ifp); 1158 } 1159 } 1160 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1161 taskqueue_free(sc->sc_tq); 1162 1163 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1164 if (mac->mac_intrhand[i] != NULL) { 1165 bus_teardown_intr(dev, mac->mac_res_irq[i], 1166 mac->mac_intrhand[i]); 1167 mac->mac_intrhand[i] = NULL; 1168 } 1169 } 1170 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1171 if (mac->mac_msi != 0) 1172 pci_release_msi(dev); 1173 1174 BWN_LOCK_DESTROY(sc); 1175 return (0); 1176} 1177 1178static int 1179bwn_attach_pre(struct bwn_softc *sc) 1180{ 1181 struct ifnet *ifp; 1182 int error = 0; 1183 1184 BWN_LOCK_INIT(sc); 1185 TAILQ_INIT(&sc->sc_maclist); 1186 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1187 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1188 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1189 1190 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1191 taskqueue_thread_enqueue, &sc->sc_tq); 1192 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1193 "%s taskq", device_get_nameunit(sc->sc_dev)); 1194 1195 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1196 if (ifp == NULL) { 1197 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1198 error = ENOSPC; 1199 goto fail; 1200 } 1201 1202 /* set these up early for if_printf use */ 1203 if_initname(ifp, device_get_name(sc->sc_dev), 1204 device_get_unit(sc->sc_dev)); 1205 1206 ifp->if_softc = sc; 1207 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1208 ifp->if_init = bwn_init; 1209 ifp->if_ioctl = bwn_ioctl; 1210 ifp->if_start = bwn_start; 1211 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 1212 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 1213 IFQ_SET_READY(&ifp->if_snd); 1214 1215 return (0); 1216 1217fail: BWN_LOCK_DESTROY(sc); 1218 return (error); 1219} 1220 1221static void 1222bwn_sprom_bugfixes(struct siba_softc *siba) 1223{ 1224#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1225 ((siba->siba_pci_vid == PCI_VENDOR_##_vendor) && \ 1226 (siba->siba_pci_did == _device) && \ 1227 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) && \ 1228 (siba->siba_pci_subdid == _subdevice)) 1229 1230 if (siba->siba_board_vendor == PCI_VENDOR_APPLE && 1231 siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40) 1232 siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL; 1233 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL && 1234 siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74) 1235 siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST; 1236 if (siba->siba_type == SIBA_TYPE_PCI) { 1237 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1238 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1239 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1240 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1241 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1242 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1243 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1244 siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST; 1245 } 1246#undef BWN_ISDEV 1247} 1248 1249static int 1250bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1251{ 1252#define IS_RUNNING(ifp) \ 1253 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1254 struct bwn_softc *sc = ifp->if_softc; 1255 struct ieee80211com *ic = ifp->if_l2com; 1256 struct ifreq *ifr = (struct ifreq *)data; 1257 int error = 0, startall; 1258 1259 switch (cmd) { 1260 case SIOCSIFFLAGS: 1261 startall = 0; 1262 if (IS_RUNNING(ifp)) { 1263 bwn_update_promisc(ifp); 1264 } else if (ifp->if_flags & IFF_UP) { 1265 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1266 bwn_init(sc); 1267 startall = 1; 1268 } 1269 } else 1270 bwn_stop(sc, 1); 1271 if (startall) 1272 ieee80211_start_all(ic); 1273 break; 1274 case SIOCGIFMEDIA: 1275 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1276 break; 1277 case SIOCGIFADDR: 1278 error = ether_ioctl(ifp, cmd, data); 1279 break; 1280 default: 1281 error = EINVAL; 1282 break; 1283 } 1284 return (error); 1285} 1286 1287static void 1288bwn_start(struct ifnet *ifp) 1289{ 1290 struct bwn_softc *sc = ifp->if_softc; 1291 1292 BWN_LOCK(sc); 1293 bwn_start_locked(ifp); 1294 BWN_UNLOCK(sc); 1295} 1296 1297static void 1298bwn_start_locked(struct ifnet *ifp) 1299{ 1300 struct bwn_softc *sc = ifp->if_softc; 1301 struct bwn_mac *mac = sc->sc_curmac; 1302 struct ieee80211_frame *wh; 1303 struct ieee80211_node *ni; 1304 struct ieee80211_key *k; 1305 struct mbuf *m; 1306 1307 BWN_ASSERT_LOCKED(sc); 1308 1309 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1310 mac->mac_status < BWN_MAC_STATUS_STARTED) 1311 return; 1312 1313 for (;;) { 1314 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1315 if (m == NULL) 1316 break; 1317 1318 if (bwn_tx_isfull(sc, m)) 1319 break; 1320 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1321 if (ni == NULL) { 1322 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1323 m_freem(m); 1324 ifp->if_oerrors++; 1325 continue; 1326 } 1327 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1328 wh = mtod(m, struct ieee80211_frame *); 1329 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1330 k = ieee80211_crypto_encap(ni, m); 1331 if (k == NULL) { 1332 ieee80211_free_node(ni); 1333 m_freem(m); 1334 ifp->if_oerrors++; 1335 continue; 1336 } 1337 } 1338 wh = NULL; /* Catch any invalid use */ 1339 1340 if (bwn_tx_start(sc, ni, m) != 0) { 1341 if (ni != NULL) 1342 ieee80211_free_node(ni); 1343 ifp->if_oerrors++; 1344 continue; 1345 } 1346 1347 sc->sc_watchdog_timer = 5; 1348 } 1349} 1350 1351static int 1352bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1353{ 1354 struct bwn_dma_ring *dr; 1355 struct bwn_mac *mac = sc->sc_curmac; 1356 struct bwn_pio_txqueue *tq; 1357 struct ifnet *ifp = sc->sc_ifp; 1358 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1359 1360 BWN_ASSERT_LOCKED(sc); 1361 1362 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1363 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1364 if (dr->dr_stop == 1 || 1365 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1366 dr->dr_stop = 1; 1367 goto full; 1368 } 1369 } else { 1370 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1371 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1372 pktlen > (tq->tq_size - tq->tq_used)) { 1373 tq->tq_stop = 1; 1374 goto full; 1375 } 1376 } 1377 return (0); 1378full: 1379 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1380 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1381 return (1); 1382} 1383 1384static int 1385bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1386{ 1387 struct bwn_mac *mac = sc->sc_curmac; 1388 int error; 1389 1390 BWN_ASSERT_LOCKED(sc); 1391 1392 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1393 m_freem(m); 1394 return (ENXIO); 1395 } 1396 1397 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1398 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1399 if (error) { 1400 m_freem(m); 1401 return (error); 1402 } 1403 return (0); 1404} 1405 1406static int 1407bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1408{ 1409 struct bwn_pio_txpkt *tp; 1410 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1411 struct bwn_softc *sc = mac->mac_sc; 1412 struct bwn_txhdr txhdr; 1413 struct mbuf *m_new; 1414 uint32_t ctl32; 1415 int error; 1416 uint16_t ctl16; 1417 1418 BWN_ASSERT_LOCKED(sc); 1419 1420 /* XXX TODO send packets after DTIM */ 1421 1422 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1423 tp = TAILQ_FIRST(&tq->tq_pktlist); 1424 tp->tp_ni = ni; 1425 tp->tp_m = m; 1426 1427 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1428 if (error) { 1429 device_printf(sc->sc_dev, "tx fail\n"); 1430 return (error); 1431 } 1432 1433 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1434 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1435 tq->tq_free--; 1436 1437 if (mac->mac_sd->sd_id.sd_rev >= 8) { 1438 /* 1439 * XXX please removes m_defrag(9) 1440 */ 1441 m_new = m_defrag(m, M_DONTWAIT); 1442 if (m_new == NULL) { 1443 device_printf(sc->sc_dev, 1444 "%s: can't defrag TX buffer\n", 1445 __func__); 1446 return (ENOBUFS); 1447 } 1448 if (m_new->m_next != NULL) 1449 device_printf(sc->sc_dev, 1450 "TODO: fragmented packets for PIO\n"); 1451 tp->tp_m = m_new; 1452 1453 /* send HEADER */ 1454 ctl32 = bwn_pio_write_multi_4(mac, tq, 1455 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1456 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1457 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1458 /* send BODY */ 1459 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1460 mtod(m_new, const void *), m_new->m_pkthdr.len); 1461 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1462 ctl32 | BWN_PIO8_TXCTL_EOF); 1463 } else { 1464 ctl16 = bwn_pio_write_multi_2(mac, tq, 1465 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1466 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1467 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1468 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1469 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1470 ctl16 | BWN_PIO_TXCTL_EOF); 1471 } 1472 1473 return (0); 1474} 1475 1476static struct bwn_pio_txqueue * 1477bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1478{ 1479 1480 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1481 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1482 1483 switch (prio) { 1484 case 0: 1485 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1486 case 1: 1487 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1488 case 2: 1489 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1490 case 3: 1491 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1492 } 1493 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1494 return (NULL); 1495} 1496 1497static int 1498bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1499{ 1500#define BWN_GET_TXHDRCACHE(slot) \ 1501 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1502 struct bwn_dma *dma = &mac->mac_method.dma; 1503 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1504 struct bwn_dmadesc_generic *desc; 1505 struct bwn_dmadesc_meta *mt; 1506 struct bwn_softc *sc = mac->mac_sc; 1507 struct ifnet *ifp = sc->sc_ifp; 1508 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1509 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1510 1511 BWN_ASSERT_LOCKED(sc); 1512 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1513 1514 /* XXX send after DTIM */ 1515 1516 slot = bwn_dma_getslot(dr); 1517 dr->getdesc(dr, slot, &desc, &mt); 1518 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1519 ("%s:%d: fail", __func__, __LINE__)); 1520 1521 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1522 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1523 BWN_DMA_COOKIE(dr, slot)); 1524 if (error) 1525 goto fail; 1526 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1527 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1528 &mt->mt_paddr, BUS_DMA_NOWAIT); 1529 if (error) { 1530 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1531 __func__, error); 1532 goto fail; 1533 } 1534 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1535 BUS_DMASYNC_PREWRITE); 1536 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1537 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1538 BUS_DMASYNC_PREWRITE); 1539 1540 slot = bwn_dma_getslot(dr); 1541 dr->getdesc(dr, slot, &desc, &mt); 1542 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1543 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1544 mt->mt_m = m; 1545 mt->mt_ni = ni; 1546 1547 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1548 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1549 if (error && error != EFBIG) { 1550 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1551 __func__, error); 1552 goto fail; 1553 } 1554 if (error) { /* error == EFBIG */ 1555 struct mbuf *m_new; 1556 1557 m_new = m_defrag(m, M_DONTWAIT); 1558 if (m_new == NULL) { 1559 if_printf(ifp, "%s: can't defrag TX buffer\n", 1560 __func__); 1561 error = ENOBUFS; 1562 goto fail; 1563 } else { 1564 m = m_new; 1565 } 1566 1567 mt->mt_m = m; 1568 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1569 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1570 if (error) { 1571 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1572 __func__, error); 1573 goto fail; 1574 } 1575 } 1576 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1577 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1578 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1579 BUS_DMASYNC_PREWRITE); 1580 1581 /* XXX send after DTIM */ 1582 1583 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1584 return (0); 1585fail: 1586 dr->dr_curslot = backup[0]; 1587 dr->dr_usedslot = backup[1]; 1588 return (error); 1589#undef BWN_GET_TXHDRCACHE 1590} 1591 1592static void 1593bwn_watchdog(void *arg) 1594{ 1595 struct bwn_softc *sc = arg; 1596 struct ifnet *ifp = sc->sc_ifp; 1597 1598 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1599 if_printf(ifp, "device timeout\n"); 1600 ifp->if_oerrors++; 1601 } 1602 callout_schedule(&sc->sc_watchdog_ch, hz); 1603} 1604 1605static int 1606bwn_attach_core(struct bwn_mac *mac) 1607{ 1608 struct bwn_softc *sc = mac->mac_sc; 1609 struct siba_dev_softc *sd = mac->mac_sd; 1610 struct siba_softc *siba = sd->sd_bus; 1611 int error, have_bg = 0, have_a = 0; 1612 uint32_t high; 1613 1614 KASSERT(sd->sd_id.sd_rev >= 5, 1615 ("unsupported revision %d", sd->sd_id.sd_rev)); 1616 1617 siba_powerup(siba, 0); 1618 1619 high = siba_read_4(sd, SIBA_TGSHIGH); 1620 bwn_reset_core(mac, 1621 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1622 error = bwn_phy_getinfo(mac, high); 1623 if (error) 1624 goto fail; 1625 1626 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1627 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1628 if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 && 1629 siba->siba_pci_did != 0x4324) { 1630 have_a = have_bg = 0; 1631 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1632 have_a = 1; 1633 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1634 mac->mac_phy.type == BWN_PHYTYPE_N || 1635 mac->mac_phy.type == BWN_PHYTYPE_LP) 1636 have_bg = 1; 1637 else 1638 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1639 mac->mac_phy.type)); 1640 } 1641 /* XXX turns off PHY A because it's not supported */ 1642 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1643 mac->mac_phy.type != BWN_PHYTYPE_N) { 1644 have_a = 0; 1645 have_bg = 1; 1646 } 1647 1648 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1649 mac->mac_phy.attach = bwn_phy_g_attach; 1650 mac->mac_phy.detach = bwn_phy_g_detach; 1651 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1652 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1653 mac->mac_phy.init = bwn_phy_g_init; 1654 mac->mac_phy.exit = bwn_phy_g_exit; 1655 mac->mac_phy.phy_read = bwn_phy_g_read; 1656 mac->mac_phy.phy_write = bwn_phy_g_write; 1657 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1658 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1659 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1660 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1661 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1662 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1663 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1664 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1665 mac->mac_phy.set_im = bwn_phy_g_im; 1666 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1667 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1668 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1669 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1670 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1671 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1672 mac->mac_phy.init = bwn_phy_lp_init; 1673 mac->mac_phy.phy_read = bwn_phy_lp_read; 1674 mac->mac_phy.phy_write = bwn_phy_lp_write; 1675 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1676 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1677 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1678 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1679 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1680 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1681 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1682 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1683 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1684 } else { 1685 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1686 mac->mac_phy.type); 1687 error = ENXIO; 1688 goto fail; 1689 } 1690 1691 mac->mac_phy.gmode = have_bg; 1692 if (mac->mac_phy.attach != NULL) { 1693 error = mac->mac_phy.attach(mac); 1694 if (error) { 1695 device_printf(sc->sc_dev, "failed\n"); 1696 goto fail; 1697 } 1698 } 1699 1700 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1701 1702 error = bwn_chiptest(mac); 1703 if (error) 1704 goto fail; 1705 error = bwn_setup_channels(mac, have_bg, have_a); 1706 if (error) { 1707 device_printf(sc->sc_dev, "failed to setup channels\n"); 1708 goto fail; 1709 } 1710 1711 if (sc->sc_curmac == NULL) 1712 sc->sc_curmac = mac; 1713 1714 error = bwn_dma_attach(mac); 1715 if (error != 0) { 1716 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1717 goto fail; 1718 } 1719 1720 mac->mac_phy.switch_analog(mac, 0); 1721 1722 siba_dev_down(sd, 0); 1723fail: 1724 siba_powerdown(siba); 1725 return (error); 1726} 1727 1728static void 1729bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1730{ 1731 struct siba_dev_softc *sd = mac->mac_sd; 1732 uint32_t low, ctl; 1733 1734 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1735 1736 siba_dev_up(sd, flags); 1737 DELAY(2000); 1738 1739 low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1740 ~BWN_TGSLOW_PHYRESET; 1741 siba_write_4(sd, SIBA_TGSLOW, low); 1742 siba_read_4(sd, SIBA_TGSLOW); 1743 DELAY(1000); 1744 siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1745 siba_read_4(sd, SIBA_TGSLOW); 1746 DELAY(1000); 1747 1748 if (mac->mac_phy.switch_analog != NULL) 1749 mac->mac_phy.switch_analog(mac, 1); 1750 1751 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1752 if (flags & BWN_TGSLOW_SUPPORT_G) 1753 ctl |= BWN_MACCTL_GMODE; 1754 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1755} 1756 1757static int 1758bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1759{ 1760 struct bwn_phy *phy = &mac->mac_phy; 1761 struct bwn_softc *sc = mac->mac_sc; 1762 struct siba_dev_softc *sd = mac->mac_sd; 1763 struct siba_softc *siba = sd->sd_bus; 1764 uint32_t tmp; 1765 1766 /* PHY */ 1767 tmp = BWN_READ_2(mac, BWN_PHYVER); 1768 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1769 phy->rf_on = 1; 1770 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1771 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1772 phy->rev = (tmp & BWN_PHYVER_VERSION); 1773 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1774 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1775 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1776 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1777 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1778 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1779 goto unsupphy; 1780 1781 /* RADIO */ 1782 if (siba->siba_chipid == 0x4317) { 1783 if (siba->siba_chiprev == 0) 1784 tmp = 0x3205017f; 1785 else if (siba->siba_chiprev == 1) 1786 tmp = 0x4205017f; 1787 else 1788 tmp = 0x5205017f; 1789 } else { 1790 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1791 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1792 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1793 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1794 } 1795 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1796 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1797 phy->rf_manuf = (tmp & 0x00000fff); 1798 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1799 goto unsupradio; 1800 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1801 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1802 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1803 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1804 (phy->type == BWN_PHYTYPE_N && 1805 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1806 (phy->type == BWN_PHYTYPE_LP && 1807 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1808 goto unsupradio; 1809 1810 return (0); 1811unsupphy: 1812 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1813 "analog %#x)\n", 1814 phy->type, phy->rev, phy->analog); 1815 return (ENXIO); 1816unsupradio: 1817 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1818 "rev %#x)\n", 1819 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1820 return (ENXIO); 1821} 1822 1823static int 1824bwn_chiptest(struct bwn_mac *mac) 1825{ 1826#define TESTVAL0 0x55aaaa55 1827#define TESTVAL1 0xaa5555aa 1828 struct bwn_softc *sc = mac->mac_sc; 1829 struct siba_dev_softc *sd = mac->mac_sd; 1830 uint32_t v, backup; 1831 1832 BWN_LOCK(sc); 1833 1834 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1835 1836 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1837 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1838 goto error; 1839 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1840 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1841 goto error; 1842 1843 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1844 1845 if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) { 1846 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1847 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1848 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1849 goto error; 1850 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1851 goto error; 1852 } 1853 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1854 1855 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1856 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1857 goto error; 1858 1859 BWN_UNLOCK(sc); 1860 return (0); 1861error: 1862 BWN_UNLOCK(sc); 1863 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1864 return (ENODEV); 1865} 1866 1867#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1868#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1869 1870static int 1871bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1872{ 1873 struct bwn_softc *sc = mac->mac_sc; 1874 struct ifnet *ifp = sc->sc_ifp; 1875 struct ieee80211com *ic = ifp->if_l2com; 1876 1877 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1878 ic->ic_nchans = 0; 1879 1880 if (have_bg) 1881 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1882 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1883 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1884 if (have_a) 1885 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1886 &ic->ic_nchans, &bwn_chantable_n, 1887 IEEE80211_CHAN_HTA); 1888 } else { 1889 if (have_a) 1890 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1891 &ic->ic_nchans, &bwn_chantable_a, 1892 IEEE80211_CHAN_A); 1893 } 1894 1895 mac->mac_phy.supports_2ghz = have_bg; 1896 mac->mac_phy.supports_5ghz = have_a; 1897 1898 return (ic->ic_nchans == 0 ? ENXIO : 0); 1899} 1900 1901static uint32_t 1902bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1903{ 1904 uint32_t ret; 1905 1906 BWN_ASSERT_LOCKED(mac->mac_sc); 1907 1908 if (way == BWN_SHARED) { 1909 KASSERT((offset & 0x0001) == 0, 1910 ("%s:%d warn", __func__, __LINE__)); 1911 if (offset & 0x0003) { 1912 bwn_shm_ctlword(mac, way, offset >> 2); 1913 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1914 ret <<= 16; 1915 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1916 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1917 goto out; 1918 } 1919 offset >>= 2; 1920 } 1921 bwn_shm_ctlword(mac, way, offset); 1922 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1923out: 1924 return (ret); 1925} 1926 1927static uint16_t 1928bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1929{ 1930 uint16_t ret; 1931 1932 BWN_ASSERT_LOCKED(mac->mac_sc); 1933 1934 if (way == BWN_SHARED) { 1935 KASSERT((offset & 0x0001) == 0, 1936 ("%s:%d warn", __func__, __LINE__)); 1937 if (offset & 0x0003) { 1938 bwn_shm_ctlword(mac, way, offset >> 2); 1939 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1940 goto out; 1941 } 1942 offset >>= 2; 1943 } 1944 bwn_shm_ctlword(mac, way, offset); 1945 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1946out: 1947 1948 return (ret); 1949} 1950 1951static void 1952bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1953 uint16_t offset) 1954{ 1955 uint32_t control; 1956 1957 control = way; 1958 control <<= 16; 1959 control |= offset; 1960 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1961} 1962 1963static void 1964bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1965 uint32_t value) 1966{ 1967 BWN_ASSERT_LOCKED(mac->mac_sc); 1968 1969 if (way == BWN_SHARED) { 1970 KASSERT((offset & 0x0001) == 0, 1971 ("%s:%d warn", __func__, __LINE__)); 1972 if (offset & 0x0003) { 1973 bwn_shm_ctlword(mac, way, offset >> 2); 1974 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1975 (value >> 16) & 0xffff); 1976 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1977 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1978 return; 1979 } 1980 offset >>= 2; 1981 } 1982 bwn_shm_ctlword(mac, way, offset); 1983 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1984} 1985 1986static void 1987bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1988 uint16_t value) 1989{ 1990 BWN_ASSERT_LOCKED(mac->mac_sc); 1991 1992 if (way == BWN_SHARED) { 1993 KASSERT((offset & 0x0001) == 0, 1994 ("%s:%d warn", __func__, __LINE__)); 1995 if (offset & 0x0003) { 1996 bwn_shm_ctlword(mac, way, offset >> 2); 1997 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1998 return; 1999 } 2000 offset >>= 2; 2001 } 2002 bwn_shm_ctlword(mac, way, offset); 2003 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 2004} 2005 2006static void 2007bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 2008 int txpow) 2009{ 2010 2011 c->ic_freq = freq; 2012 c->ic_flags = flags; 2013 c->ic_ieee = ieee; 2014 c->ic_minpower = 0; 2015 c->ic_maxpower = 2 * txpow; 2016 c->ic_maxregpower = txpow; 2017} 2018 2019static void 2020bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2021 const struct bwn_channelinfo *ci, int flags) 2022{ 2023 struct ieee80211_channel *c; 2024 int i; 2025 2026 c = &chans[*nchans]; 2027 2028 for (i = 0; i < ci->nchannels; i++) { 2029 const struct bwn_channel *hc; 2030 2031 hc = &ci->channels[i]; 2032 if (*nchans >= maxchans) 2033 break; 2034 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2035 c++, (*nchans)++; 2036 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2037 /* g channel have a separate b-only entry */ 2038 if (*nchans >= maxchans) 2039 break; 2040 c[0] = c[-1]; 2041 c[-1].ic_flags = IEEE80211_CHAN_B; 2042 c++, (*nchans)++; 2043 } 2044 if (flags == IEEE80211_CHAN_HTG) { 2045 /* HT g channel have a separate g-only entry */ 2046 if (*nchans >= maxchans) 2047 break; 2048 c[-1].ic_flags = IEEE80211_CHAN_G; 2049 c[0] = c[-1]; 2050 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2051 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2052 c++, (*nchans)++; 2053 } 2054 if (flags == IEEE80211_CHAN_HTA) { 2055 /* HT a channel have a separate a-only entry */ 2056 if (*nchans >= maxchans) 2057 break; 2058 c[-1].ic_flags = IEEE80211_CHAN_A; 2059 c[0] = c[-1]; 2060 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2061 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2062 c++, (*nchans)++; 2063 } 2064 } 2065} 2066 2067static int 2068bwn_phy_g_attach(struct bwn_mac *mac) 2069{ 2070 struct bwn_softc *sc = mac->mac_sc; 2071 struct bwn_phy *phy = &mac->mac_phy; 2072 struct bwn_phy_g *pg = &phy->phy_g; 2073 struct siba_dev_softc *sd = mac->mac_sd; 2074 struct siba_sprom *sprom = &sd->sd_bus->siba_sprom; 2075 unsigned int i; 2076 int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1), 2077 pab2 = (int16_t)(sprom->pa0b2); 2078 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2079 int8_t bg = (int8_t)sprom->tssi_bg; 2080 2081 if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050)) 2082 device_printf(sc->sc_dev, "not supported anymore\n"); 2083 2084 pg->pg_flags = 0; 2085 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2086 pab2 == -1) { 2087 pg->pg_idletssi = 52; 2088 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2089 return (0); 2090 } 2091 2092 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2093 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2094 if (pg->pg_tssi2dbm == NULL) { 2095 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2096 return (ENOMEM); 2097 } 2098 for (i = 0; i < 64; i++) { 2099 int32_t m1, m2, f, q, delta; 2100 int8_t j = 0; 2101 2102 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2103 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2104 f = 256; 2105 2106 do { 2107 if (j > 15) { 2108 device_printf(sc->sc_dev, 2109 "failed to generate tssi2dBm\n"); 2110 free(pg->pg_tssi2dbm, M_DEVBUF); 2111 return (ENOMEM); 2112 } 2113 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2114 f, 2048); 2115 delta = abs(q - f); 2116 f = q; 2117 j++; 2118 } while (delta >= 2); 2119 2120 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2121 128); 2122 } 2123 2124 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2125 return (0); 2126} 2127 2128static void 2129bwn_phy_g_detach(struct bwn_mac *mac) 2130{ 2131 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2132 2133 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2134 free(pg->pg_tssi2dbm, M_DEVBUF); 2135 pg->pg_tssi2dbm = NULL; 2136 } 2137 pg->pg_flags = 0; 2138} 2139 2140static void 2141bwn_phy_g_init_pre(struct bwn_mac *mac) 2142{ 2143 struct bwn_phy *phy = &mac->mac_phy; 2144 struct bwn_phy_g *pg = &phy->phy_g; 2145 void *tssi2dbm; 2146 int idletssi; 2147 unsigned int i; 2148 2149 tssi2dbm = pg->pg_tssi2dbm; 2150 idletssi = pg->pg_idletssi; 2151 2152 memset(pg, 0, sizeof(*pg)); 2153 2154 pg->pg_tssi2dbm = tssi2dbm; 2155 pg->pg_idletssi = idletssi; 2156 2157 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2158 2159 for (i = 0; i < N(pg->pg_nrssi); i++) 2160 pg->pg_nrssi[i] = -1000; 2161 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2162 pg->pg_nrssi_lt[i] = i; 2163 pg->pg_lofcal = 0xffff; 2164 pg->pg_initval = 0xffff; 2165 pg->pg_immode = BWN_IMMODE_NONE; 2166 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2167 pg->pg_avgtssi = 0xff; 2168 2169 pg->pg_loctl.tx_bias = 0xff; 2170 TAILQ_INIT(&pg->pg_loctl.calib_list); 2171} 2172 2173static int 2174bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2175{ 2176 struct bwn_phy *phy = &mac->mac_phy; 2177 struct bwn_phy_g *pg = &phy->phy_g; 2178 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2179 struct siba_softc *bus = mac->mac_sd->sd_bus; 2180 static const struct bwn_rfatt rfatt0[] = { 2181 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2182 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2183 { 3, 1 }, { 4, 1 } 2184 }; 2185 static const struct bwn_rfatt rfatt1[] = { 2186 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2187 { 14, 1 } 2188 }; 2189 static const struct bwn_rfatt rfatt2[] = { 2190 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2191 { 9, 1 } 2192 }; 2193 static const struct bwn_bbatt bbatt_0[] = { 2194 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2195 }; 2196 2197 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2198 2199 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2200 pg->pg_bbatt.att = 0; 2201 else 2202 pg->pg_bbatt.att = 2; 2203 2204 /* prepare Radio Attenuation */ 2205 pg->pg_rfatt.padmix = 0; 2206 2207 if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 2208 bus->siba_board_type == SIBA_BOARD_BCM4309G) { 2209 if (bus->siba_board_rev < 0x43) { 2210 pg->pg_rfatt.att = 2; 2211 goto done; 2212 } else if (bus->siba_board_rev < 0x51) { 2213 pg->pg_rfatt.att = 3; 2214 goto done; 2215 } 2216 } 2217 2218 if (phy->type == BWN_PHYTYPE_A) { 2219 pg->pg_rfatt.att = 0x60; 2220 goto done; 2221 } 2222 2223 switch (phy->rf_ver) { 2224 case 0x2050: 2225 switch (phy->rf_rev) { 2226 case 0: 2227 pg->pg_rfatt.att = 5; 2228 goto done; 2229 case 1: 2230 if (phy->type == BWN_PHYTYPE_G) { 2231 if (bus->siba_board_vendor == 2232 SIBA_BOARDVENDOR_BCM && 2233 bus->siba_board_type == 2234 SIBA_BOARD_BCM4309G && 2235 bus->siba_board_rev >= 30) 2236 pg->pg_rfatt.att = 3; 2237 else if (bus->siba_board_vendor == 2238 SIBA_BOARDVENDOR_BCM && 2239 bus->siba_board_type == SIBA_BOARD_BU4306) 2240 pg->pg_rfatt.att = 3; 2241 else 2242 pg->pg_rfatt.att = 1; 2243 } else { 2244 if (bus->siba_board_vendor == 2245 SIBA_BOARDVENDOR_BCM && 2246 bus->siba_board_type == 2247 SIBA_BOARD_BCM4309G && 2248 bus->siba_board_rev >= 30) 2249 pg->pg_rfatt.att = 7; 2250 else 2251 pg->pg_rfatt.att = 6; 2252 } 2253 goto done; 2254 case 2: 2255 if (phy->type == BWN_PHYTYPE_G) { 2256 if (bus->siba_board_vendor == 2257 SIBA_BOARDVENDOR_BCM && 2258 bus->siba_board_type == 2259 SIBA_BOARD_BCM4309G && 2260 bus->siba_board_rev >= 30) 2261 pg->pg_rfatt.att = 3; 2262 else if (bus->siba_board_vendor == 2263 SIBA_BOARDVENDOR_BCM && 2264 bus->siba_board_type == SIBA_BOARD_BU4306) 2265 pg->pg_rfatt.att = 5; 2266 else if (bus->siba_chipid == 0x4320) 2267 pg->pg_rfatt.att = 4; 2268 else 2269 pg->pg_rfatt.att = 3; 2270 } else 2271 pg->pg_rfatt.att = 6; 2272 goto done; 2273 case 3: 2274 pg->pg_rfatt.att = 5; 2275 goto done; 2276 case 4: 2277 case 5: 2278 pg->pg_rfatt.att = 1; 2279 goto done; 2280 case 6: 2281 case 7: 2282 pg->pg_rfatt.att = 5; 2283 goto done; 2284 case 8: 2285 pg->pg_rfatt.att = 0xa; 2286 pg->pg_rfatt.padmix = 1; 2287 goto done; 2288 case 9: 2289 default: 2290 pg->pg_rfatt.att = 5; 2291 goto done; 2292 } 2293 break; 2294 case 0x2053: 2295 switch (phy->rf_rev) { 2296 case 1: 2297 pg->pg_rfatt.att = 6; 2298 goto done; 2299 } 2300 break; 2301 } 2302 pg->pg_rfatt.att = 5; 2303done: 2304 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2305 2306 if (!bwn_has_hwpctl(mac)) { 2307 lo->rfatt.array = rfatt0; 2308 lo->rfatt.len = N(rfatt0); 2309 lo->rfatt.min = 0; 2310 lo->rfatt.max = 9; 2311 goto genbbatt; 2312 } 2313 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2314 lo->rfatt.array = rfatt1; 2315 lo->rfatt.len = N(rfatt1); 2316 lo->rfatt.min = 0; 2317 lo->rfatt.max = 14; 2318 goto genbbatt; 2319 } 2320 lo->rfatt.array = rfatt2; 2321 lo->rfatt.len = N(rfatt2); 2322 lo->rfatt.min = 0; 2323 lo->rfatt.max = 9; 2324genbbatt: 2325 lo->bbatt.array = bbatt_0; 2326 lo->bbatt.len = N(bbatt_0); 2327 lo->bbatt.min = 0; 2328 lo->bbatt.max = 8; 2329 2330 BWN_READ_4(mac, BWN_MACCTL); 2331 if (phy->rev == 1) { 2332 phy->gmode = 0; 2333 bwn_reset_core(mac, 0); 2334 bwn_phy_g_init_sub(mac); 2335 phy->gmode = 1; 2336 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2337 } 2338 return (0); 2339} 2340 2341static uint16_t 2342bwn_phy_g_txctl(struct bwn_mac *mac) 2343{ 2344 struct bwn_phy *phy = &mac->mac_phy; 2345 2346 if (phy->rf_ver != 0x2050) 2347 return (0); 2348 if (phy->rf_rev == 1) 2349 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2350 if (phy->rf_rev < 6) 2351 return (BWN_TXCTL_PA2DB); 2352 if (phy->rf_rev == 8) 2353 return (BWN_TXCTL_TXMIX); 2354 return (0); 2355} 2356 2357static int 2358bwn_phy_g_init(struct bwn_mac *mac) 2359{ 2360 2361 bwn_phy_g_init_sub(mac); 2362 return (0); 2363} 2364 2365static void 2366bwn_phy_g_exit(struct bwn_mac *mac) 2367{ 2368 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2369 struct bwn_lo_calib *cal, *tmp; 2370 2371 if (lo == NULL) 2372 return; 2373 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2374 TAILQ_REMOVE(&lo->calib_list, cal, list); 2375 free(cal, M_DEVBUF); 2376 } 2377} 2378 2379static uint16_t 2380bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2381{ 2382 2383 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2384 return (BWN_READ_2(mac, BWN_PHYDATA)); 2385} 2386 2387static void 2388bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2389{ 2390 2391 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2392 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2393} 2394 2395static uint16_t 2396bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2397{ 2398 2399 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2400 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2401 return (BWN_READ_2(mac, BWN_RFDATALO)); 2402} 2403 2404static void 2405bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2406{ 2407 2408 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2409 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2410 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2411} 2412 2413static int 2414bwn_phy_g_hwpctl(struct bwn_mac *mac) 2415{ 2416 2417 return (mac->mac_phy.rev >= 6); 2418} 2419 2420static void 2421bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2422{ 2423 struct bwn_phy *phy = &mac->mac_phy; 2424 struct bwn_phy_g *pg = &phy->phy_g; 2425 unsigned int channel; 2426 uint16_t rfover, rfoverval; 2427 2428 if (on) { 2429 if (phy->rf_on) 2430 return; 2431 2432 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2433 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2434 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2435 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2436 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2437 pg->pg_radioctx_over); 2438 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2439 pg->pg_radioctx_overval); 2440 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2441 } 2442 channel = phy->chan; 2443 bwn_phy_g_switch_chan(mac, 6, 1); 2444 bwn_phy_g_switch_chan(mac, channel, 0); 2445 return; 2446 } 2447 2448 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2449 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2450 pg->pg_radioctx_over = rfover; 2451 pg->pg_radioctx_overval = rfoverval; 2452 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2453 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2454 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2455} 2456 2457static int 2458bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2459{ 2460 2461 if ((newchan < 1) || (newchan > 14)) 2462 return (EINVAL); 2463 bwn_phy_g_switch_chan(mac, newchan, 0); 2464 2465 return (0); 2466} 2467 2468static uint32_t 2469bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2470{ 2471 2472 return (1); 2473} 2474 2475static void 2476bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2477{ 2478 struct bwn_phy *phy = &mac->mac_phy; 2479 uint64_t hf; 2480 int autodiv = 0; 2481 uint16_t tmp; 2482 2483 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2484 autodiv = 1; 2485 2486 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2487 bwn_hf_write(mac, hf); 2488 2489 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2490 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2491 ((autodiv ? BWN_ANTAUTO1 : antenna) 2492 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2493 2494 if (autodiv) { 2495 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2496 if (antenna == BWN_ANTAUTO1) 2497 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2498 else 2499 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2500 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2501 } 2502 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2503 if (autodiv) 2504 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2505 else 2506 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2507 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2508 if (phy->rev >= 2) { 2509 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2510 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2511 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2512 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2513 0x15); 2514 if (phy->rev == 2) 2515 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2516 else 2517 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2518 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2519 8); 2520 } 2521 if (phy->rev >= 6) 2522 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2523 2524 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2525 bwn_hf_write(mac, hf); 2526} 2527 2528static int 2529bwn_phy_g_im(struct bwn_mac *mac, int mode) 2530{ 2531 struct bwn_phy *phy = &mac->mac_phy; 2532 struct bwn_phy_g *pg = &phy->phy_g; 2533 2534 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2535 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2536 2537 if (phy->rev == 0 || !phy->gmode) 2538 return (ENODEV); 2539 2540 pg->pg_aci_wlan_automatic = 0; 2541 return (0); 2542} 2543 2544static int 2545bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2546{ 2547 struct bwn_phy *phy = &mac->mac_phy; 2548 struct bwn_phy_g *pg = &phy->phy_g; 2549 struct bwn_softc *sc = mac->mac_sc; 2550 struct siba_softc *siba = mac->mac_sd->sd_bus; 2551 unsigned int tssi; 2552 int cck, ofdm; 2553 int power; 2554 int rfatt, bbatt; 2555 unsigned int max; 2556 2557 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2558 2559 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2560 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2561 if (cck < 0 && ofdm < 0) { 2562 if (ignore_tssi == 0) 2563 return (BWN_TXPWR_RES_DONE); 2564 cck = 0; 2565 ofdm = 0; 2566 } 2567 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2568 if (pg->pg_avgtssi != 0xff) 2569 tssi = (tssi + pg->pg_avgtssi) / 2; 2570 pg->pg_avgtssi = tssi; 2571 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2572 2573 max = siba->siba_sprom.maxpwr_bg; 2574 if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL) 2575 max -= 3; 2576 if (max >= 120) { 2577 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2578 siba->siba_sprom.maxpwr_bg = max = 80; 2579 } 2580 2581 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2582 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2583 tssi, 0x00), 0x3f)]); 2584 if (power == 0) 2585 return (BWN_TXPWR_RES_DONE); 2586 2587 rfatt = -((power + 7) / 8); 2588 bbatt = (-(power / 2)) - (4 * rfatt); 2589 if ((rfatt == 0) && (bbatt == 0)) 2590 return (BWN_TXPWR_RES_DONE); 2591 pg->pg_bbatt_delta = bbatt; 2592 pg->pg_rfatt_delta = rfatt; 2593 return (BWN_TXPWR_RES_NEED_ADJUST); 2594} 2595 2596static void 2597bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2598{ 2599 struct bwn_phy *phy = &mac->mac_phy; 2600 struct bwn_phy_g *pg = &phy->phy_g; 2601 struct bwn_softc *sc = mac->mac_sc; 2602 int rfatt, bbatt; 2603 uint8_t txctl; 2604 2605 bwn_mac_suspend(mac); 2606 2607 BWN_ASSERT_LOCKED(sc); 2608 2609 bbatt = pg->pg_bbatt.att; 2610 bbatt += pg->pg_bbatt_delta; 2611 rfatt = pg->pg_rfatt.att; 2612 rfatt += pg->pg_rfatt_delta; 2613 2614 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2615 txctl = pg->pg_txctl; 2616 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2617 if (rfatt <= 1) { 2618 if (txctl == 0) { 2619 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2620 rfatt += 2; 2621 bbatt += 2; 2622 } else if (mac->mac_sd->sd_bus->siba_sprom. 2623 bf_lo & 2624 BWN_BFL_PACTRL) { 2625 bbatt += 4 * (rfatt - 2); 2626 rfatt = 2; 2627 } 2628 } else if (rfatt > 4 && txctl) { 2629 txctl = 0; 2630 if (bbatt < 3) { 2631 rfatt -= 3; 2632 bbatt += 2; 2633 } else { 2634 rfatt -= 2; 2635 bbatt -= 2; 2636 } 2637 } 2638 } 2639 pg->pg_txctl = txctl; 2640 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2641 pg->pg_rfatt.att = rfatt; 2642 pg->pg_bbatt.att = bbatt; 2643 2644 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2645 2646 bwn_phy_lock(mac); 2647 bwn_rf_lock(mac); 2648 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2649 pg->pg_txctl); 2650 bwn_rf_unlock(mac); 2651 bwn_phy_unlock(mac); 2652 2653 bwn_mac_enable(mac); 2654} 2655 2656static void 2657bwn_phy_g_task_15s(struct bwn_mac *mac) 2658{ 2659 struct bwn_phy *phy = &mac->mac_phy; 2660 struct bwn_phy_g *pg = &phy->phy_g; 2661 struct bwn_softc *sc = mac->mac_sc; 2662 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2663 unsigned long expire, now; 2664 struct bwn_lo_calib *cal, *tmp; 2665 uint8_t expired = 0; 2666 2667 bwn_mac_suspend(mac); 2668 2669 if (lo == NULL) 2670 goto fail; 2671 2672 BWN_GETTIME(now); 2673 if (bwn_has_hwpctl(mac)) { 2674 expire = now - BWN_LO_PWRVEC_EXPIRE; 2675 if (time_before(lo->pwr_vec_read_time, expire)) { 2676 bwn_lo_get_powervector(mac); 2677 bwn_phy_g_dc_lookup_init(mac, 0); 2678 } 2679 goto fail; 2680 } 2681 2682 expire = now - BWN_LO_CALIB_EXPIRE; 2683 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2684 if (!time_before(cal->calib_time, expire)) 2685 continue; 2686 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2687 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2688 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2689 expired = 1; 2690 } 2691 2692 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2693 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2694 cal->ctl.i, cal->ctl.q); 2695 2696 TAILQ_REMOVE(&lo->calib_list, cal, list); 2697 free(cal, M_DEVBUF); 2698 } 2699 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2700 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2701 &pg->pg_rfatt); 2702 if (cal == NULL) { 2703 device_printf(sc->sc_dev, 2704 "failed to recalibrate LO\n"); 2705 goto fail; 2706 } 2707 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2708 bwn_lo_write(mac, &cal->ctl); 2709 } 2710 2711fail: 2712 bwn_mac_enable(mac); 2713} 2714 2715static void 2716bwn_phy_g_task_60s(struct bwn_mac *mac) 2717{ 2718 struct bwn_phy *phy = &mac->mac_phy; 2719 uint8_t old = phy->chan; 2720 2721 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) 2722 return; 2723 2724 bwn_mac_suspend(mac); 2725 bwn_nrssi_slope_11g(mac); 2726 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2727 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2728 bwn_switch_channel(mac, old); 2729 } 2730 bwn_mac_enable(mac); 2731} 2732 2733static void 2734bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2735{ 2736 2737 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2738} 2739 2740static int 2741bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2742 const struct ieee80211_bpf_params *params) 2743{ 2744 struct ieee80211com *ic = ni->ni_ic; 2745 struct ifnet *ifp = ic->ic_ifp; 2746 struct bwn_softc *sc = ifp->if_softc; 2747 struct bwn_mac *mac = sc->sc_curmac; 2748 2749 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2750 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2751 ieee80211_free_node(ni); 2752 m_freem(m); 2753 return (ENETDOWN); 2754 } 2755 2756 BWN_LOCK(sc); 2757 if (bwn_tx_isfull(sc, m)) { 2758 ieee80211_free_node(ni); 2759 m_freem(m); 2760 ifp->if_oerrors++; 2761 BWN_UNLOCK(sc); 2762 return (ENOBUFS); 2763 } 2764 2765 if (bwn_tx_start(sc, ni, m) != 0) { 2766 if (ni != NULL) 2767 ieee80211_free_node(ni); 2768 ifp->if_oerrors++; 2769 } 2770 sc->sc_watchdog_timer = 5; 2771 BWN_UNLOCK(sc); 2772 return (0); 2773} 2774 2775/* 2776 * Setup driver-specific state for a newly associated node. 2777 * Note that we're called also on a re-associate, the isnew 2778 * param tells us if this is the first time or not. 2779 */ 2780static void 2781bwn_newassoc(struct ieee80211_node *ni, int isnew) 2782{ 2783 struct ieee80211vap *vap = ni->ni_vap; 2784 2785 ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr, 2786 &BWN_NODE(ni)->bn_amn, ni); 2787} 2788 2789/* 2790 * Callback from the 802.11 layer to update the slot time 2791 * based on the current setting. We use it to notify the 2792 * firmware of ERP changes and the f/w takes care of things 2793 * like slot time and preamble. 2794 */ 2795static void 2796bwn_updateslot(struct ifnet *ifp) 2797{ 2798 struct bwn_softc *sc = ifp->if_softc; 2799 struct ieee80211com *ic = ifp->if_l2com; 2800 struct bwn_mac *mac; 2801 2802 BWN_LOCK(sc); 2803 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2804 mac = (struct bwn_mac *)sc->sc_curmac; 2805 bwn_set_slot_time(mac, 2806 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2807 } 2808 BWN_UNLOCK(sc); 2809} 2810 2811/* 2812 * Callback from the 802.11 layer after a promiscuous mode change. 2813 * Note this interface does not check the operating mode as this 2814 * is an internal callback and we are expected to honor the current 2815 * state (e.g. this is used for setting the interface in promiscuous 2816 * mode when operating in hostap mode to do ACS). 2817 */ 2818static void 2819bwn_update_promisc(struct ifnet *ifp) 2820{ 2821 struct bwn_softc *sc = ifp->if_softc; 2822 struct bwn_mac *mac = sc->sc_curmac; 2823 2824 BWN_LOCK(sc); 2825 mac = sc->sc_curmac; 2826 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2827 if (ifp->if_flags & IFF_PROMISC) 2828 sc->sc_filters |= BWN_MACCTL_PROMISC; 2829 else 2830 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2831 bwn_set_opmode(mac); 2832 } 2833 BWN_UNLOCK(sc); 2834} 2835 2836/* 2837 * Callback from the 802.11 layer to update WME parameters. 2838 */ 2839static int 2840bwn_wme_update(struct ieee80211com *ic) 2841{ 2842 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2843 struct bwn_mac *mac = sc->sc_curmac; 2844 struct wmeParams *wmep; 2845 int i; 2846 2847 BWN_LOCK(sc); 2848 mac = sc->sc_curmac; 2849 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2850 bwn_mac_suspend(mac); 2851 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2852 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2853 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2854 } 2855 bwn_mac_enable(mac); 2856 } 2857 BWN_UNLOCK(sc); 2858 return (0); 2859} 2860 2861static struct ieee80211_node * 2862bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2863{ 2864 struct ieee80211com *ic = vap->iv_ic; 2865 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2866 const size_t space = sizeof(struct bwn_node); 2867 struct bwn_node *bn; 2868 2869 bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO); 2870 if (bn == NULL) { 2871 /* XXX stat+msg */ 2872 return (NULL); 2873 } 2874 DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn); 2875 return (&bn->bn_node); 2876} 2877 2878static void 2879bwn_node_cleanup(struct ieee80211_node *ni) 2880{ 2881 struct ieee80211com *ic = ni->ni_ic; 2882 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2883 2884 sc->sc_node_cleanup(ni); 2885} 2886 2887static void 2888bwn_scan_start(struct ieee80211com *ic) 2889{ 2890 struct ifnet *ifp = ic->ic_ifp; 2891 struct bwn_softc *sc = ifp->if_softc; 2892 struct bwn_mac *mac; 2893 2894 BWN_LOCK(sc); 2895 mac = sc->sc_curmac; 2896 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2897 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2898 bwn_set_opmode(mac); 2899 /* disable CFP update during scan */ 2900 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2901 } 2902 BWN_UNLOCK(sc); 2903} 2904 2905static void 2906bwn_scan_end(struct ieee80211com *ic) 2907{ 2908 struct ifnet *ifp = ic->ic_ifp; 2909 struct bwn_softc *sc = ifp->if_softc; 2910 struct bwn_mac *mac; 2911 2912 BWN_LOCK(sc); 2913 mac = sc->sc_curmac; 2914 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2915 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2916 bwn_set_opmode(mac); 2917 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2918 } 2919 BWN_UNLOCK(sc); 2920} 2921 2922static void 2923bwn_set_channel(struct ieee80211com *ic) 2924{ 2925 struct ifnet *ifp = ic->ic_ifp; 2926 struct bwn_softc *sc = ifp->if_softc; 2927 struct bwn_mac *mac = sc->sc_curmac; 2928 struct bwn_phy *phy = &mac->mac_phy; 2929 int chan, error; 2930 2931 BWN_LOCK(sc); 2932 2933 error = bwn_switch_band(sc, ic->ic_curchan); 2934 if (error) 2935 goto fail;; 2936 bwn_mac_suspend(mac); 2937 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2938 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2939 if (chan != phy->chan) 2940 bwn_switch_channel(mac, chan); 2941 2942 /* TX power level */ 2943 if (ic->ic_curchan->ic_maxpower != 0 && 2944 ic->ic_curchan->ic_maxpower != phy->txpower) { 2945 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2946 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2947 BWN_TXPWR_IGNORE_TSSI); 2948 } 2949 2950 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2951 if (phy->set_antenna) 2952 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2953 2954 if (sc->sc_rf_enabled != phy->rf_on) { 2955 if (sc->sc_rf_enabled) { 2956 bwn_rf_turnon(mac); 2957 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2958 device_printf(sc->sc_dev, 2959 "please turns on the RF switch\n"); 2960 } else 2961 bwn_rf_turnoff(mac); 2962 } 2963 2964 bwn_mac_enable(mac); 2965 2966fail: 2967 /* 2968 * Setup radio tap channel freq and flags 2969 */ 2970 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2971 htole16(ic->ic_curchan->ic_freq); 2972 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2973 htole16(ic->ic_curchan->ic_flags & 0xffff); 2974 2975 BWN_UNLOCK(sc); 2976} 2977 2978static struct ieee80211vap * 2979bwn_vap_create(struct ieee80211com *ic, 2980 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2981 const uint8_t bssid[IEEE80211_ADDR_LEN], 2982 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2983{ 2984 struct ifnet *ifp = ic->ic_ifp; 2985 struct bwn_softc *sc = ifp->if_softc; 2986 struct ieee80211vap *vap; 2987 struct bwn_vap *bvp; 2988 uint8_t mac[IEEE80211_ADDR_LEN]; 2989 2990 IEEE80211_ADDR_COPY(mac, mac0); 2991 switch (opmode) { 2992 case IEEE80211_M_HOSTAP: 2993 case IEEE80211_M_MBSS: 2994 case IEEE80211_M_STA: 2995 case IEEE80211_M_WDS: 2996 case IEEE80211_M_MONITOR: 2997 case IEEE80211_M_IBSS: 2998 case IEEE80211_M_AHDEMO: 2999 break; 3000 default: 3001 return (NULL); 3002 } 3003 3004 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 3005 3006 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 3007 M_80211_VAP, M_NOWAIT | M_ZERO); 3008 if (bvp == NULL) { 3009 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 3010 return (NULL); 3011 } 3012 vap = &bvp->bv_vap; 3013 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 3014 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 3015 /* override with driver methods */ 3016 bvp->bv_newstate = vap->iv_newstate; 3017 vap->iv_newstate = bwn_newstate; 3018 3019 /* override max aid so sta's cannot assoc when we're out of sta id's */ 3020 vap->iv_max_aid = BWN_STAID_MAX; 3021 3022 ieee80211_amrr_init(&bvp->bv_amrr, vap, 3023 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 3024 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 3025 500 /*ms*/); 3026 3027 /* complete setup */ 3028 ieee80211_vap_attach(vap, ieee80211_media_change, 3029 ieee80211_media_status); 3030 return (vap); 3031} 3032 3033static void 3034bwn_vap_delete(struct ieee80211vap *vap) 3035{ 3036 struct bwn_vap *bvp = BWN_VAP(vap); 3037 3038 ieee80211_amrr_cleanup(&bvp->bv_amrr); 3039 ieee80211_vap_detach(vap); 3040 free(bvp, M_80211_VAP); 3041} 3042 3043static void 3044bwn_init(void *arg) 3045{ 3046 struct bwn_softc *sc = arg; 3047 struct ifnet *ifp = sc->sc_ifp; 3048 struct ieee80211com *ic = ifp->if_l2com; 3049 int error = 0; 3050 3051 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3052 __func__, ifp->if_flags); 3053 3054 BWN_LOCK(sc); 3055 error = bwn_init_locked(sc); 3056 BWN_UNLOCK(sc); 3057 3058 if (error == 0) 3059 ieee80211_start_all(ic); /* start all vap's */ 3060} 3061 3062static int 3063bwn_init_locked(struct bwn_softc *sc) 3064{ 3065 struct bwn_mac *mac; 3066 struct ifnet *ifp = sc->sc_ifp; 3067 int error; 3068 3069 BWN_ASSERT_LOCKED(sc); 3070 3071 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3072 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3073 sc->sc_filters = 0; 3074 bwn_wme_clear(sc); 3075 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3076 sc->sc_rf_enabled = 1; 3077 3078 mac = sc->sc_curmac; 3079 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3080 error = bwn_core_init(mac); 3081 if (error != 0) 3082 return (error); 3083 } 3084 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3085 bwn_core_start(mac); 3086 3087 bwn_set_opmode(mac); 3088 bwn_set_pretbtt(mac); 3089 bwn_spu_setdelay(mac, 0); 3090 bwn_set_macaddr(mac); 3091 3092 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3093 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3094 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3095 3096 return (0); 3097} 3098 3099static void 3100bwn_stop(struct bwn_softc *sc, int statechg) 3101{ 3102 3103 BWN_LOCK(sc); 3104 bwn_stop_locked(sc, statechg); 3105 BWN_UNLOCK(sc); 3106} 3107 3108static void 3109bwn_stop_locked(struct bwn_softc *sc, int statechg) 3110{ 3111 struct bwn_mac *mac = sc->sc_curmac; 3112 struct ifnet *ifp = sc->sc_ifp; 3113 3114 BWN_ASSERT_LOCKED(sc); 3115 3116 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3117 /* XXX FIXME opmode not based on VAP */ 3118 bwn_set_opmode(mac); 3119 bwn_set_macaddr(mac); 3120 } 3121 3122 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3123 bwn_core_stop(mac); 3124 3125 callout_stop(&sc->sc_led_blink_ch); 3126 sc->sc_led_blinking = 0; 3127 3128 bwn_core_exit(mac); 3129 sc->sc_rf_enabled = 0; 3130 3131 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3132} 3133 3134static void 3135bwn_wme_clear(struct bwn_softc *sc) 3136{ 3137#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3138 struct wmeParams *p; 3139 unsigned int i; 3140 3141 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3142 ("%s:%d: fail", __func__, __LINE__)); 3143 3144 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3145 p = &(sc->sc_wmeParams[i]); 3146 3147 switch (bwn_wme_shm_offsets[i]) { 3148 case BWN_WME_VOICE: 3149 p->wmep_txopLimit = 0; 3150 p->wmep_aifsn = 2; 3151 /* XXX FIXME: log2(cwmin) */ 3152 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3153 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3154 break; 3155 case BWN_WME_VIDEO: 3156 p->wmep_txopLimit = 0; 3157 p->wmep_aifsn = 2; 3158 /* XXX FIXME: log2(cwmin) */ 3159 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3160 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3161 break; 3162 case BWN_WME_BESTEFFORT: 3163 p->wmep_txopLimit = 0; 3164 p->wmep_aifsn = 3; 3165 /* XXX FIXME: log2(cwmin) */ 3166 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3167 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3168 break; 3169 case BWN_WME_BACKGROUND: 3170 p->wmep_txopLimit = 0; 3171 p->wmep_aifsn = 7; 3172 /* XXX FIXME: log2(cwmin) */ 3173 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3174 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3175 break; 3176 default: 3177 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3178 } 3179 } 3180} 3181 3182static int 3183bwn_core_init(struct bwn_mac *mac) 3184{ 3185#ifdef BWN_DEBUG 3186 struct bwn_softc *sc = mac->mac_sc; 3187#endif 3188 struct siba_dev_softc *sd = mac->mac_sd; 3189 struct siba_softc *siba = sd->sd_bus; 3190 struct siba_sprom *sprom = &siba->siba_sprom; 3191 uint64_t hf; 3192 int error; 3193 3194 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3195 ("%s:%d: fail", __func__, __LINE__)); 3196 3197 siba_powerup(siba, 0); 3198 if (!siba_dev_isup(sd)) 3199 bwn_reset_core(mac, 3200 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3201 3202 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3203 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3204 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3205 BWN_GETTIME(mac->mac_phy.nexttime); 3206 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3207 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3208 mac->mac_stats.link_noise = -95; 3209 mac->mac_reason_intr = 0; 3210 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3211 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3212#ifdef BWN_DEBUG 3213 if (sc->sc_debug & BWN_DEBUG_XMIT) 3214 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3215#endif 3216 mac->mac_suspended = 1; 3217 mac->mac_task_state = 0; 3218 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3219 3220 mac->mac_phy.init_pre(mac); 3221 3222 siba_pcicore_intr(&siba->siba_pci, sd); 3223 3224 bwn_fix_imcfglobug(mac); 3225 bwn_bt_disable(mac); 3226 if (mac->mac_phy.prepare_hw) { 3227 error = mac->mac_phy.prepare_hw(mac); 3228 if (error) 3229 goto fail0; 3230 } 3231 error = bwn_chip_init(mac); 3232 if (error) 3233 goto fail0; 3234 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3235 mac->mac_sd->sd_id.sd_rev); 3236 hf = bwn_hf_read(mac); 3237 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3238 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3239 if (sprom->bf_lo & BWN_BFL_PACTRL) 3240 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3241 if (mac->mac_phy.rev == 1) 3242 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3243 } 3244 if (mac->mac_phy.rf_ver == 0x2050) { 3245 if (mac->mac_phy.rf_rev < 6) 3246 hf |= BWN_HF_FORCE_VCO_RECALC; 3247 if (mac->mac_phy.rf_rev == 6) 3248 hf |= BWN_HF_4318_TSSI; 3249 } 3250 if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW) 3251 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3252 if ((siba->siba_type == SIBA_TYPE_PCI) && 3253 (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10)) 3254 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3255 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3256 bwn_hf_write(mac, hf); 3257 3258 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3259 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3260 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3261 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3262 3263 bwn_rate_init(mac); 3264 bwn_set_phytxctl(mac); 3265 3266 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3267 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3268 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3269 3270 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3271 bwn_pio_init(mac); 3272 else 3273 bwn_dma_init(mac); 3274 if (error) 3275 goto fail1; 3276 bwn_wme_init(mac); 3277 bwn_spu_setdelay(mac, 1); 3278 bwn_bt_enable(mac); 3279 3280 siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)); 3281 bwn_set_macaddr(mac); 3282 bwn_crypt_init(mac); 3283 3284 /* XXX LED initializatin */ 3285 3286 mac->mac_status = BWN_MAC_STATUS_INITED; 3287 3288 return (error); 3289 3290fail1: 3291 bwn_chip_exit(mac); 3292fail0: 3293 siba_powerdown(siba); 3294 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3295 ("%s:%d: fail", __func__, __LINE__)); 3296 return (error); 3297} 3298 3299static void 3300bwn_core_start(struct bwn_mac *mac) 3301{ 3302 struct bwn_softc *sc = mac->mac_sc; 3303 uint32_t tmp; 3304 3305 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3306 ("%s:%d: fail", __func__, __LINE__)); 3307 3308 if (mac->mac_sd->sd_id.sd_rev < 5) 3309 return; 3310 3311 while (1) { 3312 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3313 if (!(tmp & 0x00000001)) 3314 break; 3315 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3316 } 3317 3318 bwn_mac_enable(mac); 3319 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3320 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3321 3322 mac->mac_status = BWN_MAC_STATUS_STARTED; 3323} 3324 3325static void 3326bwn_core_exit(struct bwn_mac *mac) 3327{ 3328 uint32_t macctl; 3329 3330 BWN_ASSERT_LOCKED(mac->mac_sc); 3331 3332 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3333 ("%s:%d: fail", __func__, __LINE__)); 3334 3335 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3336 return; 3337 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3338 3339 macctl = BWN_READ_4(mac, BWN_MACCTL); 3340 macctl &= ~BWN_MACCTL_MCODE_RUN; 3341 macctl |= BWN_MACCTL_MCODE_JMP0; 3342 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3343 3344 bwn_dma_stop(mac); 3345 bwn_pio_stop(mac); 3346 bwn_chip_exit(mac); 3347 mac->mac_phy.switch_analog(mac, 0); 3348 siba_dev_down(mac->mac_sd, 0); 3349 siba_powerdown(mac->mac_sd->sd_bus); 3350} 3351 3352static void 3353bwn_fix_imcfglobug(struct bwn_mac *mac) 3354{ 3355 struct siba_dev_softc *sd = mac->mac_sd; 3356 struct siba_softc *siba = sd->sd_bus; 3357 uint32_t tmp; 3358 3359 if (siba->siba_pci.spc_dev == NULL) 3360 return; 3361 if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI || 3362 siba->siba_pci.spc_dev->sd_id.sd_rev > 5) 3363 return; 3364 3365 tmp = siba_read_4(sd, SIBA_IMCFGLO) & 3366 ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO); 3367 switch (siba->siba_type) { 3368 case SIBA_TYPE_PCI: 3369 case SIBA_TYPE_PCMCIA: 3370 tmp |= 0x32; 3371 break; 3372 case SIBA_TYPE_SSB: 3373 tmp |= 0x53; 3374 break; 3375 } 3376 siba_write_4(sd, SIBA_IMCFGLO, tmp); 3377} 3378 3379static void 3380bwn_bt_disable(struct bwn_mac *mac) 3381{ 3382 struct bwn_softc *sc = mac->mac_sc; 3383 3384 (void)sc; 3385 /* XXX do nothing yet */ 3386} 3387 3388static int 3389bwn_chip_init(struct bwn_mac *mac) 3390{ 3391 struct bwn_phy *phy = &mac->mac_phy; 3392 uint32_t macctl; 3393 int error; 3394 3395 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3396 if (phy->gmode) 3397 macctl |= BWN_MACCTL_GMODE; 3398 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3399 3400 error = bwn_fw_fillinfo(mac); 3401 if (error) 3402 return (error); 3403 error = bwn_fw_loaducode(mac); 3404 if (error) 3405 return (error); 3406 3407 error = bwn_gpio_init(mac); 3408 if (error) 3409 return (error); 3410 3411 error = bwn_fw_loadinitvals(mac); 3412 if (error) { 3413 bwn_gpio_cleanup(mac); 3414 return (error); 3415 } 3416 phy->switch_analog(mac, 1); 3417 error = bwn_phy_init(mac); 3418 if (error) { 3419 bwn_gpio_cleanup(mac); 3420 return (error); 3421 } 3422 if (phy->set_im) 3423 phy->set_im(mac, BWN_IMMODE_NONE); 3424 if (phy->set_antenna) 3425 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3426 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3427 3428 if (phy->type == BWN_PHYTYPE_B) 3429 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3430 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3431 if (mac->mac_sd->sd_id.sd_rev < 5) 3432 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3433 3434 BWN_WRITE_4(mac, BWN_MACCTL, 3435 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3436 BWN_WRITE_4(mac, BWN_MACCTL, 3437 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3438 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3439 3440 bwn_set_opmode(mac); 3441 if (mac->mac_sd->sd_id.sd_rev < 3) { 3442 BWN_WRITE_2(mac, 0x060e, 0x0000); 3443 BWN_WRITE_2(mac, 0x0610, 0x8000); 3444 BWN_WRITE_2(mac, 0x0604, 0x0000); 3445 BWN_WRITE_2(mac, 0x0606, 0x0200); 3446 } else { 3447 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3448 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3449 } 3450 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3451 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3452 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3453 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3454 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3455 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3456 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3457 siba_write_4(mac->mac_sd, SIBA_TGSLOW, 3458 siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000); 3459 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, 3460 mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay); 3461 return (error); 3462} 3463 3464/* read hostflags */ 3465static uint64_t 3466bwn_hf_read(struct bwn_mac *mac) 3467{ 3468 uint64_t ret; 3469 3470 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3471 ret <<= 16; 3472 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3473 ret <<= 16; 3474 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3475 return (ret); 3476} 3477 3478static void 3479bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3480{ 3481 3482 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3483 (value & 0x00000000ffffull)); 3484 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3485 (value & 0x0000ffff0000ull) >> 16); 3486 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3487 (value & 0xffff00000000ULL) >> 32); 3488} 3489 3490static void 3491bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3492{ 3493 3494 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3495 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3496} 3497 3498static void 3499bwn_rate_init(struct bwn_mac *mac) 3500{ 3501 3502 switch (mac->mac_phy.type) { 3503 case BWN_PHYTYPE_A: 3504 case BWN_PHYTYPE_G: 3505 case BWN_PHYTYPE_LP: 3506 case BWN_PHYTYPE_N: 3507 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3508 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3509 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3510 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3511 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3512 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3513 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3514 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3515 break; 3516 /* FALLTHROUGH */ 3517 case BWN_PHYTYPE_B: 3518 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3519 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3520 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3521 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3522 break; 3523 default: 3524 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3525 } 3526} 3527 3528static void 3529bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3530{ 3531 uint16_t offset; 3532 3533 if (ofdm) { 3534 offset = 0x480; 3535 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3536 } else { 3537 offset = 0x4c0; 3538 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3539 } 3540 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3541 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3542} 3543 3544static uint8_t 3545bwn_plcp_getcck(const uint8_t bitrate) 3546{ 3547 3548 switch (bitrate) { 3549 case BWN_CCK_RATE_1MB: 3550 return (0x0a); 3551 case BWN_CCK_RATE_2MB: 3552 return (0x14); 3553 case BWN_CCK_RATE_5MB: 3554 return (0x37); 3555 case BWN_CCK_RATE_11MB: 3556 return (0x6e); 3557 } 3558 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3559 return (0); 3560} 3561 3562static uint8_t 3563bwn_plcp_getofdm(const uint8_t bitrate) 3564{ 3565 3566 switch (bitrate) { 3567 case BWN_OFDM_RATE_6MB: 3568 return (0xb); 3569 case BWN_OFDM_RATE_9MB: 3570 return (0xf); 3571 case BWN_OFDM_RATE_12MB: 3572 return (0xa); 3573 case BWN_OFDM_RATE_18MB: 3574 return (0xe); 3575 case BWN_OFDM_RATE_24MB: 3576 return (0x9); 3577 case BWN_OFDM_RATE_36MB: 3578 return (0xd); 3579 case BWN_OFDM_RATE_48MB: 3580 return (0x8); 3581 case BWN_OFDM_RATE_54MB: 3582 return (0xc); 3583 } 3584 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3585 return (0); 3586} 3587 3588static void 3589bwn_set_phytxctl(struct bwn_mac *mac) 3590{ 3591 uint16_t ctl; 3592 3593 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3594 BWN_TX_PHY_TXPWR); 3595 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3596 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3597 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3598} 3599 3600static void 3601bwn_pio_init(struct bwn_mac *mac) 3602{ 3603 struct bwn_pio *pio = &mac->mac_method.pio; 3604 3605 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3606 & ~BWN_MACCTL_BIGENDIAN); 3607 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3608 3609 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3610 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3611 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3612 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3613 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3614 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3615} 3616 3617static void 3618bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3619 int index) 3620{ 3621 struct bwn_pio_txpkt *tp; 3622 unsigned int i; 3623 3624 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3625 tq->tq_index = index; 3626 3627 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3628 if (mac->mac_sd->sd_id.sd_rev >= 8) 3629 tq->tq_size = 1920; 3630 else { 3631 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3632 tq->tq_size -= 80; 3633 } 3634 3635 TAILQ_INIT(&tq->tq_pktlist); 3636 for (i = 0; i < N(tq->tq_pkts); i++) { 3637 tp = &(tq->tq_pkts[i]); 3638 tp->tp_index = i; 3639 tp->tp_queue = tq; 3640 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3641 } 3642} 3643 3644static uint16_t 3645bwn_pio_idx2base(struct bwn_mac *mac, int index) 3646{ 3647 struct bwn_softc *sc = mac->mac_sc; 3648 static const uint16_t bases[] = { 3649 BWN_PIO_BASE0, 3650 BWN_PIO_BASE1, 3651 BWN_PIO_BASE2, 3652 BWN_PIO_BASE3, 3653 BWN_PIO_BASE4, 3654 BWN_PIO_BASE5, 3655 BWN_PIO_BASE6, 3656 BWN_PIO_BASE7, 3657 }; 3658 static const uint16_t bases_rev11[] = { 3659 BWN_PIO11_BASE0, 3660 BWN_PIO11_BASE1, 3661 BWN_PIO11_BASE2, 3662 BWN_PIO11_BASE3, 3663 BWN_PIO11_BASE4, 3664 BWN_PIO11_BASE5, 3665 }; 3666 3667 if (mac->mac_sd->sd_id.sd_rev >= 11) { 3668 if (index >= N(bases_rev11)) 3669 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3670 return (bases_rev11[index]); 3671 } 3672 if (index >= N(bases)) 3673 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3674 return (bases[index]); 3675} 3676 3677static void 3678bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3679 int index) 3680{ 3681 3682 prq->prq_mac = mac; 3683 prq->prq_rev = mac->mac_sd->sd_id.sd_rev; 3684 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3685 bwn_dma_rxdirectfifo(mac, index, 1); 3686} 3687 3688static void 3689bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3690{ 3691 if (tq == NULL) 3692 return; 3693 bwn_pio_cancel_tx_packets(tq); 3694} 3695 3696static void 3697bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3698{ 3699 3700 bwn_destroy_pioqueue_tx(pio); 3701} 3702 3703static uint16_t 3704bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3705 uint16_t offset) 3706{ 3707 3708 return (BWN_READ_2(mac, tq->tq_base + offset)); 3709} 3710 3711static void 3712bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3713{ 3714 uint32_t ctl; 3715 int type; 3716 uint16_t base; 3717 3718 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3719 base = bwn_dma_base(type, idx); 3720 if (type == BWN_DMA_64BIT) { 3721 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3722 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3723 if (enable) 3724 ctl |= BWN_DMA64_RXDIRECTFIFO; 3725 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3726 } else { 3727 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3728 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3729 if (enable) 3730 ctl |= BWN_DMA32_RXDIRECTFIFO; 3731 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3732 } 3733} 3734 3735static uint64_t 3736bwn_dma_mask(struct bwn_mac *mac) 3737{ 3738 uint32_t tmp; 3739 uint16_t base; 3740 3741 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3742 if (tmp & SIBA_TGSHIGH_DMA64) 3743 return (BWN_DMA_BIT_MASK(64)); 3744 base = bwn_dma_base(0, 0); 3745 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3746 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3747 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3748 return (BWN_DMA_BIT_MASK(32)); 3749 3750 return (BWN_DMA_BIT_MASK(30)); 3751} 3752 3753static int 3754bwn_dma_mask2type(uint64_t dmamask) 3755{ 3756 3757 if (dmamask == BWN_DMA_BIT_MASK(30)) 3758 return (BWN_DMA_30BIT); 3759 if (dmamask == BWN_DMA_BIT_MASK(32)) 3760 return (BWN_DMA_32BIT); 3761 if (dmamask == BWN_DMA_BIT_MASK(64)) 3762 return (BWN_DMA_64BIT); 3763 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3764 return (BWN_DMA_30BIT); 3765} 3766 3767static void 3768bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3769{ 3770 struct bwn_pio_txpkt *tp; 3771 unsigned int i; 3772 3773 for (i = 0; i < N(tq->tq_pkts); i++) { 3774 tp = &(tq->tq_pkts[i]); 3775 if (tp->tp_m) { 3776 m_freem(tp->tp_m); 3777 tp->tp_m = NULL; 3778 } 3779 } 3780} 3781 3782static uint16_t 3783bwn_dma_base(int type, int controller_idx) 3784{ 3785 static const uint16_t map64[] = { 3786 BWN_DMA64_BASE0, 3787 BWN_DMA64_BASE1, 3788 BWN_DMA64_BASE2, 3789 BWN_DMA64_BASE3, 3790 BWN_DMA64_BASE4, 3791 BWN_DMA64_BASE5, 3792 }; 3793 static const uint16_t map32[] = { 3794 BWN_DMA32_BASE0, 3795 BWN_DMA32_BASE1, 3796 BWN_DMA32_BASE2, 3797 BWN_DMA32_BASE3, 3798 BWN_DMA32_BASE4, 3799 BWN_DMA32_BASE5, 3800 }; 3801 3802 if (type == BWN_DMA_64BIT) { 3803 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3804 ("%s:%d: fail", __func__, __LINE__)); 3805 return (map64[controller_idx]); 3806 } 3807 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3808 ("%s:%d: fail", __func__, __LINE__)); 3809 return (map32[controller_idx]); 3810} 3811 3812static void 3813bwn_dma_init(struct bwn_mac *mac) 3814{ 3815 struct bwn_dma *dma = &mac->mac_method.dma; 3816 3817 /* setup TX DMA channels. */ 3818 bwn_dma_setup(dma->wme[WME_AC_BK]); 3819 bwn_dma_setup(dma->wme[WME_AC_BE]); 3820 bwn_dma_setup(dma->wme[WME_AC_VI]); 3821 bwn_dma_setup(dma->wme[WME_AC_VO]); 3822 bwn_dma_setup(dma->mcast); 3823 /* setup RX DMA channel. */ 3824 bwn_dma_setup(dma->rx); 3825} 3826 3827static struct bwn_dma_ring * 3828bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3829 int for_tx, int type) 3830{ 3831 struct bwn_dma *dma = &mac->mac_method.dma; 3832 struct bwn_dma_ring *dr; 3833 struct bwn_dmadesc_generic *desc; 3834 struct bwn_dmadesc_meta *mt; 3835 struct bwn_softc *sc = mac->mac_sc; 3836 int error, i; 3837 3838 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3839 if (dr == NULL) 3840 goto out; 3841 dr->dr_numslots = BWN_RXRING_SLOTS; 3842 if (for_tx) 3843 dr->dr_numslots = BWN_TXRING_SLOTS; 3844 3845 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3846 M_DEVBUF, M_NOWAIT | M_ZERO); 3847 if (dr->dr_meta == NULL) 3848 goto fail0; 3849 3850 dr->dr_type = type; 3851 dr->dr_mac = mac; 3852 dr->dr_base = bwn_dma_base(type, controller_index); 3853 dr->dr_index = controller_index; 3854 if (type == BWN_DMA_64BIT) { 3855 dr->getdesc = bwn_dma_64_getdesc; 3856 dr->setdesc = bwn_dma_64_setdesc; 3857 dr->start_transfer = bwn_dma_64_start_transfer; 3858 dr->suspend = bwn_dma_64_suspend; 3859 dr->resume = bwn_dma_64_resume; 3860 dr->get_curslot = bwn_dma_64_get_curslot; 3861 dr->set_curslot = bwn_dma_64_set_curslot; 3862 } else { 3863 dr->getdesc = bwn_dma_32_getdesc; 3864 dr->setdesc = bwn_dma_32_setdesc; 3865 dr->start_transfer = bwn_dma_32_start_transfer; 3866 dr->suspend = bwn_dma_32_suspend; 3867 dr->resume = bwn_dma_32_resume; 3868 dr->get_curslot = bwn_dma_32_get_curslot; 3869 dr->set_curslot = bwn_dma_32_set_curslot; 3870 } 3871 if (for_tx) { 3872 dr->dr_tx = 1; 3873 dr->dr_curslot = -1; 3874 } else { 3875 if (dr->dr_index == 0) { 3876 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3877 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3878 } else 3879 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3880 } 3881 3882 error = bwn_dma_allocringmemory(dr); 3883 if (error) 3884 goto fail2; 3885 3886 if (for_tx) { 3887 /* 3888 * Assumption: BWN_TXRING_SLOTS can be divided by 3889 * BWN_TX_SLOTS_PER_FRAME 3890 */ 3891 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3892 ("%s:%d: fail", __func__, __LINE__)); 3893 3894 dr->dr_txhdr_cache = 3895 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3896 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3897 KASSERT(dr->dr_txhdr_cache != NULL, 3898 ("%s:%d: fail", __func__, __LINE__)); 3899 3900 /* 3901 * Create TX ring DMA stuffs 3902 */ 3903 error = bus_dma_tag_create(dma->parent_dtag, 3904 BWN_ALIGN, 0, 3905 BUS_SPACE_MAXADDR, 3906 BUS_SPACE_MAXADDR, 3907 NULL, NULL, 3908 BWN_HDRSIZE(mac), 3909 1, 3910 BUS_SPACE_MAXSIZE_32BIT, 3911 0, 3912 NULL, NULL, 3913 &dr->dr_txring_dtag); 3914 if (error) { 3915 device_printf(sc->sc_dev, 3916 "can't create TX ring DMA tag: TODO frees\n"); 3917 goto fail1; 3918 } 3919 3920 for (i = 0; i < dr->dr_numslots; i += 2) { 3921 dr->getdesc(dr, i, &desc, &mt); 3922 3923 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3924 mt->mt_m = NULL; 3925 mt->mt_ni = NULL; 3926 mt->mt_islast = 0; 3927 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3928 &mt->mt_dmap); 3929 if (error) { 3930 device_printf(sc->sc_dev, 3931 "can't create RX buf DMA map\n"); 3932 goto fail1; 3933 } 3934 3935 dr->getdesc(dr, i + 1, &desc, &mt); 3936 3937 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3938 mt->mt_m = NULL; 3939 mt->mt_ni = NULL; 3940 mt->mt_islast = 1; 3941 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3942 &mt->mt_dmap); 3943 if (error) { 3944 device_printf(sc->sc_dev, 3945 "can't create RX buf DMA map\n"); 3946 goto fail1; 3947 } 3948 } 3949 } else { 3950 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3951 &dr->dr_spare_dmap); 3952 if (error) { 3953 device_printf(sc->sc_dev, 3954 "can't create RX buf DMA map\n"); 3955 goto out; /* XXX wrong! */ 3956 } 3957 3958 for (i = 0; i < dr->dr_numslots; i++) { 3959 dr->getdesc(dr, i, &desc, &mt); 3960 3961 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3962 &mt->mt_dmap); 3963 if (error) { 3964 device_printf(sc->sc_dev, 3965 "can't create RX buf DMA map\n"); 3966 goto out; /* XXX wrong! */ 3967 } 3968 error = bwn_dma_newbuf(dr, desc, mt, 1); 3969 if (error) { 3970 device_printf(sc->sc_dev, 3971 "failed to allocate RX buf\n"); 3972 goto out; /* XXX wrong! */ 3973 } 3974 } 3975 3976 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3977 BUS_DMASYNC_PREWRITE); 3978 3979 dr->dr_usedslot = dr->dr_numslots; 3980 } 3981 3982 out: 3983 return (dr); 3984 3985fail2: 3986 free(dr->dr_txhdr_cache, M_DEVBUF); 3987fail1: 3988 free(dr->dr_meta, M_DEVBUF); 3989fail0: 3990 free(dr, M_DEVBUF); 3991 return (NULL); 3992} 3993 3994static void 3995bwn_dma_ringfree(struct bwn_dma_ring **dr) 3996{ 3997 3998 if (dr == NULL) 3999 return; 4000 4001 bwn_dma_free_descbufs(*dr); 4002 bwn_dma_free_ringmemory(*dr); 4003 4004 free((*dr)->dr_txhdr_cache, M_DEVBUF); 4005 free((*dr)->dr_meta, M_DEVBUF); 4006 free(*dr, M_DEVBUF); 4007 4008 *dr = NULL; 4009} 4010 4011static void 4012bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 4013 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4014{ 4015 struct bwn_dmadesc32 *desc; 4016 4017 *meta = &(dr->dr_meta[slot]); 4018 desc = dr->dr_ring_descbase; 4019 desc = &(desc[slot]); 4020 4021 *gdesc = (struct bwn_dmadesc_generic *)desc; 4022} 4023 4024static void 4025bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 4026 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4027 int start, int end, int irq) 4028{ 4029 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 4030 uint32_t addr, addrext, ctl; 4031 int slot; 4032 4033 slot = (int)(&(desc->dma.dma32) - descbase); 4034 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4035 ("%s:%d: fail", __func__, __LINE__)); 4036 4037 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 4038 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 4039 addr |= siba_dma_translation(dr->dr_mac->mac_sd); 4040 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 4041 if (slot == dr->dr_numslots - 1) 4042 ctl |= BWN_DMA32_DCTL_DTABLEEND; 4043 if (start) 4044 ctl |= BWN_DMA32_DCTL_FRAMESTART; 4045 if (end) 4046 ctl |= BWN_DMA32_DCTL_FRAMEEND; 4047 if (irq) 4048 ctl |= BWN_DMA32_DCTL_IRQ; 4049 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 4050 & BWN_DMA32_DCTL_ADDREXT_MASK; 4051 4052 desc->dma.dma32.control = htole32(ctl); 4053 desc->dma.dma32.address = htole32(addr); 4054} 4055 4056static void 4057bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 4058{ 4059 4060 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 4061 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 4062} 4063 4064static void 4065bwn_dma_32_suspend(struct bwn_dma_ring *dr) 4066{ 4067 4068 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4069 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 4070} 4071 4072static void 4073bwn_dma_32_resume(struct bwn_dma_ring *dr) 4074{ 4075 4076 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4077 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 4078} 4079 4080static int 4081bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4082{ 4083 uint32_t val; 4084 4085 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4086 val &= BWN_DMA32_RXDPTR; 4087 4088 return (val / sizeof(struct bwn_dmadesc32)); 4089} 4090 4091static void 4092bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4093{ 4094 4095 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4096 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4097} 4098 4099static void 4100bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4101 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4102{ 4103 struct bwn_dmadesc64 *desc; 4104 4105 *meta = &(dr->dr_meta[slot]); 4106 desc = dr->dr_ring_descbase; 4107 desc = &(desc[slot]); 4108 4109 *gdesc = (struct bwn_dmadesc_generic *)desc; 4110} 4111 4112static void 4113bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4114 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4115 int start, int end, int irq) 4116{ 4117 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4118 int slot; 4119 uint32_t ctl0 = 0, ctl1 = 0; 4120 uint32_t addrlo, addrhi; 4121 uint32_t addrext; 4122 4123 slot = (int)(&(desc->dma.dma64) - descbase); 4124 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4125 ("%s:%d: fail", __func__, __LINE__)); 4126 4127 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4128 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4129 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4130 30; 4131 addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1); 4132 if (slot == dr->dr_numslots - 1) 4133 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4134 if (start) 4135 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4136 if (end) 4137 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4138 if (irq) 4139 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4140 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4141 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4142 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4143 4144 desc->dma.dma64.control0 = htole32(ctl0); 4145 desc->dma.dma64.control1 = htole32(ctl1); 4146 desc->dma.dma64.address_low = htole32(addrlo); 4147 desc->dma.dma64.address_high = htole32(addrhi); 4148} 4149 4150static void 4151bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4152{ 4153 4154 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4155 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4156} 4157 4158static void 4159bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4160{ 4161 4162 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4163 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4164} 4165 4166static void 4167bwn_dma_64_resume(struct bwn_dma_ring *dr) 4168{ 4169 4170 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4171 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4172} 4173 4174static int 4175bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4176{ 4177 uint32_t val; 4178 4179 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4180 val &= BWN_DMA64_RXSTATDPTR; 4181 4182 return (val / sizeof(struct bwn_dmadesc64)); 4183} 4184 4185static void 4186bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4187{ 4188 4189 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4190 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4191} 4192 4193static int 4194bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4195{ 4196 struct bwn_mac *mac = dr->dr_mac; 4197 struct bwn_dma *dma = &mac->mac_method.dma; 4198 struct bwn_softc *sc = mac->mac_sc; 4199 int error; 4200 4201 error = bus_dma_tag_create(dma->parent_dtag, 4202 BWN_ALIGN, 0, 4203 BUS_SPACE_MAXADDR, 4204 BUS_SPACE_MAXADDR, 4205 NULL, NULL, 4206 BWN_DMA_RINGMEMSIZE, 4207 1, 4208 BUS_SPACE_MAXSIZE_32BIT, 4209 0, 4210 NULL, NULL, 4211 &dr->dr_ring_dtag); 4212 if (error) { 4213 device_printf(sc->sc_dev, 4214 "can't create TX ring DMA tag: TODO frees\n"); 4215 return (-1); 4216 } 4217 4218 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4219 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4220 &dr->dr_ring_dmap); 4221 if (error) { 4222 device_printf(sc->sc_dev, 4223 "can't allocate DMA mem: TODO frees\n"); 4224 return (-1); 4225 } 4226 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4227 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4228 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4229 if (error) { 4230 device_printf(sc->sc_dev, 4231 "can't load DMA mem: TODO free\n"); 4232 return (-1); 4233 } 4234 4235 return (0); 4236} 4237 4238static void 4239bwn_dma_setup(struct bwn_dma_ring *dr) 4240{ 4241 uint64_t ring64; 4242 uint32_t addrext, ring32, value; 4243 uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd); 4244 4245 if (dr->dr_tx) { 4246 dr->dr_curslot = -1; 4247 4248 if (dr->dr_type == BWN_DMA_64BIT) { 4249 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4250 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4251 >> 30; 4252 value = BWN_DMA64_TXENABLE; 4253 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4254 & BWN_DMA64_TXADDREXT_MASK; 4255 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4256 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4257 (ring64 & 0xffffffff)); 4258 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4259 ((ring64 >> 32) & 4260 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4261 } else { 4262 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4263 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4264 value = BWN_DMA32_TXENABLE; 4265 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4266 & BWN_DMA32_TXADDREXT_MASK; 4267 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4268 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4269 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4270 } 4271 return; 4272 } 4273 4274 /* 4275 * set for RX 4276 */ 4277 dr->dr_usedslot = dr->dr_numslots; 4278 4279 if (dr->dr_type == BWN_DMA_64BIT) { 4280 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4281 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4282 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4283 value |= BWN_DMA64_RXENABLE; 4284 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4285 & BWN_DMA64_RXADDREXT_MASK; 4286 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4287 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4288 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4289 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4290 | (trans << 1)); 4291 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4292 sizeof(struct bwn_dmadesc64)); 4293 } else { 4294 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4295 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4296 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4297 value |= BWN_DMA32_RXENABLE; 4298 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4299 & BWN_DMA32_RXADDREXT_MASK; 4300 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4301 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4302 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4303 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4304 sizeof(struct bwn_dmadesc32)); 4305 } 4306} 4307 4308static void 4309bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4310{ 4311 4312 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4313 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4314 dr->dr_ring_dmap); 4315} 4316 4317static void 4318bwn_dma_cleanup(struct bwn_dma_ring *dr) 4319{ 4320 4321 if (dr->dr_tx) { 4322 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4323 if (dr->dr_type == BWN_DMA_64BIT) { 4324 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4325 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4326 } else 4327 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4328 } else { 4329 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4330 if (dr->dr_type == BWN_DMA_64BIT) { 4331 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4332 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4333 } else 4334 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4335 } 4336} 4337 4338static void 4339bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4340{ 4341 struct bwn_dmadesc_generic *desc; 4342 struct bwn_dmadesc_meta *meta; 4343 struct bwn_mac *mac = dr->dr_mac; 4344 struct bwn_dma *dma = &mac->mac_method.dma; 4345 struct bwn_softc *sc = mac->mac_sc; 4346 int i; 4347 4348 if (!dr->dr_usedslot) 4349 return; 4350 for (i = 0; i < dr->dr_numslots; i++) { 4351 dr->getdesc(dr, i, &desc, &meta); 4352 4353 if (meta->mt_m == NULL) { 4354 if (!dr->dr_tx) 4355 device_printf(sc->sc_dev, "%s: not TX?\n", 4356 __func__); 4357 continue; 4358 } 4359 if (dr->dr_tx) { 4360 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4361 bus_dmamap_unload(dr->dr_txring_dtag, 4362 meta->mt_dmap); 4363 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4364 bus_dmamap_unload(dma->txbuf_dtag, 4365 meta->mt_dmap); 4366 } else 4367 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4368 bwn_dma_free_descbuf(dr, meta); 4369 } 4370} 4371 4372static int 4373bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4374 int type) 4375{ 4376 struct bwn_softc *sc = mac->mac_sc; 4377 uint32_t value; 4378 int i; 4379 uint16_t offset; 4380 4381 for (i = 0; i < 10; i++) { 4382 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4383 BWN_DMA32_TXSTATUS; 4384 value = BWN_READ_4(mac, base + offset); 4385 if (type == BWN_DMA_64BIT) { 4386 value &= BWN_DMA64_TXSTAT; 4387 if (value == BWN_DMA64_TXSTAT_DISABLED || 4388 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4389 value == BWN_DMA64_TXSTAT_STOPPED) 4390 break; 4391 } else { 4392 value &= BWN_DMA32_TXSTATE; 4393 if (value == BWN_DMA32_TXSTAT_DISABLED || 4394 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4395 value == BWN_DMA32_TXSTAT_STOPPED) 4396 break; 4397 } 4398 DELAY(1000); 4399 } 4400 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4401 BWN_WRITE_4(mac, base + offset, 0); 4402 for (i = 0; i < 10; i++) { 4403 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4404 BWN_DMA32_TXSTATUS; 4405 value = BWN_READ_4(mac, base + offset); 4406 if (type == BWN_DMA_64BIT) { 4407 value &= BWN_DMA64_TXSTAT; 4408 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4409 i = -1; 4410 break; 4411 } 4412 } else { 4413 value &= BWN_DMA32_TXSTATE; 4414 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4415 i = -1; 4416 break; 4417 } 4418 } 4419 DELAY(1000); 4420 } 4421 if (i != -1) { 4422 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4423 return (ENODEV); 4424 } 4425 DELAY(1000); 4426 4427 return (0); 4428} 4429 4430static int 4431bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4432 int type) 4433{ 4434 struct bwn_softc *sc = mac->mac_sc; 4435 uint32_t value; 4436 int i; 4437 uint16_t offset; 4438 4439 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4440 BWN_WRITE_4(mac, base + offset, 0); 4441 for (i = 0; i < 10; i++) { 4442 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4443 BWN_DMA32_RXSTATUS; 4444 value = BWN_READ_4(mac, base + offset); 4445 if (type == BWN_DMA_64BIT) { 4446 value &= BWN_DMA64_RXSTAT; 4447 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4448 i = -1; 4449 break; 4450 } 4451 } else { 4452 value &= BWN_DMA32_RXSTATE; 4453 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4454 i = -1; 4455 break; 4456 } 4457 } 4458 DELAY(1000); 4459 } 4460 if (i != -1) { 4461 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4462 return (ENODEV); 4463 } 4464 4465 return (0); 4466} 4467 4468static void 4469bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4470 struct bwn_dmadesc_meta *meta) 4471{ 4472 4473 if (meta->mt_m != NULL) { 4474 m_freem(meta->mt_m); 4475 meta->mt_m = NULL; 4476 } 4477 if (meta->mt_ni != NULL) { 4478 ieee80211_free_node(meta->mt_ni); 4479 meta->mt_ni = NULL; 4480 } 4481} 4482 4483static void 4484bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4485{ 4486 struct bwn_rxhdr4 *rxhdr; 4487 unsigned char *frame; 4488 4489 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4490 rxhdr->frame_len = 0; 4491 4492 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4493 sizeof(struct bwn_plcp6) + 2, 4494 ("%s:%d: fail", __func__, __LINE__)); 4495 frame = mtod(m, char *) + dr->dr_frameoffset; 4496 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4497} 4498 4499static uint8_t 4500bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4501{ 4502 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4503 4504 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4505 == 0xff); 4506} 4507 4508static void 4509bwn_wme_init(struct bwn_mac *mac) 4510{ 4511 4512 bwn_wme_load(mac); 4513 4514 /* enable WME support. */ 4515 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4516 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4517 BWN_IFSCTL_USE_EDCF); 4518} 4519 4520static void 4521bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4522{ 4523 struct bwn_softc *sc = mac->mac_sc; 4524 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4525 uint16_t delay; /* microsec */ 4526 4527 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4528 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4529 delay = 500; 4530 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4531 delay = max(delay, (uint16_t)2400); 4532 4533 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4534} 4535 4536static void 4537bwn_bt_enable(struct bwn_mac *mac) 4538{ 4539 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 4540 uint64_t hf; 4541 4542 if (bwn_bluetooth == 0) 4543 return; 4544 if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0) 4545 return; 4546 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4547 return; 4548 4549 hf = bwn_hf_read(mac); 4550 if (sprom->bf_lo & BWN_BFL_BTCMOD) 4551 hf |= BWN_HF_BT_COEXISTALT; 4552 else 4553 hf |= BWN_HF_BT_COEXIST; 4554 bwn_hf_write(mac, hf); 4555} 4556 4557static void 4558bwn_set_macaddr(struct bwn_mac *mac) 4559{ 4560 4561 bwn_mac_write_bssid(mac); 4562 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4563} 4564 4565static void 4566bwn_clear_keys(struct bwn_mac *mac) 4567{ 4568 int i; 4569 4570 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4571 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4572 ("%s:%d: fail", __func__, __LINE__)); 4573 4574 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4575 NULL, BWN_SEC_KEYSIZE, NULL); 4576 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4577 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4578 NULL, BWN_SEC_KEYSIZE, NULL); 4579 } 4580 mac->mac_key[i].keyconf = NULL; 4581 } 4582} 4583 4584static void 4585bwn_crypt_init(struct bwn_mac *mac) 4586{ 4587 4588 mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20; 4589 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4590 ("%s:%d: fail", __func__, __LINE__)); 4591 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4592 mac->mac_ktp *= 2; 4593 if (mac->mac_sd->sd_id.sd_rev >= 5) { 4594 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, 4595 mac->mac_max_nr_keys - 8); 4596 } 4597 bwn_clear_keys(mac); 4598} 4599 4600static void 4601bwn_chip_exit(struct bwn_mac *mac) 4602{ 4603 4604 bwn_phy_exit(mac); 4605 bwn_gpio_cleanup(mac); 4606} 4607 4608static int 4609bwn_fw_fillinfo(struct bwn_mac *mac) 4610{ 4611 int error; 4612 4613 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4614 if (error == 0) 4615 return (0); 4616 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4617 if (error == 0) 4618 return (0); 4619 return (error); 4620} 4621 4622static int 4623bwn_gpio_init(struct bwn_mac *mac) 4624{ 4625 struct siba_softc *bus = mac->mac_sd->sd_bus; 4626 struct siba_dev_softc *sd; 4627 uint32_t mask = 0x0000001f, set = 0x0000000f; 4628 4629 BWN_WRITE_4(mac, BWN_MACCTL, 4630 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4631 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4632 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4633 4634 if (bus->siba_chipid == 0x4301) { 4635 mask |= 0x0060; 4636 set |= 0x0060; 4637 } 4638 if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) { 4639 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4640 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4641 mask |= 0x0200; 4642 set |= 0x0200; 4643 } 4644 if (mac->mac_sd->sd_id.sd_rev >= 2) 4645 mask |= 0x0010; 4646 sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev : 4647 bus->siba_pci.spc_dev; 4648 if (sd == NULL) 4649 return (0); 4650 siba_write_4(sd, BWN_GPIOCTL, 4651 (siba_read_4(sd, BWN_GPIOCTL) & mask) | set); 4652 4653 return (0); 4654} 4655 4656static int 4657bwn_fw_loadinitvals(struct bwn_mac *mac) 4658{ 4659#define GETFWOFFSET(fwp, offset) \ 4660 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4661 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4662 const struct bwn_fwhdr *hdr; 4663 struct bwn_fw *fw = &mac->mac_fw; 4664 int error; 4665 4666 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4667 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4668 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4669 if (error) 4670 return (error); 4671 if (fw->initvals_band.fw) { 4672 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4673 error = bwn_fwinitvals_write(mac, 4674 GETFWOFFSET(fw->initvals_band, hdr_len), 4675 be32toh(hdr->size), 4676 fw->initvals_band.fw->datasize - hdr_len); 4677 } 4678 return (error); 4679#undef GETFWOFFSET 4680} 4681 4682static int 4683bwn_phy_init(struct bwn_mac *mac) 4684{ 4685 struct bwn_softc *sc = mac->mac_sc; 4686 int error; 4687 4688 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4689 mac->mac_phy.rf_onoff(mac, 1); 4690 error = mac->mac_phy.init(mac); 4691 if (error) { 4692 device_printf(sc->sc_dev, "PHY init failed\n"); 4693 goto fail0; 4694 } 4695 error = bwn_switch_channel(mac, 4696 mac->mac_phy.get_default_chan(mac)); 4697 if (error) { 4698 device_printf(sc->sc_dev, 4699 "failed to switch default channel\n"); 4700 goto fail1; 4701 } 4702 return (0); 4703fail1: 4704 if (mac->mac_phy.exit) 4705 mac->mac_phy.exit(mac); 4706fail0: 4707 mac->mac_phy.rf_onoff(mac, 0); 4708 4709 return (error); 4710} 4711 4712static void 4713bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4714{ 4715 uint16_t ant; 4716 uint16_t tmp; 4717 4718 ant = bwn_ant2phy(antenna); 4719 4720 /* For ACK/CTS */ 4721 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4722 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4723 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4724 /* For Probe Resposes */ 4725 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4726 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4727 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4728} 4729 4730static void 4731bwn_set_opmode(struct bwn_mac *mac) 4732{ 4733 struct bwn_softc *sc = mac->mac_sc; 4734 struct ifnet *ifp = sc->sc_ifp; 4735 struct ieee80211com *ic = ifp->if_l2com; 4736 uint32_t ctl; 4737 uint16_t cfp_pretbtt; 4738 4739 ctl = BWN_READ_4(mac, BWN_MACCTL); 4740 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4741 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4742 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4743 ctl |= BWN_MACCTL_STA; 4744 4745 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4746 ic->ic_opmode == IEEE80211_M_MBSS) 4747 ctl |= BWN_MACCTL_HOSTAP; 4748 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4749 ctl &= ~BWN_MACCTL_STA; 4750 ctl |= sc->sc_filters; 4751 4752 if (mac->mac_sd->sd_id.sd_rev <= 4) 4753 ctl |= BWN_MACCTL_PROMISC; 4754 4755 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4756 4757 cfp_pretbtt = 2; 4758 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4759 if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 && 4760 mac->mac_sd->sd_bus->siba_chiprev == 3) 4761 cfp_pretbtt = 100; 4762 else 4763 cfp_pretbtt = 50; 4764 } 4765 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4766} 4767 4768static void 4769bwn_gpio_cleanup(struct bwn_mac *mac) 4770{ 4771 struct siba_softc *bus = mac->mac_sd->sd_bus; 4772 struct siba_dev_softc *gpiodev, *pcidev = NULL; 4773 4774 pcidev = bus->siba_pci.spc_dev; 4775 gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev; 4776 if (!gpiodev) 4777 return; 4778 siba_write_4(gpiodev, BWN_GPIOCTL, 0); 4779} 4780 4781static int 4782bwn_dma_gettype(struct bwn_mac *mac) 4783{ 4784 uint32_t tmp; 4785 uint16_t base; 4786 4787 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4788 if (tmp & SIBA_TGSHIGH_DMA64) 4789 return (BWN_DMA_64BIT); 4790 base = bwn_dma_base(0, 0); 4791 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4792 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4793 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4794 return (BWN_DMA_32BIT); 4795 4796 return (BWN_DMA_30BIT); 4797} 4798 4799static void 4800bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4801{ 4802 if (!error) { 4803 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4804 *((bus_addr_t *)arg) = seg->ds_addr; 4805 } 4806} 4807 4808static void 4809bwn_phy_g_init_sub(struct bwn_mac *mac) 4810{ 4811 struct bwn_phy *phy = &mac->mac_phy; 4812 struct bwn_phy_g *pg = &phy->phy_g; 4813 uint16_t i, tmp; 4814 4815 if (phy->rev == 1) 4816 bwn_phy_init_b5(mac); 4817 else 4818 bwn_phy_init_b6(mac); 4819 4820 if (phy->rev >= 2 || phy->gmode) 4821 bwn_phy_init_a(mac); 4822 4823 if (phy->rev >= 2) { 4824 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4825 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4826 } 4827 if (phy->rev == 2) { 4828 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4829 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4830 } 4831 if (phy->rev > 5) { 4832 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4833 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4834 } 4835 if (phy->gmode || phy->rev >= 2) { 4836 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4837 tmp &= BWN_PHYVER_VERSION; 4838 if (tmp == 3 || tmp == 5) { 4839 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4840 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4841 } 4842 if (tmp == 5) { 4843 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4844 0x1f00); 4845 } 4846 } 4847 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4848 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4849 if (phy->rf_rev == 8) { 4850 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4851 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4852 } 4853 if (BWN_HAS_LOOPBACK(phy)) 4854 bwn_loopback_calcgain(mac); 4855 4856 if (phy->rf_rev != 8) { 4857 if (pg->pg_initval == 0xffff) 4858 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4859 else 4860 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4861 } 4862 bwn_lo_g_init(mac); 4863 if (BWN_HAS_TXMAG(phy)) { 4864 BWN_RF_WRITE(mac, 0x52, 4865 (BWN_RF_READ(mac, 0x52) & 0xff00) 4866 | pg->pg_loctl.tx_bias | 4867 pg->pg_loctl.tx_magn); 4868 } else { 4869 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4870 } 4871 if (phy->rev >= 6) { 4872 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4873 (pg->pg_loctl.tx_bias << 12)); 4874 } 4875 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) 4876 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4877 else 4878 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4879 if (phy->rev < 2) 4880 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4881 else 4882 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4883 if (phy->gmode || phy->rev >= 2) { 4884 bwn_lo_g_adjust(mac); 4885 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4886 } 4887 4888 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 4889 for (i = 0; i < 64; i++) { 4890 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4891 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4892 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4893 -32), 31)); 4894 } 4895 bwn_nrssi_threshold(mac); 4896 } else if (phy->gmode || phy->rev >= 2) { 4897 if (pg->pg_nrssi[0] == -1000) { 4898 KASSERT(pg->pg_nrssi[1] == -1000, 4899 ("%s:%d: fail", __func__, __LINE__)); 4900 bwn_nrssi_slope_11g(mac); 4901 } else 4902 bwn_nrssi_threshold(mac); 4903 } 4904 if (phy->rf_rev == 8) 4905 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4906 bwn_phy_hwpctl_init(mac); 4907 if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306 4908 && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) { 4909 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4910 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4911 } 4912} 4913 4914static uint8_t 4915bwn_has_hwpctl(struct bwn_mac *mac) 4916{ 4917 4918 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4919 return (0); 4920 return (mac->mac_phy.use_hwpctl(mac)); 4921} 4922 4923static void 4924bwn_phy_init_b5(struct bwn_mac *mac) 4925{ 4926 struct siba_softc *bus = mac->mac_sd->sd_bus; 4927 struct bwn_phy *phy = &mac->mac_phy; 4928 struct bwn_phy_g *pg = &phy->phy_g; 4929 uint16_t offset, value; 4930 uint8_t old_channel; 4931 4932 if (phy->analog == 1) 4933 BWN_RF_SET(mac, 0x007a, 0x0050); 4934 if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) && 4935 (bus->siba_board_type != SIBA_BOARD_BU4306)) { 4936 value = 0x2120; 4937 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4938 BWN_PHY_WRITE(mac, offset, value); 4939 value += 0x202; 4940 } 4941 } 4942 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4943 if (phy->rf_ver == 0x2050) 4944 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4945 4946 if (phy->gmode || phy->rev >= 2) { 4947 if (phy->rf_ver == 0x2050) { 4948 BWN_RF_SET(mac, 0x007a, 0x0020); 4949 BWN_RF_SET(mac, 0x0051, 0x0004); 4950 } 4951 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4952 4953 BWN_PHY_SET(mac, 0x0802, 0x0100); 4954 BWN_PHY_SET(mac, 0x042b, 0x2000); 4955 4956 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4957 4958 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4959 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4960 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4961 } 4962 4963 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4964 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4965 4966 if (phy->analog == 1) { 4967 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4968 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4969 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4970 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4971 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4972 } else 4973 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4974 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4975 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4976 4977 if (phy->analog == 1) 4978 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4979 else 4980 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4981 4982 if (phy->analog == 0) 4983 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4984 4985 old_channel = phy->chan; 4986 bwn_phy_g_switch_chan(mac, 7, 0); 4987 4988 if (phy->rf_ver != 0x2050) { 4989 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4990 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4991 } 4992 4993 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4994 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4995 4996 if (phy->rf_ver == 0x2050) { 4997 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4998 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4999 } 5000 5001 BWN_RF_WRITE(mac, 0x005b, 0x007b); 5002 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 5003 BWN_RF_SET(mac, 0x007a, 0x0007); 5004 5005 bwn_phy_g_switch_chan(mac, old_channel, 0); 5006 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 5007 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 5008 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 5009 5010 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5011 pg->pg_txctl); 5012 5013 if (phy->rf_ver == 0x2050) 5014 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5015 5016 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 5017} 5018 5019static void 5020bwn_loopback_calcgain(struct bwn_mac *mac) 5021{ 5022 struct bwn_phy *phy = &mac->mac_phy; 5023 struct bwn_phy_g *pg = &phy->phy_g; 5024 uint16_t backup_phy[16] = { 0 }; 5025 uint16_t backup_radio[3]; 5026 uint16_t backup_bband; 5027 uint16_t i, j, loop_i_max; 5028 uint16_t trsw_rx; 5029 uint16_t loop1_outer_done, loop1_inner_done; 5030 5031 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5032 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 5033 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5034 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5035 if (phy->rev != 1) { 5036 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5037 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5038 } 5039 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5040 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5041 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5042 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 5043 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 5044 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5045 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5046 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 5047 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5048 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5049 backup_bband = pg->pg_bbatt.att; 5050 backup_radio[0] = BWN_RF_READ(mac, 0x52); 5051 backup_radio[1] = BWN_RF_READ(mac, 0x43); 5052 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 5053 5054 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 5055 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 5056 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 5057 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 5058 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 5059 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 5060 if (phy->rev != 1) { 5061 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 5062 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 5063 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 5064 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 5065 } 5066 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 5067 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 5068 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 5069 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 5070 5071 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 5072 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5073 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5074 5075 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 5076 if (phy->rev != 1) { 5077 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 5078 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 5079 } 5080 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 5081 5082 if (phy->rf_rev == 8) 5083 BWN_RF_WRITE(mac, 0x43, 0x000f); 5084 else { 5085 BWN_RF_WRITE(mac, 0x52, 0); 5086 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 5087 } 5088 bwn_phy_g_set_bbatt(mac, 11); 5089 5090 if (phy->rev >= 3) 5091 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5092 else 5093 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5094 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5095 5096 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5097 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5098 5099 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5100 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5101 5102 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) { 5103 if (phy->rev >= 7) { 5104 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5105 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5106 } 5107 } 5108 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5109 5110 j = 0; 5111 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5112 for (i = 0; i < loop_i_max; i++) { 5113 for (j = 0; j < 16; j++) { 5114 BWN_RF_WRITE(mac, 0x43, i); 5115 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5116 (j << 8)); 5117 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5118 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5119 DELAY(20); 5120 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5121 goto done0; 5122 } 5123 } 5124done0: 5125 loop1_outer_done = i; 5126 loop1_inner_done = j; 5127 if (j >= 8) { 5128 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5129 trsw_rx = 0x1b; 5130 for (j = j - 8; j < 16; j++) { 5131 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5132 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5133 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5134 DELAY(20); 5135 trsw_rx -= 3; 5136 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5137 goto done1; 5138 } 5139 } else 5140 trsw_rx = 0x18; 5141done1: 5142 5143 if (phy->rev != 1) { 5144 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5145 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5146 } 5147 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5148 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5150 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5151 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5152 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5153 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5154 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5155 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5156 5157 bwn_phy_g_set_bbatt(mac, backup_bband); 5158 5159 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5160 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5161 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5162 5163 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5164 DELAY(10); 5165 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5166 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5167 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5168 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5169 5170 pg->pg_max_lb_gain = 5171 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5172 pg->pg_trsw_rx_gain = trsw_rx * 2; 5173} 5174 5175static uint16_t 5176bwn_rf_init_bcm2050(struct bwn_mac *mac) 5177{ 5178 struct bwn_phy *phy = &mac->mac_phy; 5179 uint32_t tmp1 = 0, tmp2 = 0; 5180 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5181 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5182 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5183 static const uint8_t rcc_table[] = { 5184 0x02, 0x03, 0x01, 0x0f, 5185 0x06, 0x07, 0x05, 0x0f, 5186 0x0a, 0x0b, 0x09, 0x0f, 5187 0x0e, 0x0f, 0x0d, 0x0f, 5188 }; 5189 5190 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5191 rfoverval = rfover = cck3 = 0; 5192 radio0 = BWN_RF_READ(mac, 0x43); 5193 radio1 = BWN_RF_READ(mac, 0x51); 5194 radio2 = BWN_RF_READ(mac, 0x52); 5195 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5196 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5197 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5198 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5199 5200 if (phy->type == BWN_PHYTYPE_B) { 5201 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5202 reg0 = BWN_READ_2(mac, 0x3ec); 5203 5204 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5205 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5206 } else if (phy->gmode || phy->rev >= 2) { 5207 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5208 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5209 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5210 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5211 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5212 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5213 5214 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5215 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5216 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5217 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5218 if (BWN_HAS_LOOPBACK(phy)) { 5219 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5220 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5221 if (phy->rev >= 3) 5222 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5223 else 5224 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5225 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5226 } 5227 5228 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5229 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5230 BWN_LPD(0, 1, 1))); 5231 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5232 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5233 } 5234 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5235 5236 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5237 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5238 reg1 = BWN_READ_2(mac, 0x3e6); 5239 reg2 = BWN_READ_2(mac, 0x3f4); 5240 5241 if (phy->analog == 0) 5242 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5243 else { 5244 if (phy->analog >= 2) 5245 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5246 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5247 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5248 } 5249 5250 reg = BWN_RF_READ(mac, 0x60); 5251 index = (reg & 0x001e) >> 1; 5252 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5253 5254 if (phy->type == BWN_PHYTYPE_B) 5255 BWN_RF_WRITE(mac, 0x78, 0x26); 5256 if (phy->gmode || phy->rev >= 2) { 5257 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5258 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5259 BWN_LPD(0, 1, 1))); 5260 } 5261 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5262 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5263 if (phy->gmode || phy->rev >= 2) { 5264 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5265 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5266 BWN_LPD(0, 0, 1))); 5267 } 5268 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5269 BWN_RF_SET(mac, 0x51, 0x0004); 5270 if (phy->rf_rev == 8) 5271 BWN_RF_WRITE(mac, 0x43, 0x1f); 5272 else { 5273 BWN_RF_WRITE(mac, 0x52, 0); 5274 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5275 } 5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5277 5278 for (i = 0; i < 16; i++) { 5279 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5280 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5281 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5282 if (phy->gmode || phy->rev >= 2) { 5283 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5284 bwn_rf_2050_rfoverval(mac, 5285 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5286 } 5287 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5288 DELAY(10); 5289 if (phy->gmode || phy->rev >= 2) { 5290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5291 bwn_rf_2050_rfoverval(mac, 5292 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5293 } 5294 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5295 DELAY(10); 5296 if (phy->gmode || phy->rev >= 2) { 5297 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5298 bwn_rf_2050_rfoverval(mac, 5299 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5300 } 5301 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5302 DELAY(20); 5303 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5304 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5305 if (phy->gmode || phy->rev >= 2) { 5306 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5307 bwn_rf_2050_rfoverval(mac, 5308 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5309 } 5310 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5311 } 5312 DELAY(10); 5313 5314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5315 tmp1++; 5316 tmp1 >>= 9; 5317 5318 for (i = 0; i < 16; i++) { 5319 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5320 BWN_RF_WRITE(mac, 0x78, radio78); 5321 DELAY(10); 5322 for (j = 0; j < 16; j++) { 5323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5324 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5326 if (phy->gmode || phy->rev >= 2) { 5327 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5328 bwn_rf_2050_rfoverval(mac, 5329 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5330 } 5331 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5332 DELAY(10); 5333 if (phy->gmode || phy->rev >= 2) { 5334 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5335 bwn_rf_2050_rfoverval(mac, 5336 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5337 } 5338 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5339 DELAY(10); 5340 if (phy->gmode || phy->rev >= 2) { 5341 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5342 bwn_rf_2050_rfoverval(mac, 5343 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5344 } 5345 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5346 DELAY(10); 5347 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5348 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5349 if (phy->gmode || phy->rev >= 2) { 5350 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5351 bwn_rf_2050_rfoverval(mac, 5352 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5353 } 5354 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5355 } 5356 tmp2++; 5357 tmp2 >>= 8; 5358 if (tmp1 < tmp2) 5359 break; 5360 } 5361 5362 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5363 BWN_RF_WRITE(mac, 0x51, radio1); 5364 BWN_RF_WRITE(mac, 0x52, radio2); 5365 BWN_RF_WRITE(mac, 0x43, radio0); 5366 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5367 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5368 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5369 BWN_WRITE_2(mac, 0x3e6, reg1); 5370 if (phy->analog != 0) 5371 BWN_WRITE_2(mac, 0x3f4, reg2); 5372 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5373 bwn_spu_workaround(mac, phy->chan); 5374 if (phy->type == BWN_PHYTYPE_B) { 5375 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5376 BWN_WRITE_2(mac, 0x3ec, reg0); 5377 } else if (phy->gmode) { 5378 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5379 BWN_READ_2(mac, BWN_PHY_RADIO) 5380 & 0x7fff); 5381 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5382 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5383 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5384 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5385 analogoverval); 5386 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5387 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5388 if (BWN_HAS_LOOPBACK(phy)) { 5389 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5390 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5391 } 5392 } 5393 5394 return ((i > 15) ? radio78 : rcc); 5395} 5396 5397static void 5398bwn_phy_init_b6(struct bwn_mac *mac) 5399{ 5400 struct bwn_phy *phy = &mac->mac_phy; 5401 struct bwn_phy_g *pg = &phy->phy_g; 5402 uint16_t offset, val; 5403 uint8_t old_channel; 5404 5405 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5406 ("%s:%d: fail", __func__, __LINE__)); 5407 5408 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5409 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5410 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5411 BWN_RF_WRITE(mac, 0x51, 0x37); 5412 BWN_RF_WRITE(mac, 0x52, 0x70); 5413 BWN_RF_WRITE(mac, 0x53, 0xb3); 5414 BWN_RF_WRITE(mac, 0x54, 0x9b); 5415 BWN_RF_WRITE(mac, 0x5a, 0x88); 5416 BWN_RF_WRITE(mac, 0x5b, 0x88); 5417 BWN_RF_WRITE(mac, 0x5d, 0x88); 5418 BWN_RF_WRITE(mac, 0x5e, 0x88); 5419 BWN_RF_WRITE(mac, 0x7d, 0x88); 5420 bwn_hf_write(mac, 5421 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5422 } 5423 if (phy->rf_rev == 8) { 5424 BWN_RF_WRITE(mac, 0x51, 0); 5425 BWN_RF_WRITE(mac, 0x52, 0x40); 5426 BWN_RF_WRITE(mac, 0x53, 0xb7); 5427 BWN_RF_WRITE(mac, 0x54, 0x98); 5428 BWN_RF_WRITE(mac, 0x5a, 0x88); 5429 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5430 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5431 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) { 5432 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5433 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5434 } else { 5435 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5436 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5437 } 5438 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5439 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5440 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5441 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5442 } 5443 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5444 BWN_PHY_WRITE(mac, offset, val); 5445 val -= 0x0202; 5446 } 5447 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5448 BWN_PHY_WRITE(mac, offset, val); 5449 val -= 0x0202; 5450 } 5451 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5452 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5453 val += 0x0202; 5454 } 5455 if (phy->type == BWN_PHYTYPE_G) { 5456 BWN_RF_SET(mac, 0x007a, 0x0020); 5457 BWN_RF_SET(mac, 0x0051, 0x0004); 5458 BWN_PHY_SET(mac, 0x0802, 0x0100); 5459 BWN_PHY_SET(mac, 0x042b, 0x2000); 5460 BWN_PHY_WRITE(mac, 0x5b, 0); 5461 BWN_PHY_WRITE(mac, 0x5c, 0); 5462 } 5463 5464 old_channel = phy->chan; 5465 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5466 5467 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5468 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5469 DELAY(40); 5470 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5471 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5472 BWN_RF_WRITE(mac, 0x50, 0x20); 5473 } 5474 if (phy->rf_rev <= 2) { 5475 BWN_RF_WRITE(mac, 0x7c, 0x20); 5476 BWN_RF_WRITE(mac, 0x5a, 0x70); 5477 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5478 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5479 } 5480 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5481 5482 bwn_phy_g_switch_chan(mac, old_channel, 0); 5483 5484 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5485 if (phy->rf_rev >= 6) 5486 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5487 else 5488 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5489 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5490 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5491 pg->pg_txctl); 5492 if (phy->rf_rev <= 5) 5493 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5494 if (phy->rf_rev <= 2) 5495 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5496 5497 if (phy->analog == 4) { 5498 BWN_WRITE_2(mac, 0x3e4, 9); 5499 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5500 } else 5501 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5502 if (phy->type == BWN_PHYTYPE_B) 5503 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5504 else if (phy->type == BWN_PHYTYPE_G) 5505 BWN_WRITE_2(mac, 0x03e6, 0x0); 5506} 5507 5508static void 5509bwn_phy_init_a(struct bwn_mac *mac) 5510{ 5511 struct bwn_phy *phy = &mac->mac_phy; 5512 5513 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5514 ("%s:%d: fail", __func__, __LINE__)); 5515 5516 if (phy->rev >= 6) { 5517 if (phy->type == BWN_PHYTYPE_A) 5518 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5519 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5520 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5521 else 5522 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5523 } 5524 5525 bwn_wa_init(mac); 5526 5527 if (phy->type == BWN_PHYTYPE_G && 5528 (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)) 5529 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5530} 5531 5532static void 5533bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5534{ 5535 int i; 5536 5537 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5538 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5539} 5540 5541static void 5542bwn_wa_agc(struct bwn_mac *mac) 5543{ 5544 struct bwn_phy *phy = &mac->mac_phy; 5545 5546 if (phy->rev == 1) { 5547 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5548 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5549 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5550 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5551 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5552 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5554 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5555 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5556 } else { 5557 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5561 } 5562 5563 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5564 0x5700); 5565 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5566 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5567 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5568 BWN_RF_SET(mac, 0x7a, 0x0008); 5569 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5570 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5571 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5572 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5573 if (phy->rev == 1) 5574 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5575 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5576 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5577 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5578 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5579 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5580 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5581 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5582 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5583 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5584 if (phy->rev == 1) { 5585 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5586 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5587 } else { 5588 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5589 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5590 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5591 if (phy->rev >= 6) { 5592 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5593 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5594 (uint16_t)~0xf000, 0x3000); 5595 } 5596 } 5597 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5598 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5599 if (phy->rev == 1) { 5600 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5601 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5602 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5603 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5604 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5605 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5606 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5607 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5608 } else { 5609 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5610 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5611 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5613 } 5614 if (phy->rev >= 6) { 5615 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5616 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5617 } 5618 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5619} 5620 5621static void 5622bwn_wa_grev1(struct bwn_mac *mac) 5623{ 5624 struct bwn_phy *phy = &mac->mac_phy; 5625 int i; 5626 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5627 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5628 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5629 5630 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5631 5632 /* init CRSTHRES and ANTDWELL */ 5633 if (phy->rev == 1) { 5634 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5635 } else if (phy->rev == 2) { 5636 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5637 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5638 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5639 } else { 5640 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5641 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5642 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5643 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5644 } 5645 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5646 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5647 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5648 5649 /* XXX support PHY-A??? */ 5650 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5651 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5652 bwn_tab_finefreqg[i]); 5653 5654 /* XXX support PHY-A??? */ 5655 if (phy->rev == 1) 5656 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5657 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5658 bwn_tab_noise_g1[i]); 5659 else 5660 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5662 bwn_tab_noise_g2[i]); 5663 5664 5665 for (i = 0; i < N(bwn_tab_rotor); i++) 5666 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5667 bwn_tab_rotor[i]); 5668 5669 /* XXX support PHY-A??? */ 5670 if (phy->rev >= 6) { 5671 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5672 BWN_PHY_ENCORE_EN) 5673 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5674 else 5675 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5676 } else 5677 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5678 5679 for (i = 0; i < N(bwn_tab_retard); i++) 5680 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5681 bwn_tab_retard[i]); 5682 5683 if (phy->rev == 1) { 5684 for (i = 0; i < 16; i++) 5685 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5686 i, 0x0020); 5687 } else { 5688 for (i = 0; i < 32; i++) 5689 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5690 } 5691 5692 bwn_wa_agc(mac); 5693} 5694 5695static void 5696bwn_wa_grev26789(struct bwn_mac *mac) 5697{ 5698 struct bwn_phy *phy = &mac->mac_phy; 5699 int i; 5700 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5701 uint16_t ofdmrev; 5702 5703 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5704 5705 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5706 5707 /* init CRSTHRES and ANTDWELL */ 5708 if (phy->rev == 1) 5709 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5710 else if (phy->rev == 2) { 5711 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5712 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5713 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5714 } else { 5715 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5716 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5717 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5718 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5719 } 5720 5721 for (i = 0; i < 64; i++) 5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5723 5724 /* XXX support PHY-A??? */ 5725 if (phy->rev == 1) 5726 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5728 bwn_tab_noise_g1[i]); 5729 else 5730 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5731 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5732 bwn_tab_noise_g2[i]); 5733 5734 /* XXX support PHY-A??? */ 5735 if (phy->rev >= 6) { 5736 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5737 BWN_PHY_ENCORE_EN) 5738 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5739 else 5740 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5741 } else 5742 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5743 5744 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5745 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5746 bwn_tab_sigmasqr2[i]); 5747 5748 if (phy->rev == 1) { 5749 for (i = 0; i < 16; i++) 5750 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5751 0x0020); 5752 } else { 5753 for (i = 0; i < 32; i++) 5754 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5755 } 5756 5757 bwn_wa_agc(mac); 5758 5759 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5760 if (ofdmrev > 2) { 5761 if (phy->type == BWN_PHYTYPE_A) 5762 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5763 else 5764 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5765 } else { 5766 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5767 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5768 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5769 } 5770 5771 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5772 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5773} 5774 5775static void 5776bwn_wa_init(struct bwn_mac *mac) 5777{ 5778 struct bwn_phy *phy = &mac->mac_phy; 5779 struct siba_softc *bus = mac->mac_sd->sd_bus; 5780 5781 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5782 5783 switch (phy->rev) { 5784 case 1: 5785 bwn_wa_grev1(mac); 5786 break; 5787 case 2: 5788 case 6: 5789 case 7: 5790 case 8: 5791 case 9: 5792 bwn_wa_grev26789(mac); 5793 break; 5794 default: 5795 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5796 } 5797 5798 if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM || 5799 bus->siba_board_type != SIBA_BOARD_BU4306 || 5800 bus->siba_board_rev != 0x17) { 5801 if (phy->rev < 2) { 5802 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5803 0x0002); 5804 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5805 0x0001); 5806 } else { 5807 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5808 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5809 if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) && 5810 (phy->rev >= 7)) { 5811 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5812 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5813 0x0020, 0x0001); 5814 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5815 0x0021, 0x0001); 5816 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5817 0x0022, 0x0001); 5818 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5819 0x0023, 0x0000); 5820 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5821 0x0000, 0x0000); 5822 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5823 0x0003, 0x0002); 5824 } 5825 } 5826 } 5827 if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) { 5828 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5829 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5830 } 5831 5832 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5833 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5834} 5835 5836static void 5837bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5838 uint16_t value) 5839{ 5840 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5841 uint16_t addr; 5842 5843 addr = table + offset; 5844 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5845 (addr - 1 != pg->pg_ofdmtab_addr)) { 5846 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5847 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5848 } 5849 pg->pg_ofdmtab_addr = addr; 5850 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5851} 5852 5853static void 5854bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5855 uint32_t value) 5856{ 5857 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5858 uint16_t addr; 5859 5860 addr = table + offset; 5861 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5862 (addr - 1 != pg->pg_ofdmtab_addr)) { 5863 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5864 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5865 } 5866 pg->pg_ofdmtab_addr = addr; 5867 5868 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5869 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5870} 5871 5872static void 5873bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5874 uint16_t value) 5875{ 5876 5877 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5878 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5879} 5880 5881static void 5882bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5883{ 5884 struct bwn_phy *phy = &mac->mac_phy; 5885 unsigned int i, max_loop; 5886 uint16_t value; 5887 uint32_t buffer[5] = { 5888 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5889 }; 5890 5891 if (ofdm) { 5892 max_loop = 0x1e; 5893 buffer[0] = 0x000201cc; 5894 } else { 5895 max_loop = 0xfa; 5896 buffer[0] = 0x000b846e; 5897 } 5898 5899 BWN_ASSERT_LOCKED(mac->mac_sc); 5900 5901 for (i = 0; i < 5; i++) 5902 bwn_ram_write(mac, i * 4, buffer[i]); 5903 5904 BWN_WRITE_2(mac, 0x0568, 0x0000); 5905 BWN_WRITE_2(mac, 0x07c0, 5906 (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100); 5907 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5908 BWN_WRITE_2(mac, 0x050c, value); 5909 if (phy->type == BWN_PHYTYPE_LP) 5910 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5911 BWN_WRITE_2(mac, 0x0508, 0x0000); 5912 BWN_WRITE_2(mac, 0x050a, 0x0000); 5913 BWN_WRITE_2(mac, 0x054c, 0x0000); 5914 BWN_WRITE_2(mac, 0x056a, 0x0014); 5915 BWN_WRITE_2(mac, 0x0568, 0x0826); 5916 BWN_WRITE_2(mac, 0x0500, 0x0000); 5917 if (phy->type == BWN_PHYTYPE_LP) 5918 BWN_WRITE_2(mac, 0x0502, 0x0050); 5919 else 5920 BWN_WRITE_2(mac, 0x0502, 0x0030); 5921 5922 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5923 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5924 for (i = 0x00; i < max_loop; i++) { 5925 value = BWN_READ_2(mac, 0x050e); 5926 if (value & 0x0080) 5927 break; 5928 DELAY(10); 5929 } 5930 for (i = 0x00; i < 0x0a; i++) { 5931 value = BWN_READ_2(mac, 0x050e); 5932 if (value & 0x0400) 5933 break; 5934 DELAY(10); 5935 } 5936 for (i = 0x00; i < 0x19; i++) { 5937 value = BWN_READ_2(mac, 0x0690); 5938 if (!(value & 0x0100)) 5939 break; 5940 DELAY(10); 5941 } 5942 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5943 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5944} 5945 5946static void 5947bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5948{ 5949 uint32_t macctl; 5950 5951 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5952 5953 macctl = BWN_READ_4(mac, BWN_MACCTL); 5954 if (macctl & BWN_MACCTL_BIGENDIAN) 5955 printf("TODO: need swap\n"); 5956 5957 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5958 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5959 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5960} 5961 5962static void 5963bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5964{ 5965 uint16_t value; 5966 5967 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5968 ("%s:%d: fail", __func__, __LINE__)); 5969 5970 value = (uint8_t) (ctl->q); 5971 value |= ((uint8_t) (ctl->i)) << 8; 5972 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5973} 5974 5975static uint16_t 5976bwn_lo_calcfeed(struct bwn_mac *mac, 5977 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5978{ 5979 struct bwn_phy *phy = &mac->mac_phy; 5980 uint16_t rfover; 5981 uint16_t feedthrough; 5982 5983 if (phy->gmode) { 5984 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5985 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5986 5987 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5988 ("%s:%d: fail", __func__, __LINE__)); 5989 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5990 ("%s:%d: fail", __func__, __LINE__)); 5991 5992 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5993 5994 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5995 if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) 5996 && phy->rev > 6) 5997 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5998 5999 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6000 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6001 DELAY(10); 6002 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 6003 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6004 DELAY(10); 6005 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 6006 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6007 DELAY(10); 6008 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 6009 } else { 6010 pga |= BWN_PHY_PGACTL_UNKNOWN; 6011 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6012 DELAY(10); 6013 pga |= BWN_PHY_PGACTL_LOWBANDW; 6014 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6015 DELAY(10); 6016 pga |= BWN_PHY_PGACTL_LPF; 6017 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6018 } 6019 DELAY(21); 6020 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 6021 6022 return (feedthrough); 6023} 6024 6025static uint16_t 6026bwn_lo_txctl_regtable(struct bwn_mac *mac, 6027 uint16_t *value, uint16_t *pad_mix_gain) 6028{ 6029 struct bwn_phy *phy = &mac->mac_phy; 6030 uint16_t reg, v, padmix; 6031 6032 if (phy->type == BWN_PHYTYPE_B) { 6033 v = 0x30; 6034 if (phy->rf_rev <= 5) { 6035 reg = 0x43; 6036 padmix = 0; 6037 } else { 6038 reg = 0x52; 6039 padmix = 5; 6040 } 6041 } else { 6042 if (phy->rev >= 2 && phy->rf_rev == 8) { 6043 reg = 0x43; 6044 v = 0x10; 6045 padmix = 2; 6046 } else { 6047 reg = 0x52; 6048 v = 0x30; 6049 padmix = 5; 6050 } 6051 } 6052 if (value) 6053 *value = v; 6054 if (pad_mix_gain) 6055 *pad_mix_gain = padmix; 6056 6057 return (reg); 6058} 6059 6060static void 6061bwn_lo_measure_txctl_values(struct bwn_mac *mac) 6062{ 6063 struct bwn_phy *phy = &mac->mac_phy; 6064 struct bwn_phy_g *pg = &phy->phy_g; 6065 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6066 uint16_t reg, mask; 6067 uint16_t trsw_rx, pga; 6068 uint16_t rf_pctl_reg; 6069 6070 static const uint8_t tx_bias_values[] = { 6071 0x09, 0x08, 0x0a, 0x01, 0x00, 6072 0x02, 0x05, 0x04, 0x06, 6073 }; 6074 static const uint8_t tx_magn_values[] = { 6075 0x70, 0x40, 6076 }; 6077 6078 if (!BWN_HAS_LOOPBACK(phy)) { 6079 rf_pctl_reg = 6; 6080 trsw_rx = 2; 6081 pga = 0; 6082 } else { 6083 int lb_gain; 6084 6085 trsw_rx = 0; 6086 lb_gain = pg->pg_max_lb_gain / 2; 6087 if (lb_gain > 10) { 6088 rf_pctl_reg = 0; 6089 pga = abs(10 - lb_gain) / 6; 6090 pga = MIN(MAX(pga, 0), 15); 6091 } else { 6092 int cmp_val; 6093 int tmp; 6094 6095 pga = 0; 6096 cmp_val = 0x24; 6097 if ((phy->rev >= 2) && 6098 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6099 cmp_val = 0x3c; 6100 tmp = lb_gain; 6101 if ((10 - lb_gain) < cmp_val) 6102 tmp = (10 - lb_gain); 6103 if (tmp < 0) 6104 tmp += 6; 6105 else 6106 tmp += 3; 6107 cmp_val /= 4; 6108 tmp /= 4; 6109 if (tmp >= cmp_val) 6110 rf_pctl_reg = cmp_val; 6111 else 6112 rf_pctl_reg = tmp; 6113 } 6114 } 6115 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6116 bwn_phy_g_set_bbatt(mac, 2); 6117 6118 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6119 mask = ~mask; 6120 BWN_RF_MASK(mac, reg, mask); 6121 6122 if (BWN_HAS_TXMAG(phy)) { 6123 int i, j; 6124 int feedthrough; 6125 int min_feedth = 0xffff; 6126 uint8_t tx_magn, tx_bias; 6127 6128 for (i = 0; i < N(tx_magn_values); i++) { 6129 tx_magn = tx_magn_values[i]; 6130 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6131 for (j = 0; j < N(tx_bias_values); j++) { 6132 tx_bias = tx_bias_values[j]; 6133 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6134 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6135 trsw_rx); 6136 if (feedthrough < min_feedth) { 6137 lo->tx_bias = tx_bias; 6138 lo->tx_magn = tx_magn; 6139 min_feedth = feedthrough; 6140 } 6141 if (lo->tx_bias == 0) 6142 break; 6143 } 6144 BWN_RF_WRITE(mac, 0x52, 6145 (BWN_RF_READ(mac, 0x52) 6146 & 0xff00) | lo->tx_bias | lo-> 6147 tx_magn); 6148 } 6149 } else { 6150 lo->tx_magn = 0; 6151 lo->tx_bias = 0; 6152 BWN_RF_MASK(mac, 0x52, 0xfff0); 6153 } 6154 6155 BWN_GETTIME(lo->txctl_measured_time); 6156} 6157 6158static void 6159bwn_lo_get_powervector(struct bwn_mac *mac) 6160{ 6161 struct bwn_phy *phy = &mac->mac_phy; 6162 struct bwn_phy_g *pg = &phy->phy_g; 6163 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6164 int i; 6165 uint64_t tmp; 6166 uint64_t power_vector = 0; 6167 6168 for (i = 0; i < 8; i += 2) { 6169 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6170 power_vector |= (tmp << (i * 8)); 6171 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6172 } 6173 if (power_vector) 6174 lo->power_vector = power_vector; 6175 6176 BWN_GETTIME(lo->pwr_vec_read_time); 6177} 6178 6179static void 6180bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6181 int use_trsw_rx) 6182{ 6183 struct bwn_phy *phy = &mac->mac_phy; 6184 struct bwn_phy_g *pg = &phy->phy_g; 6185 uint16_t tmp; 6186 6187 if (max_rx_gain < 0) 6188 max_rx_gain = 0; 6189 6190 if (BWN_HAS_LOOPBACK(phy)) { 6191 int trsw_rx = 0; 6192 int trsw_rx_gain; 6193 6194 if (use_trsw_rx) { 6195 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6196 if (max_rx_gain >= trsw_rx_gain) { 6197 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6198 trsw_rx = 0x20; 6199 } 6200 } else 6201 trsw_rx_gain = max_rx_gain; 6202 if (trsw_rx_gain < 9) { 6203 pg->pg_lna_lod_gain = 0; 6204 } else { 6205 pg->pg_lna_lod_gain = 1; 6206 trsw_rx_gain -= 8; 6207 } 6208 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6209 pg->pg_pga_gain = trsw_rx_gain / 3; 6210 if (pg->pg_pga_gain >= 5) { 6211 pg->pg_pga_gain -= 5; 6212 pg->pg_lna_gain = 2; 6213 } else 6214 pg->pg_lna_gain = 0; 6215 } else { 6216 pg->pg_lna_gain = 0; 6217 pg->pg_trsw_rx_gain = 0x20; 6218 if (max_rx_gain >= 0x14) { 6219 pg->pg_lna_lod_gain = 1; 6220 pg->pg_pga_gain = 2; 6221 } else if (max_rx_gain >= 0x12) { 6222 pg->pg_lna_lod_gain = 1; 6223 pg->pg_pga_gain = 1; 6224 } else if (max_rx_gain >= 0xf) { 6225 pg->pg_lna_lod_gain = 1; 6226 pg->pg_pga_gain = 0; 6227 } else { 6228 pg->pg_lna_lod_gain = 0; 6229 pg->pg_pga_gain = 0; 6230 } 6231 } 6232 6233 tmp = BWN_RF_READ(mac, 0x7a); 6234 if (pg->pg_lna_lod_gain == 0) 6235 tmp &= ~0x0008; 6236 else 6237 tmp |= 0x0008; 6238 BWN_RF_WRITE(mac, 0x7a, tmp); 6239} 6240 6241static void 6242bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6243{ 6244 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 6245 struct bwn_phy *phy = &mac->mac_phy; 6246 struct bwn_phy_g *pg = &phy->phy_g; 6247 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6248 struct timespec ts; 6249 uint16_t tmp; 6250 6251 if (bwn_has_hwpctl(mac)) { 6252 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6253 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6254 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6255 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6256 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6257 6258 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6259 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6260 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6261 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6262 } 6263 if (phy->type == BWN_PHYTYPE_B && 6264 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6265 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6266 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6267 } 6268 if (phy->rev >= 2) { 6269 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6270 sav->phy_analogoverval = 6271 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6272 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6273 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6274 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6275 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6276 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6277 6278 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6279 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6280 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6281 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6282 if (phy->type == BWN_PHYTYPE_G) { 6283 if ((phy->rev >= 7) && 6284 (sprom->bf_lo & BWN_BFL_EXTLNA)) { 6285 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6286 } else { 6287 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6288 } 6289 } else { 6290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6291 } 6292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6293 } 6294 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6295 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6296 sav->rf0 = BWN_RF_READ(mac, 0x43); 6297 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6298 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6299 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6300 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6301 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6302 6303 if (!BWN_HAS_TXMAG(phy)) { 6304 sav->rf2 = BWN_RF_READ(mac, 0x52); 6305 sav->rf2 &= 0x00f0; 6306 } 6307 if (phy->type == BWN_PHYTYPE_B) { 6308 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6309 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6310 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6311 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6312 } else { 6313 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6314 | 0x8000); 6315 } 6316 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6317 & 0xf000); 6318 6319 tmp = 6320 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6321 BWN_PHY_WRITE(mac, tmp, 0x007f); 6322 6323 tmp = sav->phy_syncctl; 6324 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6325 tmp = sav->rf1; 6326 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6327 6328 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6329 if (phy->type == BWN_PHYTYPE_G || 6330 (phy->type == BWN_PHYTYPE_B && 6331 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6332 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6333 } else 6334 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6335 if (phy->rev >= 2) 6336 bwn_dummy_transmission(mac, 0, 1); 6337 bwn_phy_g_switch_chan(mac, 6, 0); 6338 BWN_RF_READ(mac, 0x51); 6339 if (phy->type == BWN_PHYTYPE_G) 6340 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6341 6342 nanouptime(&ts); 6343 if (time_before(lo->txctl_measured_time, 6344 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6345 bwn_lo_measure_txctl_values(mac); 6346 6347 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6348 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6349 else { 6350 if (phy->type == BWN_PHYTYPE_B) 6351 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6352 else 6353 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6354 } 6355} 6356 6357static void 6358bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6359{ 6360 struct bwn_phy *phy = &mac->mac_phy; 6361 struct bwn_phy_g *pg = &phy->phy_g; 6362 uint16_t tmp; 6363 6364 if (phy->rev >= 2) { 6365 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6366 tmp = (pg->pg_pga_gain << 8); 6367 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6368 DELAY(5); 6369 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6370 DELAY(2); 6371 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6372 } else { 6373 tmp = (pg->pg_pga_gain | 0xefa0); 6374 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6375 } 6376 if (phy->type == BWN_PHYTYPE_G) { 6377 if (phy->rev >= 3) 6378 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6379 else 6380 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6381 if (phy->rev >= 2) 6382 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6383 else 6384 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6385 } 6386 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6387 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6388 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6389 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6390 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6391 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6392 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6393 if (!BWN_HAS_TXMAG(phy)) { 6394 tmp = sav->rf2; 6395 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6396 } 6397 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6398 if (phy->type == BWN_PHYTYPE_B && 6399 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6400 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6401 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6402 } 6403 if (phy->rev >= 2) { 6404 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6405 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6406 sav->phy_analogoverval); 6407 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6408 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6409 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6410 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6411 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6412 } 6413 if (bwn_has_hwpctl(mac)) { 6414 tmp = (sav->phy_lomask & 0xbfff); 6415 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6416 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6417 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6418 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6419 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6420 } 6421 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6422} 6423 6424static int 6425bwn_lo_probe_loctl(struct bwn_mac *mac, 6426 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6427{ 6428 struct bwn_phy *phy = &mac->mac_phy; 6429 struct bwn_phy_g *pg = &phy->phy_g; 6430 struct bwn_loctl orig, test; 6431 struct bwn_loctl prev = { -100, -100 }; 6432 static const struct bwn_loctl modifiers[] = { 6433 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6434 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6435 }; 6436 int begin, end, lower = 0, i; 6437 uint16_t feedth; 6438 6439 if (d->curstate == 0) { 6440 begin = 1; 6441 end = 8; 6442 } else if (d->curstate % 2 == 0) { 6443 begin = d->curstate - 1; 6444 end = d->curstate + 1; 6445 } else { 6446 begin = d->curstate - 2; 6447 end = d->curstate + 2; 6448 } 6449 if (begin < 1) 6450 begin += 8; 6451 if (end > 8) 6452 end -= 8; 6453 6454 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6455 i = begin; 6456 d->curstate = i; 6457 while (1) { 6458 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6459 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6460 test.i += modifiers[i - 1].i * d->multipler; 6461 test.q += modifiers[i - 1].q * d->multipler; 6462 if ((test.i != prev.i || test.q != prev.q) && 6463 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6464 bwn_lo_write(mac, &test); 6465 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6466 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6467 if (feedth < d->feedth) { 6468 memcpy(probe, &test, 6469 sizeof(struct bwn_loctl)); 6470 lower = 1; 6471 d->feedth = feedth; 6472 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6473 break; 6474 } 6475 } 6476 memcpy(&prev, &test, sizeof(prev)); 6477 if (i == end) 6478 break; 6479 if (i == 8) 6480 i = 1; 6481 else 6482 i++; 6483 d->curstate = i; 6484 } 6485 6486 return (lower); 6487} 6488 6489static void 6490bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6491{ 6492 struct bwn_phy *phy = &mac->mac_phy; 6493 struct bwn_phy_g *pg = &phy->phy_g; 6494 struct bwn_lo_g_sm d; 6495 struct bwn_loctl probe; 6496 int lower, repeat, cnt = 0; 6497 uint16_t feedth; 6498 6499 d.nmeasure = 0; 6500 d.multipler = 1; 6501 if (BWN_HAS_LOOPBACK(phy)) 6502 d.multipler = 3; 6503 6504 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6505 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6506 6507 do { 6508 bwn_lo_write(mac, &d.loctl); 6509 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6510 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6511 if (feedth < 0x258) { 6512 if (feedth >= 0x12c) 6513 *rxgain += 6; 6514 else 6515 *rxgain += 3; 6516 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6517 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6518 } 6519 d.feedth = feedth; 6520 d.curstate = 0; 6521 do { 6522 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6523 ("%s:%d: fail", __func__, __LINE__)); 6524 memcpy(&probe, &d.loctl, 6525 sizeof(struct bwn_loctl)); 6526 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6527 if (!lower) 6528 break; 6529 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6530 break; 6531 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6532 d.nmeasure++; 6533 } while (d.nmeasure < 24); 6534 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6535 6536 if (BWN_HAS_LOOPBACK(phy)) { 6537 if (d.feedth > 0x1194) 6538 *rxgain -= 6; 6539 else if (d.feedth < 0x5dc) 6540 *rxgain += 3; 6541 if (cnt == 0) { 6542 if (d.feedth <= 0x5dc) { 6543 d.multipler = 1; 6544 cnt++; 6545 } else 6546 d.multipler = 2; 6547 } else if (cnt == 2) 6548 d.multipler = 1; 6549 } 6550 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6551 } while (++cnt < repeat); 6552} 6553 6554static struct bwn_lo_calib * 6555bwn_lo_calibset(struct bwn_mac *mac, 6556 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6557{ 6558 struct bwn_phy *phy = &mac->mac_phy; 6559 struct bwn_phy_g *pg = &phy->phy_g; 6560 struct bwn_loctl loctl = { 0, 0 }; 6561 struct bwn_lo_calib *cal; 6562 struct bwn_lo_g_value sval = { 0 }; 6563 int rxgain; 6564 uint16_t pad, reg, value; 6565 6566 sval.old_channel = phy->chan; 6567 bwn_mac_suspend(mac); 6568 bwn_lo_save(mac, &sval); 6569 6570 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6571 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6572 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6573 6574 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6575 if (rfatt->padmix) 6576 rxgain -= pad; 6577 if (BWN_HAS_LOOPBACK(phy)) 6578 rxgain += pg->pg_max_lb_gain; 6579 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6580 bwn_phy_g_set_bbatt(mac, bbatt->att); 6581 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6582 6583 bwn_lo_restore(mac, &sval); 6584 bwn_mac_enable(mac); 6585 6586 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6587 if (!cal) { 6588 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6589 return (NULL); 6590 } 6591 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6592 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6593 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6594 6595 BWN_GETTIME(cal->calib_time); 6596 6597 return (cal); 6598} 6599 6600static struct bwn_lo_calib * 6601bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6602 const struct bwn_rfatt *rfatt) 6603{ 6604 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6605 struct bwn_lo_calib *c; 6606 6607 TAILQ_FOREACH(c, &lo->calib_list, list) { 6608 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6609 continue; 6610 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6611 continue; 6612 return (c); 6613 } 6614 6615 c = bwn_lo_calibset(mac, bbatt, rfatt); 6616 if (!c) 6617 return (NULL); 6618 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6619 6620 return (c); 6621} 6622 6623static void 6624bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6625{ 6626 struct bwn_phy *phy = &mac->mac_phy; 6627 struct bwn_phy_g *pg = &phy->phy_g; 6628 struct bwn_softc *sc = mac->mac_sc; 6629 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6630 const struct bwn_rfatt *rfatt; 6631 const struct bwn_bbatt *bbatt; 6632 uint64_t pvector; 6633 int i; 6634 int rf_offset, bb_offset; 6635 uint8_t changed = 0; 6636 6637 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6638 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6639 ("%s:%d: fail", __func__, __LINE__)); 6640 6641 pvector = lo->power_vector; 6642 if (!update && !pvector) 6643 return; 6644 6645 bwn_mac_suspend(mac); 6646 6647 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6648 struct bwn_lo_calib *cal; 6649 int idx; 6650 uint16_t val; 6651 6652 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6653 continue; 6654 bb_offset = i / lo->rfatt.len; 6655 rf_offset = i % lo->rfatt.len; 6656 bbatt = &(lo->bbatt.array[bb_offset]); 6657 rfatt = &(lo->rfatt.array[rf_offset]); 6658 6659 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6660 if (!cal) { 6661 device_printf(sc->sc_dev, "LO: Could not " 6662 "calibrate DC table entry\n"); 6663 continue; 6664 } 6665 val = (uint8_t)(cal->ctl.q); 6666 val |= ((uint8_t)(cal->ctl.i)) << 4; 6667 free(cal, M_DEVBUF); 6668 6669 idx = i / 2; 6670 if (i % 2) 6671 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6672 | ((val & 0x00ff) << 8); 6673 else 6674 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6675 | (val & 0x00ff); 6676 changed = 1; 6677 } 6678 if (changed) { 6679 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6680 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6681 } 6682 bwn_mac_enable(mac); 6683} 6684 6685static void 6686bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6687{ 6688 6689 if (!rf->padmix) 6690 return; 6691 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6692 rf->att = 4; 6693} 6694 6695static void 6696bwn_lo_g_adjust(struct bwn_mac *mac) 6697{ 6698 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6699 struct bwn_lo_calib *cal; 6700 struct bwn_rfatt rf; 6701 6702 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6703 bwn_lo_fixup_rfatt(&rf); 6704 6705 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6706 if (!cal) 6707 return; 6708 bwn_lo_write(mac, &cal->ctl); 6709} 6710 6711static void 6712bwn_lo_g_init(struct bwn_mac *mac) 6713{ 6714 6715 if (!bwn_has_hwpctl(mac)) 6716 return; 6717 6718 bwn_lo_get_powervector(mac); 6719 bwn_phy_g_dc_lookup_init(mac, 1); 6720} 6721 6722static void 6723bwn_mac_suspend(struct bwn_mac *mac) 6724{ 6725 struct bwn_softc *sc = mac->mac_sc; 6726 int i; 6727 uint32_t tmp; 6728 6729 KASSERT(mac->mac_suspended >= 0, 6730 ("%s:%d: fail", __func__, __LINE__)); 6731 6732 if (mac->mac_suspended == 0) { 6733 bwn_psctl(mac, BWN_PS_AWAKE); 6734 BWN_WRITE_4(mac, BWN_MACCTL, 6735 BWN_READ_4(mac, BWN_MACCTL) 6736 & ~BWN_MACCTL_ON); 6737 BWN_READ_4(mac, BWN_MACCTL); 6738 for (i = 35; i; i--) { 6739 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6740 if (tmp & BWN_INTR_MAC_SUSPENDED) 6741 goto out; 6742 DELAY(10); 6743 } 6744 for (i = 40; i; i--) { 6745 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6746 if (tmp & BWN_INTR_MAC_SUSPENDED) 6747 goto out; 6748 DELAY(1000); 6749 } 6750 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6751 } 6752out: 6753 mac->mac_suspended++; 6754} 6755 6756static void 6757bwn_mac_enable(struct bwn_mac *mac) 6758{ 6759 struct bwn_softc *sc = mac->mac_sc; 6760 uint16_t state; 6761 6762 state = bwn_shm_read_2(mac, BWN_SHARED, 6763 BWN_SHARED_UCODESTAT); 6764 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6765 state != BWN_SHARED_UCODESTAT_SLEEP) 6766 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6767 6768 mac->mac_suspended--; 6769 KASSERT(mac->mac_suspended >= 0, 6770 ("%s:%d: fail", __func__, __LINE__)); 6771 if (mac->mac_suspended == 0) { 6772 BWN_WRITE_4(mac, BWN_MACCTL, 6773 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6774 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6775 BWN_READ_4(mac, BWN_MACCTL); 6776 BWN_READ_4(mac, BWN_INTR_REASON); 6777 bwn_psctl(mac, 0); 6778 } 6779} 6780 6781static void 6782bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6783{ 6784 int i; 6785 uint16_t ucstat; 6786 6787 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6788 ("%s:%d: fail", __func__, __LINE__)); 6789 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6790 ("%s:%d: fail", __func__, __LINE__)); 6791 6792 /* XXX forcibly awake and hwps-off */ 6793 6794 BWN_WRITE_4(mac, BWN_MACCTL, 6795 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6796 ~BWN_MACCTL_HWPS); 6797 BWN_READ_4(mac, BWN_MACCTL); 6798 if (mac->mac_sd->sd_id.sd_rev >= 5) { 6799 for (i = 0; i < 100; i++) { 6800 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6801 BWN_SHARED_UCODESTAT); 6802 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6803 break; 6804 DELAY(10); 6805 } 6806 } 6807} 6808 6809static int16_t 6810bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6811{ 6812 6813 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6814 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6815} 6816 6817static void 6818bwn_nrssi_threshold(struct bwn_mac *mac) 6819{ 6820 struct bwn_phy *phy = &mac->mac_phy; 6821 struct bwn_phy_g *pg = &phy->phy_g; 6822 struct siba_softc *siba = mac->mac_sd->sd_bus; 6823 int32_t a, b; 6824 int16_t tmp16; 6825 uint16_t tmpu16; 6826 6827 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6828 6829 if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 6830 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6831 a = 0x13; 6832 b = 0x12; 6833 } else { 6834 a = 0xe; 6835 b = 0x11; 6836 } 6837 6838 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6839 a += (pg->pg_nrssi[0] << 6); 6840 a += (a < 32) ? 31 : 32; 6841 a = a >> 6; 6842 a = MIN(MAX(a, -31), 31); 6843 6844 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6845 b += (pg->pg_nrssi[0] << 6); 6846 if (b < 32) 6847 b += 31; 6848 else 6849 b += 32; 6850 b = b >> 6; 6851 b = MIN(MAX(b, -31), 31); 6852 6853 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6854 tmpu16 |= ((uint32_t)b & 0x0000003f); 6855 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6856 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6857 return; 6858 } 6859 6860 tmp16 = bwn_nrssi_read(mac, 0x20); 6861 if (tmp16 >= 0x20) 6862 tmp16 -= 0x40; 6863 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6864} 6865 6866static void 6867bwn_nrssi_slope_11g(struct bwn_mac *mac) 6868{ 6869#define SAVE_RF_MAX 3 6870#define SAVE_PHY_COMM_MAX 4 6871#define SAVE_PHY3_MAX 8 6872 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6873 { 0x7a, 0x52, 0x43 }; 6874 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6875 { 0x15, 0x5a, 0x59, 0x58 }; 6876 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6877 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6878 0x0801, 0x0060, 0x0014, 0x0478 6879 }; 6880 struct bwn_phy *phy = &mac->mac_phy; 6881 struct bwn_phy_g *pg = &phy->phy_g; 6882 int32_t i, tmp32, phy3_idx = 0; 6883 uint16_t delta, tmp; 6884 uint16_t save_rf[SAVE_RF_MAX]; 6885 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6886 uint16_t save_phy3[SAVE_PHY3_MAX]; 6887 uint16_t ant_div, phy0, chan_ex; 6888 int16_t nrssi0, nrssi1; 6889 6890 KASSERT(phy->type == BWN_PHYTYPE_G, 6891 ("%s:%d: fail", __func__, __LINE__)); 6892 6893 if (phy->rf_rev >= 9) 6894 return; 6895 if (phy->rf_rev == 8) 6896 bwn_nrssi_offset(mac); 6897 6898 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6899 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6900 6901 /* 6902 * Save RF/PHY registers for later restoration 6903 */ 6904 ant_div = BWN_READ_2(mac, 0x03e2); 6905 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6906 for (i = 0; i < SAVE_RF_MAX; ++i) 6907 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6908 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6909 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6910 6911 phy0 = BWN_READ_2(mac, BWN_PHY0); 6912 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6913 if (phy->rev >= 3) { 6914 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6915 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6916 BWN_PHY_WRITE(mac, 0x002e, 0); 6917 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6918 switch (phy->rev) { 6919 case 4: 6920 case 6: 6921 case 7: 6922 BWN_PHY_SET(mac, 0x0478, 0x0100); 6923 BWN_PHY_SET(mac, 0x0801, 0x0040); 6924 break; 6925 case 3: 6926 case 5: 6927 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6928 break; 6929 } 6930 BWN_PHY_SET(mac, 0x0060, 0x0040); 6931 BWN_PHY_SET(mac, 0x0014, 0x0200); 6932 } 6933 /* 6934 * Calculate nrssi0 6935 */ 6936 BWN_RF_SET(mac, 0x007a, 0x0070); 6937 bwn_set_all_gains(mac, 0, 8, 0); 6938 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6939 if (phy->rev >= 2) { 6940 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6941 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6942 } 6943 BWN_RF_SET(mac, 0x007a, 0x0080); 6944 DELAY(20); 6945 6946 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6947 if (nrssi0 >= 0x0020) 6948 nrssi0 -= 0x0040; 6949 6950 /* 6951 * Calculate nrssi1 6952 */ 6953 BWN_RF_MASK(mac, 0x007a, 0x007f); 6954 if (phy->rev >= 2) 6955 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6956 6957 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6958 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6959 BWN_RF_SET(mac, 0x007a, 0x000f); 6960 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6961 if (phy->rev >= 2) { 6962 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6963 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6964 } 6965 6966 bwn_set_all_gains(mac, 3, 0, 1); 6967 if (phy->rf_rev == 8) { 6968 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6969 } else { 6970 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6971 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6972 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6973 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6974 } 6975 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6976 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6977 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6978 DELAY(20); 6979 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6980 6981 /* 6982 * Install calculated narrow RSSI values 6983 */ 6984 if (nrssi1 >= 0x0020) 6985 nrssi1 -= 0x0040; 6986 if (nrssi0 == nrssi1) 6987 pg->pg_nrssi_slope = 0x00010000; 6988 else 6989 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6990 if (nrssi0 >= -4) { 6991 pg->pg_nrssi[0] = nrssi1; 6992 pg->pg_nrssi[1] = nrssi0; 6993 } 6994 6995 /* 6996 * Restore saved RF/PHY registers 6997 */ 6998 if (phy->rev >= 3) { 6999 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 7000 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7001 save_phy3[phy3_idx]); 7002 } 7003 } 7004 if (phy->rev >= 2) { 7005 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 7006 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 7007 } 7008 7009 for (i = 0; i < SAVE_RF_MAX; ++i) 7010 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7011 7012 BWN_WRITE_2(mac, 0x03e2, ant_div); 7013 BWN_WRITE_2(mac, 0x03e6, phy0); 7014 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 7015 7016 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7017 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7018 7019 bwn_spu_workaround(mac, phy->chan); 7020 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 7021 bwn_set_original_gains(mac); 7022 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 7023 if (phy->rev >= 3) { 7024 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 7025 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7026 save_phy3[phy3_idx]); 7027 } 7028 } 7029 7030 delta = 0x1f - pg->pg_nrssi[0]; 7031 for (i = 0; i < 64; i++) { 7032 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 7033 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 7034 pg->pg_nrssi_lt[i] = tmp32; 7035 } 7036 7037 bwn_nrssi_threshold(mac); 7038#undef SAVE_RF_MAX 7039#undef SAVE_PHY_COMM_MAX 7040#undef SAVE_PHY3_MAX 7041} 7042 7043static void 7044bwn_nrssi_offset(struct bwn_mac *mac) 7045{ 7046#define SAVE_RF_MAX 2 7047#define SAVE_PHY_COMM_MAX 10 7048#define SAVE_PHY6_MAX 8 7049 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 7050 { 0x7a, 0x43 }; 7051 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 7052 0x0001, 0x0811, 0x0812, 0x0814, 7053 0x0815, 0x005a, 0x0059, 0x0058, 7054 0x000a, 0x0003 7055 }; 7056 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 7057 0x002e, 0x002f, 0x080f, 0x0810, 7058 0x0801, 0x0060, 0x0014, 0x0478 7059 }; 7060 struct bwn_phy *phy = &mac->mac_phy; 7061 int i, phy6_idx = 0; 7062 uint16_t save_rf[SAVE_RF_MAX]; 7063 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 7064 uint16_t save_phy6[SAVE_PHY6_MAX]; 7065 int16_t nrssi; 7066 uint16_t saved = 0xffff; 7067 7068 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7069 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 7070 for (i = 0; i < SAVE_RF_MAX; ++i) 7071 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 7072 7073 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 7074 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 7075 BWN_PHY_SET(mac, 0x0811, 0x000c); 7076 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 7077 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 7078 if (phy->rev >= 6) { 7079 for (i = 0; i < SAVE_PHY6_MAX; ++i) 7080 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 7081 7082 BWN_PHY_WRITE(mac, 0x002e, 0); 7083 BWN_PHY_WRITE(mac, 0x002f, 0); 7084 BWN_PHY_WRITE(mac, 0x080f, 0); 7085 BWN_PHY_WRITE(mac, 0x0810, 0); 7086 BWN_PHY_SET(mac, 0x0478, 0x0100); 7087 BWN_PHY_SET(mac, 0x0801, 0x0040); 7088 BWN_PHY_SET(mac, 0x0060, 0x0040); 7089 BWN_PHY_SET(mac, 0x0014, 0x0200); 7090 } 7091 BWN_RF_SET(mac, 0x007a, 0x0070); 7092 BWN_RF_SET(mac, 0x007a, 0x0080); 7093 DELAY(30); 7094 7095 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7096 if (nrssi >= 0x20) 7097 nrssi -= 0x40; 7098 if (nrssi == 31) { 7099 for (i = 7; i >= 4; i--) { 7100 BWN_RF_WRITE(mac, 0x007b, i); 7101 DELAY(20); 7102 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7103 0x003f); 7104 if (nrssi >= 0x20) 7105 nrssi -= 0x40; 7106 if (nrssi < 31 && saved == 0xffff) 7107 saved = i; 7108 } 7109 if (saved == 0xffff) 7110 saved = 4; 7111 } else { 7112 BWN_RF_MASK(mac, 0x007a, 0x007f); 7113 if (phy->rev != 1) { 7114 BWN_PHY_SET(mac, 0x0814, 0x0001); 7115 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7116 } 7117 BWN_PHY_SET(mac, 0x0811, 0x000c); 7118 BWN_PHY_SET(mac, 0x0812, 0x000c); 7119 BWN_PHY_SET(mac, 0x0811, 0x0030); 7120 BWN_PHY_SET(mac, 0x0812, 0x0030); 7121 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7122 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7123 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7124 if (phy->rev == 0) 7125 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7126 else 7127 BWN_PHY_SET(mac, 0x000a, 0x2000); 7128 if (phy->rev != 1) { 7129 BWN_PHY_SET(mac, 0x0814, 0x0004); 7130 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7131 } 7132 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7133 BWN_RF_SET(mac, 0x007a, 0x000f); 7134 bwn_set_all_gains(mac, 3, 0, 1); 7135 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7136 DELAY(30); 7137 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7138 if (nrssi >= 0x20) 7139 nrssi -= 0x40; 7140 if (nrssi == -32) { 7141 for (i = 0; i < 4; i++) { 7142 BWN_RF_WRITE(mac, 0x007b, i); 7143 DELAY(20); 7144 nrssi = (int16_t)((BWN_PHY_READ(mac, 7145 0x047f) >> 8) & 0x003f); 7146 if (nrssi >= 0x20) 7147 nrssi -= 0x40; 7148 if (nrssi > -31 && saved == 0xffff) 7149 saved = i; 7150 } 7151 if (saved == 0xffff) 7152 saved = 3; 7153 } else 7154 saved = 0; 7155 } 7156 BWN_RF_WRITE(mac, 0x007b, saved); 7157 7158 /* 7159 * Restore saved RF/PHY registers 7160 */ 7161 if (phy->rev >= 6) { 7162 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7163 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7164 save_phy6[phy6_idx]); 7165 } 7166 } 7167 if (phy->rev != 1) { 7168 for (i = 3; i < 5; i++) 7169 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7170 save_phy_comm[i]); 7171 } 7172 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7173 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7174 7175 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7176 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7177 7178 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7179 BWN_PHY_SET(mac, 0x0429, 0x8000); 7180 bwn_set_original_gains(mac); 7181 if (phy->rev >= 6) { 7182 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7183 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7184 save_phy6[phy6_idx]); 7185 } 7186 } 7187 7188 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7189 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7190 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7191} 7192 7193static void 7194bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7195 int16_t third) 7196{ 7197 struct bwn_phy *phy = &mac->mac_phy; 7198 uint16_t i; 7199 uint16_t start = 0x08, end = 0x18; 7200 uint16_t tmp; 7201 uint16_t table; 7202 7203 if (phy->rev <= 1) { 7204 start = 0x10; 7205 end = 0x20; 7206 } 7207 7208 table = BWN_OFDMTAB_GAINX; 7209 if (phy->rev <= 1) 7210 table = BWN_OFDMTAB_GAINX_R1; 7211 for (i = 0; i < 4; i++) 7212 bwn_ofdmtab_write_2(mac, table, i, first); 7213 7214 for (i = start; i < end; i++) 7215 bwn_ofdmtab_write_2(mac, table, i, second); 7216 7217 if (third != -1) { 7218 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7219 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7220 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7221 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7222 } 7223 bwn_dummy_transmission(mac, 0, 1); 7224} 7225 7226static void 7227bwn_set_original_gains(struct bwn_mac *mac) 7228{ 7229 struct bwn_phy *phy = &mac->mac_phy; 7230 uint16_t i, tmp; 7231 uint16_t table; 7232 uint16_t start = 0x0008, end = 0x0018; 7233 7234 if (phy->rev <= 1) { 7235 start = 0x0010; 7236 end = 0x0020; 7237 } 7238 7239 table = BWN_OFDMTAB_GAINX; 7240 if (phy->rev <= 1) 7241 table = BWN_OFDMTAB_GAINX_R1; 7242 for (i = 0; i < 4; i++) { 7243 tmp = (i & 0xfffc); 7244 tmp |= (i & 0x0001) << 1; 7245 tmp |= (i & 0x0002) >> 1; 7246 7247 bwn_ofdmtab_write_2(mac, table, i, tmp); 7248 } 7249 7250 for (i = start; i < end; i++) 7251 bwn_ofdmtab_write_2(mac, table, i, i - start); 7252 7253 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7254 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7255 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7256 bwn_dummy_transmission(mac, 0, 1); 7257} 7258 7259static void 7260bwn_phy_hwpctl_init(struct bwn_mac *mac) 7261{ 7262 struct siba_softc *bus = mac->mac_sd->sd_bus; 7263 struct bwn_phy *phy = &mac->mac_phy; 7264 struct bwn_phy_g *pg = &phy->phy_g; 7265 struct bwn_rfatt old_rfatt, rfatt; 7266 struct bwn_bbatt old_bbatt, bbatt; 7267 uint8_t old_txctl = 0; 7268 7269 KASSERT(phy->type == BWN_PHYTYPE_G, 7270 ("%s:%d: fail", __func__, __LINE__)); 7271 7272 if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) && 7273 (bus->siba_board_type == SIBA_BOARD_BU4306)) 7274 return; 7275 7276 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7277 7278 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7279 7280 if (!phy->gmode) 7281 return; 7282 bwn_hwpctl_early_init(mac); 7283 if (pg->pg_curtssi == 0) { 7284 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7285 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7286 } else { 7287 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7288 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7289 old_txctl = pg->pg_txctl; 7290 7291 bbatt.att = 11; 7292 if (phy->rf_rev == 8) { 7293 rfatt.att = 15; 7294 rfatt.padmix = 1; 7295 } else { 7296 rfatt.att = 9; 7297 rfatt.padmix = 0; 7298 } 7299 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7300 } 7301 bwn_dummy_transmission(mac, 0, 1); 7302 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7303 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7304 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7305 else 7306 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7307 &old_rfatt, old_txctl); 7308 } 7309 bwn_hwpctl_init_gphy(mac); 7310 7311 /* clear TSSI */ 7312 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7313 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7314 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7315 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7316} 7317 7318static void 7319bwn_hwpctl_early_init(struct bwn_mac *mac) 7320{ 7321 struct bwn_phy *phy = &mac->mac_phy; 7322 7323 if (!bwn_has_hwpctl(mac)) { 7324 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7325 return; 7326 } 7327 7328 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7329 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7330 BWN_PHY_SET(mac, 0x047c, 0x0002); 7331 BWN_PHY_SET(mac, 0x047a, 0xf000); 7332 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7333 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7334 BWN_PHY_SET(mac, 0x005d, 0x8000); 7335 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7336 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7337 BWN_PHY_SET(mac, 0x0036, 0x0400); 7338 } else { 7339 BWN_PHY_SET(mac, 0x0036, 0x0200); 7340 BWN_PHY_SET(mac, 0x0036, 0x0400); 7341 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7342 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7343 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7344 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7345 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7346 } 7347} 7348 7349static void 7350bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7351{ 7352 struct bwn_phy *phy = &mac->mac_phy; 7353 struct bwn_phy_g *pg = &phy->phy_g; 7354 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7355 int i; 7356 uint16_t nr_written = 0, tmp, value; 7357 uint8_t rf, bb; 7358 7359 if (!bwn_has_hwpctl(mac)) { 7360 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7361 return; 7362 } 7363 7364 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7365 (pg->pg_idletssi - pg->pg_curtssi)); 7366 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7367 (pg->pg_idletssi - pg->pg_curtssi)); 7368 7369 for (i = 0; i < 32; i++) 7370 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7371 for (i = 32; i < 64; i++) 7372 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7373 for (i = 0; i < 64; i += 2) { 7374 value = (uint16_t) pg->pg_tssi2dbm[i]; 7375 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7376 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7377 } 7378 7379 for (rf = 0; rf < lo->rfatt.len; rf++) { 7380 for (bb = 0; bb < lo->bbatt.len; bb++) { 7381 if (nr_written >= 0x40) 7382 return; 7383 tmp = lo->bbatt.array[bb].att; 7384 tmp <<= 8; 7385 if (phy->rf_rev == 8) 7386 tmp |= 0x50; 7387 else 7388 tmp |= 0x40; 7389 tmp |= lo->rfatt.array[rf].att; 7390 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7391 nr_written++; 7392 } 7393 } 7394 7395 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7396 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7397 7398 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7399 BWN_PHY_SET(mac, 0x0478, 0x0800); 7400 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7401 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7402 7403 bwn_phy_g_dc_lookup_init(mac, 1); 7404 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7405} 7406 7407static void 7408bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7409{ 7410 struct siba_softc *siba = mac->mac_sd->sd_bus; 7411 7412 if (spu != 0) 7413 bwn_spu_workaround(mac, channel); 7414 7415 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7416 7417 if (channel == 14) { 7418 if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN) 7419 bwn_hf_write(mac, 7420 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7421 else 7422 bwn_hf_write(mac, 7423 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7424 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7425 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7426 return; 7427 } 7428 7429 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7430 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7431} 7432 7433static uint16_t 7434bwn_phy_g_chan2freq(uint8_t channel) 7435{ 7436 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7437 7438 KASSERT(channel >= 1 && channel <= 14, 7439 ("%s:%d: fail", __func__, __LINE__)); 7440 7441 return (bwn_phy_g_rf_channels[channel - 1]); 7442} 7443 7444static void 7445bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7446 const struct bwn_rfatt *rfatt, uint8_t txctl) 7447{ 7448 struct bwn_phy *phy = &mac->mac_phy; 7449 struct bwn_phy_g *pg = &phy->phy_g; 7450 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7451 uint16_t bb, rf; 7452 uint16_t tx_bias, tx_magn; 7453 7454 bb = bbatt->att; 7455 rf = rfatt->att; 7456 tx_bias = lo->tx_bias; 7457 tx_magn = lo->tx_magn; 7458 if (tx_bias == 0xff) 7459 tx_bias = 0; 7460 7461 pg->pg_txctl = txctl; 7462 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7463 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7464 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7465 bwn_phy_g_set_bbatt(mac, bb); 7466 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7467 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7468 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7469 else { 7470 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7471 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7472 } 7473 if (BWN_HAS_TXMAG(phy)) 7474 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7475 else 7476 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7477 bwn_lo_g_adjust(mac); 7478} 7479 7480static void 7481bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7482 uint16_t bbatt) 7483{ 7484 struct bwn_phy *phy = &mac->mac_phy; 7485 7486 if (phy->analog == 0) { 7487 BWN_WRITE_2(mac, BWN_PHY0, 7488 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7489 return; 7490 } 7491 if (phy->analog > 1) { 7492 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7493 return; 7494 } 7495 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7496} 7497 7498static uint16_t 7499bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7500{ 7501 struct bwn_phy *phy = &mac->mac_phy; 7502 struct bwn_phy_g *pg = &phy->phy_g; 7503 struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom); 7504 int max_lb_gain; 7505 uint16_t extlna; 7506 uint16_t i; 7507 7508 if (phy->gmode == 0) 7509 return (0); 7510 7511 if (BWN_HAS_LOOPBACK(phy)) { 7512 max_lb_gain = pg->pg_max_lb_gain; 7513 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7514 if (max_lb_gain >= 0x46) { 7515 extlna = 0x3000; 7516 max_lb_gain -= 0x46; 7517 } else if (max_lb_gain >= 0x3a) { 7518 extlna = 0x1000; 7519 max_lb_gain -= 0x3a; 7520 } else if (max_lb_gain >= 0x2e) { 7521 extlna = 0x2000; 7522 max_lb_gain -= 0x2e; 7523 } else { 7524 extlna = 0; 7525 max_lb_gain -= 0x10; 7526 } 7527 7528 for (i = 0; i < 16; i++) { 7529 max_lb_gain -= (i * 6); 7530 if (max_lb_gain < 6) 7531 break; 7532 } 7533 7534 if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7535 if (reg == BWN_PHY_RFOVER) { 7536 return (0x1b3); 7537 } else if (reg == BWN_PHY_RFOVERVAL) { 7538 extlna |= (i << 8); 7539 switch (lpd) { 7540 case BWN_LPD(0, 1, 1): 7541 return (0x0f92); 7542 case BWN_LPD(0, 0, 1): 7543 case BWN_LPD(1, 0, 1): 7544 return (0x0092 | extlna); 7545 case BWN_LPD(1, 0, 0): 7546 return (0x0093 | extlna); 7547 } 7548 KASSERT(0 == 1, 7549 ("%s:%d: fail", __func__, __LINE__)); 7550 } 7551 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7552 } else { 7553 if (reg == BWN_PHY_RFOVER) 7554 return (0x9b3); 7555 if (reg == BWN_PHY_RFOVERVAL) { 7556 if (extlna) 7557 extlna |= 0x8000; 7558 extlna |= (i << 8); 7559 switch (lpd) { 7560 case BWN_LPD(0, 1, 1): 7561 return (0x8f92); 7562 case BWN_LPD(0, 0, 1): 7563 return (0x8092 | extlna); 7564 case BWN_LPD(1, 0, 1): 7565 return (0x2092 | extlna); 7566 case BWN_LPD(1, 0, 0): 7567 return (0x2093 | extlna); 7568 } 7569 KASSERT(0 == 1, 7570 ("%s:%d: fail", __func__, __LINE__)); 7571 } 7572 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7573 } 7574 return (0); 7575 } 7576 7577 if ((phy->rev < 7) || 7578 !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7579 if (reg == BWN_PHY_RFOVER) { 7580 return (0x1b3); 7581 } else if (reg == BWN_PHY_RFOVERVAL) { 7582 switch (lpd) { 7583 case BWN_LPD(0, 1, 1): 7584 return (0x0fb2); 7585 case BWN_LPD(0, 0, 1): 7586 return (0x00b2); 7587 case BWN_LPD(1, 0, 1): 7588 return (0x30b2); 7589 case BWN_LPD(1, 0, 0): 7590 return (0x30b3); 7591 } 7592 KASSERT(0 == 1, 7593 ("%s:%d: fail", __func__, __LINE__)); 7594 } 7595 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7596 } else { 7597 if (reg == BWN_PHY_RFOVER) { 7598 return (0x9b3); 7599 } else if (reg == BWN_PHY_RFOVERVAL) { 7600 switch (lpd) { 7601 case BWN_LPD(0, 1, 1): 7602 return (0x8fb2); 7603 case BWN_LPD(0, 0, 1): 7604 return (0x80b2); 7605 case BWN_LPD(1, 0, 1): 7606 return (0x20b2); 7607 case BWN_LPD(1, 0, 0): 7608 return (0x20b3); 7609 } 7610 KASSERT(0 == 1, 7611 ("%s:%d: fail", __func__, __LINE__)); 7612 } 7613 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7614 } 7615 return (0); 7616} 7617 7618static void 7619bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7620{ 7621 7622 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7623 return; 7624 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7625 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7626 DELAY(1000); 7627 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7628} 7629 7630static int 7631bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7632{ 7633 struct bwn_softc *sc = mac->mac_sc; 7634 struct bwn_fw *fw = &mac->mac_fw; 7635 const uint8_t rev = mac->mac_sd->sd_id.sd_rev; 7636 const char *filename; 7637 uint32_t high; 7638 int error; 7639 7640 /* microcode */ 7641 if (rev >= 5 && rev <= 10) 7642 filename = "ucode5"; 7643 else if (rev >= 11 && rev <= 12) 7644 filename = "ucode11"; 7645 else if (rev == 13) 7646 filename = "ucode13"; 7647 else if (rev == 14) 7648 filename = "ucode14"; 7649 else if (rev >= 15) 7650 filename = "ucode15"; 7651 else { 7652 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7653 bwn_release_firmware(mac); 7654 return (EOPNOTSUPP); 7655 } 7656 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7657 if (error) { 7658 bwn_release_firmware(mac); 7659 return (error); 7660 } 7661 7662 /* PCM */ 7663 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7664 if (rev >= 5 && rev <= 10) { 7665 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7666 if (error == ENOENT) 7667 fw->no_pcmfile = 1; 7668 else if (error) { 7669 bwn_release_firmware(mac); 7670 return (error); 7671 } 7672 } else if (rev < 11) { 7673 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7674 return (EOPNOTSUPP); 7675 } 7676 7677 /* initvals */ 7678 high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH); 7679 switch (mac->mac_phy.type) { 7680 case BWN_PHYTYPE_A: 7681 if (rev < 5 || rev > 10) 7682 goto fail1; 7683 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7684 filename = "a0g1initvals5"; 7685 else 7686 filename = "a0g0initvals5"; 7687 break; 7688 case BWN_PHYTYPE_G: 7689 if (rev >= 5 && rev <= 10) 7690 filename = "b0g0initvals5"; 7691 else if (rev >= 13) 7692 filename = "b0g0initvals13"; 7693 else 7694 goto fail1; 7695 break; 7696 case BWN_PHYTYPE_LP: 7697 if (rev == 13) 7698 filename = "lp0initvals13"; 7699 else if (rev == 14) 7700 filename = "lp0initvals14"; 7701 else if (rev >= 15) 7702 filename = "lp0initvals15"; 7703 else 7704 goto fail1; 7705 break; 7706 case BWN_PHYTYPE_N: 7707 if (rev >= 11 && rev <= 12) 7708 filename = "n0initvals11"; 7709 else 7710 goto fail1; 7711 break; 7712 default: 7713 goto fail1; 7714 } 7715 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7716 if (error) { 7717 bwn_release_firmware(mac); 7718 return (error); 7719 } 7720 7721 /* bandswitch initvals */ 7722 switch (mac->mac_phy.type) { 7723 case BWN_PHYTYPE_A: 7724 if (rev >= 5 && rev <= 10) { 7725 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7726 filename = "a0g1bsinitvals5"; 7727 else 7728 filename = "a0g0bsinitvals5"; 7729 } else if (rev >= 11) 7730 filename = NULL; 7731 else 7732 goto fail1; 7733 break; 7734 case BWN_PHYTYPE_G: 7735 if (rev >= 5 && rev <= 10) 7736 filename = "b0g0bsinitvals5"; 7737 else if (rev >= 11) 7738 filename = NULL; 7739 else 7740 goto fail1; 7741 break; 7742 case BWN_PHYTYPE_LP: 7743 if (rev == 13) 7744 filename = "lp0bsinitvals13"; 7745 else if (rev == 14) 7746 filename = "lp0bsinitvals14"; 7747 else if (rev >= 15) 7748 filename = "lp0bsinitvals15"; 7749 else 7750 goto fail1; 7751 break; 7752 case BWN_PHYTYPE_N: 7753 if (rev >= 11 && rev <= 12) 7754 filename = "n0bsinitvals11"; 7755 else 7756 goto fail1; 7757 break; 7758 default: 7759 goto fail1; 7760 } 7761 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7762 if (error) { 7763 bwn_release_firmware(mac); 7764 return (error); 7765 } 7766 return (0); 7767fail1: 7768 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7769 bwn_release_firmware(mac); 7770 return (EOPNOTSUPP); 7771} 7772 7773static int 7774bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7775 const char *name, struct bwn_fwfile *bfw) 7776{ 7777 const struct bwn_fwhdr *hdr; 7778 struct bwn_softc *sc = mac->mac_sc; 7779 const struct firmware *fw; 7780 char namebuf[64]; 7781 7782 if (name == NULL) { 7783 bwn_do_release_fw(bfw); 7784 return (0); 7785 } 7786 if (bfw->filename != NULL) { 7787 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7788 return (0); 7789 bwn_do_release_fw(bfw); 7790 } 7791 7792 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7793 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7794 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7795 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7796 fw = firmware_get(namebuf); 7797 if (fw == NULL) { 7798 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7799 namebuf); 7800 return (ENOENT); 7801 } 7802 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7803 goto fail; 7804 hdr = (const struct bwn_fwhdr *)(fw->data); 7805 switch (hdr->type) { 7806 case BWN_FWTYPE_UCODE: 7807 case BWN_FWTYPE_PCM: 7808 if (be32toh(hdr->size) != 7809 (fw->datasize - sizeof(struct bwn_fwhdr))) 7810 goto fail; 7811 /* FALLTHROUGH */ 7812 case BWN_FWTYPE_IV: 7813 if (hdr->ver != 1) 7814 goto fail; 7815 break; 7816 default: 7817 goto fail; 7818 } 7819 bfw->filename = name; 7820 bfw->fw = fw; 7821 bfw->type = type; 7822 return (0); 7823fail: 7824 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7825 if (fw != NULL) 7826 firmware_put(fw, FIRMWARE_UNLOAD); 7827 return (EPROTO); 7828} 7829 7830static void 7831bwn_release_firmware(struct bwn_mac *mac) 7832{ 7833 7834 bwn_do_release_fw(&mac->mac_fw.ucode); 7835 bwn_do_release_fw(&mac->mac_fw.pcm); 7836 bwn_do_release_fw(&mac->mac_fw.initvals); 7837 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7838} 7839 7840static void 7841bwn_do_release_fw(struct bwn_fwfile *bfw) 7842{ 7843 7844 if (bfw->fw != NULL) 7845 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7846 bfw->fw = NULL; 7847 bfw->filename = NULL; 7848} 7849 7850static int 7851bwn_fw_loaducode(struct bwn_mac *mac) 7852{ 7853#define GETFWOFFSET(fwp, offset) \ 7854 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7855#define GETFWSIZE(fwp, offset) \ 7856 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7857 struct bwn_softc *sc = mac->mac_sc; 7858 const uint32_t *data; 7859 unsigned int i; 7860 uint32_t ctl; 7861 uint16_t date, fwcaps, time; 7862 int error = 0; 7863 7864 ctl = BWN_READ_4(mac, BWN_MACCTL); 7865 ctl |= BWN_MACCTL_MCODE_JMP0; 7866 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7867 __LINE__)); 7868 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7869 for (i = 0; i < 64; i++) 7870 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7871 for (i = 0; i < 4096; i += 2) 7872 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7873 7874 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7875 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7876 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7877 i++) { 7878 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7879 DELAY(10); 7880 } 7881 7882 if (mac->mac_fw.pcm.fw) { 7883 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7884 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7885 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7886 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7887 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7888 sizeof(struct bwn_fwhdr)); i++) { 7889 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7890 DELAY(10); 7891 } 7892 } 7893 7894 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7895 BWN_WRITE_4(mac, BWN_MACCTL, 7896 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7897 BWN_MACCTL_MCODE_RUN); 7898 7899 for (i = 0; i < 21; i++) { 7900 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7901 break; 7902 if (i >= 20) { 7903 device_printf(sc->sc_dev, "ucode timeout\n"); 7904 error = ENXIO; 7905 goto error; 7906 } 7907 DELAY(50000); 7908 } 7909 BWN_READ_4(mac, BWN_INTR_REASON); 7910 7911 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7912 if (mac->mac_fw.rev <= 0x128) { 7913 device_printf(sc->sc_dev, "the firmware is too old\n"); 7914 error = EOPNOTSUPP; 7915 goto error; 7916 } 7917 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7918 BWN_SHARED_UCODE_PATCH); 7919 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7920 mac->mac_fw.opensource = (date == 0xffff); 7921 if (bwn_wme != 0) 7922 mac->mac_flags |= BWN_MAC_FLAG_WME; 7923 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7924 7925 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7926 if (mac->mac_fw.opensource == 0) { 7927 device_printf(sc->sc_dev, 7928 "firmware version (rev %u patch %u date %#x time %#x)\n", 7929 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7930 if (mac->mac_fw.no_pcmfile) 7931 device_printf(sc->sc_dev, 7932 "no HW crypto acceleration due to pcm5\n"); 7933 } else { 7934 mac->mac_fw.patch = time; 7935 fwcaps = bwn_fwcaps_read(mac); 7936 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7937 device_printf(sc->sc_dev, 7938 "disabling HW crypto acceleration\n"); 7939 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7940 } 7941 if (!(fwcaps & BWN_FWCAPS_WME)) { 7942 device_printf(sc->sc_dev, "disabling WME support\n"); 7943 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7944 } 7945 } 7946 7947 if (BWN_ISOLDFMT(mac)) 7948 device_printf(sc->sc_dev, "using old firmware image\n"); 7949 7950 return (0); 7951 7952error: 7953 BWN_WRITE_4(mac, BWN_MACCTL, 7954 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7955 BWN_MACCTL_MCODE_JMP0); 7956 7957 return (error); 7958#undef GETFWSIZE 7959#undef GETFWOFFSET 7960} 7961 7962/* OpenFirmware only */ 7963static uint16_t 7964bwn_fwcaps_read(struct bwn_mac *mac) 7965{ 7966 7967 KASSERT(mac->mac_fw.opensource == 1, 7968 ("%s:%d: fail", __func__, __LINE__)); 7969 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7970} 7971 7972static int 7973bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7974 size_t count, size_t array_size) 7975{ 7976#define GET_NEXTIV16(iv) \ 7977 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7978 sizeof(uint16_t) + sizeof(uint16_t))) 7979#define GET_NEXTIV32(iv) \ 7980 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7981 sizeof(uint16_t) + sizeof(uint32_t))) 7982 struct bwn_softc *sc = mac->mac_sc; 7983 const struct bwn_fwinitvals *iv; 7984 uint16_t offset; 7985 size_t i; 7986 uint8_t bit32; 7987 7988 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7989 ("%s:%d: fail", __func__, __LINE__)); 7990 iv = ivals; 7991 for (i = 0; i < count; i++) { 7992 if (array_size < sizeof(iv->offset_size)) 7993 goto fail; 7994 array_size -= sizeof(iv->offset_size); 7995 offset = be16toh(iv->offset_size); 7996 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7997 offset &= BWN_FWINITVALS_OFFSET_MASK; 7998 if (offset >= 0x1000) 7999 goto fail; 8000 if (bit32) { 8001 if (array_size < sizeof(iv->data.d32)) 8002 goto fail; 8003 array_size -= sizeof(iv->data.d32); 8004 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 8005 iv = GET_NEXTIV32(iv); 8006 } else { 8007 8008 if (array_size < sizeof(iv->data.d16)) 8009 goto fail; 8010 array_size -= sizeof(iv->data.d16); 8011 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 8012 8013 iv = GET_NEXTIV16(iv); 8014 } 8015 } 8016 if (array_size != 0) 8017 goto fail; 8018 return (0); 8019fail: 8020 device_printf(sc->sc_dev, "initvals: invalid format\n"); 8021 return (EPROTO); 8022#undef GET_NEXTIV16 8023#undef GET_NEXTIV32 8024} 8025 8026static int 8027bwn_switch_channel(struct bwn_mac *mac, int chan) 8028{ 8029 struct bwn_phy *phy = &(mac->mac_phy); 8030 struct bwn_softc *sc = mac->mac_sc; 8031 struct ifnet *ifp = sc->sc_ifp; 8032 struct ieee80211com *ic = ifp->if_l2com; 8033 uint16_t channelcookie, savedcookie; 8034 int error; 8035 8036 if (chan == 0xffff) 8037 chan = phy->get_default_chan(mac); 8038 8039 channelcookie = chan; 8040 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 8041 channelcookie |= 0x100; 8042 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 8043 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 8044 error = phy->switch_channel(mac, chan); 8045 if (error) 8046 goto fail; 8047 8048 mac->mac_phy.chan = chan; 8049 DELAY(8000); 8050 return (0); 8051fail: 8052 device_printf(sc->sc_dev, "failed to switch channel\n"); 8053 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 8054 return (error); 8055} 8056 8057static uint16_t 8058bwn_ant2phy(int antenna) 8059{ 8060 8061 switch (antenna) { 8062 case BWN_ANT0: 8063 return (BWN_TX_PHY_ANT0); 8064 case BWN_ANT1: 8065 return (BWN_TX_PHY_ANT1); 8066 case BWN_ANT2: 8067 return (BWN_TX_PHY_ANT2); 8068 case BWN_ANT3: 8069 return (BWN_TX_PHY_ANT3); 8070 case BWN_ANTAUTO: 8071 return (BWN_TX_PHY_ANT01AUTO); 8072 } 8073 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8074 return (0); 8075} 8076 8077static void 8078bwn_wme_load(struct bwn_mac *mac) 8079{ 8080 struct bwn_softc *sc = mac->mac_sc; 8081 int i; 8082 8083 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8084 ("%s:%d: fail", __func__, __LINE__)); 8085 8086 bwn_mac_suspend(mac); 8087 for (i = 0; i < N(sc->sc_wmeParams); i++) 8088 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8089 bwn_wme_shm_offsets[i]); 8090 bwn_mac_enable(mac); 8091} 8092 8093static void 8094bwn_wme_loadparams(struct bwn_mac *mac, 8095 const struct wmeParams *p, uint16_t shm_offset) 8096{ 8097#define SM(_v, _f) (((_v) << _f##_S) & _f) 8098 struct bwn_softc *sc = mac->mac_sc; 8099 uint16_t params[BWN_NR_WMEPARAMS]; 8100 int slot, tmp; 8101 unsigned int i; 8102 8103 slot = BWN_READ_2(mac, BWN_RNG) & 8104 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8105 8106 memset(¶ms, 0, sizeof(params)); 8107 8108 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8109 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8110 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8111 8112 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8113 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8114 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8115 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8116 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8117 params[BWN_WMEPARAM_BSLOTS] = slot; 8118 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8119 8120 for (i = 0; i < N(params); i++) { 8121 if (i == BWN_WMEPARAM_STATUS) { 8122 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8123 shm_offset + (i * 2)); 8124 tmp |= 0x100; 8125 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8126 tmp); 8127 } else { 8128 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8129 params[i]); 8130 } 8131 } 8132} 8133 8134static void 8135bwn_mac_write_bssid(struct bwn_mac *mac) 8136{ 8137 struct bwn_softc *sc = mac->mac_sc; 8138 uint32_t tmp; 8139 int i; 8140 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8141 8142 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8143 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8144 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8145 IEEE80211_ADDR_LEN); 8146 8147 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8148 tmp = (uint32_t) (mac_bssid[i + 0]); 8149 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8150 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8151 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8152 bwn_ram_write(mac, 0x20 + i, tmp); 8153 } 8154} 8155 8156static void 8157bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8158 const uint8_t *macaddr) 8159{ 8160 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8161 uint16_t data; 8162 8163 if (!mac) 8164 macaddr = zero; 8165 8166 offset |= 0x0020; 8167 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8168 8169 data = macaddr[0]; 8170 data |= macaddr[1] << 8; 8171 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8172 data = macaddr[2]; 8173 data |= macaddr[3] << 8; 8174 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8175 data = macaddr[4]; 8176 data |= macaddr[5] << 8; 8177 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8178} 8179 8180static void 8181bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8182 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8183{ 8184 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8185 uint8_t per_sta_keys_start = 8; 8186 8187 if (BWN_SEC_NEWAPI(mac)) 8188 per_sta_keys_start = 4; 8189 8190 KASSERT(index < mac->mac_max_nr_keys, 8191 ("%s:%d: fail", __func__, __LINE__)); 8192 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8193 ("%s:%d: fail", __func__, __LINE__)); 8194 8195 if (index >= per_sta_keys_start) 8196 bwn_key_macwrite(mac, index, NULL); 8197 if (key) 8198 memcpy(buf, key, key_len); 8199 bwn_key_write(mac, index, algorithm, buf); 8200 if (index >= per_sta_keys_start) 8201 bwn_key_macwrite(mac, index, mac_addr); 8202 8203 mac->mac_key[index].algorithm = algorithm; 8204} 8205 8206static void 8207bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8208{ 8209 uint32_t addrtmp[2] = { 0, 0 }; 8210 uint8_t start = 8; 8211 8212 if (BWN_SEC_NEWAPI(mac)) 8213 start = 4; 8214 8215 KASSERT(index >= start, 8216 ("%s:%d: fail", __func__, __LINE__)); 8217 index -= start; 8218 8219 if (addr) { 8220 addrtmp[0] = addr[0]; 8221 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8222 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8223 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8224 addrtmp[1] = addr[4]; 8225 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8226 } 8227 8228 if (mac->mac_sd->sd_id.sd_rev >= 5) { 8229 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8230 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8231 } else { 8232 if (index >= 8) { 8233 bwn_shm_write_4(mac, BWN_SHARED, 8234 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8235 bwn_shm_write_2(mac, BWN_SHARED, 8236 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8237 } 8238 } 8239} 8240 8241static void 8242bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8243 const uint8_t *key) 8244{ 8245 unsigned int i; 8246 uint32_t offset; 8247 uint16_t kidx, value; 8248 8249 kidx = BWN_SEC_KEY2FW(mac, index); 8250 bwn_shm_write_2(mac, BWN_SHARED, 8251 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8252 8253 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8254 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8255 value = key[i]; 8256 value |= (uint16_t)(key[i + 1]) << 8; 8257 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8258 } 8259} 8260 8261static void 8262bwn_phy_exit(struct bwn_mac *mac) 8263{ 8264 8265 mac->mac_phy.rf_onoff(mac, 0); 8266 if (mac->mac_phy.exit != NULL) 8267 mac->mac_phy.exit(mac); 8268} 8269 8270static void 8271bwn_dma_free(struct bwn_mac *mac) 8272{ 8273 struct bwn_dma *dma; 8274 8275 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8276 return; 8277 dma = &mac->mac_method.dma; 8278 8279 bwn_dma_ringfree(&dma->rx); 8280 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8281 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8282 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8283 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8284 bwn_dma_ringfree(&dma->mcast); 8285} 8286 8287static void 8288bwn_core_stop(struct bwn_mac *mac) 8289{ 8290 struct bwn_softc *sc = mac->mac_sc; 8291 8292 BWN_ASSERT_LOCKED(sc); 8293 8294 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8295 return; 8296 8297 callout_stop(&sc->sc_rfswitch_ch); 8298 callout_stop(&sc->sc_task_ch); 8299 callout_stop(&sc->sc_watchdog_ch); 8300 sc->sc_watchdog_timer = 0; 8301 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8302 BWN_READ_4(mac, BWN_INTR_MASK); 8303 bwn_mac_suspend(mac); 8304 8305 mac->mac_status = BWN_MAC_STATUS_INITED; 8306} 8307 8308static int 8309bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8310{ 8311 struct bwn_mac *up_dev = NULL; 8312 struct bwn_mac *down_dev; 8313 struct bwn_mac *mac; 8314 int err, status; 8315 uint8_t gmode; 8316 8317 BWN_ASSERT_LOCKED(sc); 8318 8319 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8320 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8321 mac->mac_phy.supports_2ghz) { 8322 up_dev = mac; 8323 gmode = 1; 8324 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8325 mac->mac_phy.supports_5ghz) { 8326 up_dev = mac; 8327 gmode = 0; 8328 } else { 8329 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8330 return (EINVAL); 8331 } 8332 if (up_dev != NULL) 8333 break; 8334 } 8335 if (up_dev == NULL) { 8336 device_printf(sc->sc_dev, "Could not find a device\n"); 8337 return (ENODEV); 8338 } 8339 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8340 return (0); 8341 8342 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8343 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8344 8345 down_dev = sc->sc_curmac;; 8346 status = down_dev->mac_status; 8347 if (status >= BWN_MAC_STATUS_STARTED) 8348 bwn_core_stop(down_dev); 8349 if (status >= BWN_MAC_STATUS_INITED) 8350 bwn_core_exit(down_dev); 8351 8352 if (down_dev != up_dev) 8353 bwn_phy_reset(down_dev); 8354 8355 up_dev->mac_phy.gmode = gmode; 8356 if (status >= BWN_MAC_STATUS_INITED) { 8357 err = bwn_core_init(up_dev); 8358 if (err) { 8359 device_printf(sc->sc_dev, 8360 "fatal: failed to initialize for %s-GHz\n", 8361 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8362 goto fail; 8363 } 8364 } 8365 if (status >= BWN_MAC_STATUS_STARTED) 8366 bwn_core_start(up_dev); 8367 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8368 sc->sc_curmac = up_dev; 8369 8370 return (0); 8371fail: 8372 sc->sc_curmac = NULL; 8373 return (err); 8374} 8375 8376static void 8377bwn_rf_turnon(struct bwn_mac *mac) 8378{ 8379 8380 bwn_mac_suspend(mac); 8381 mac->mac_phy.rf_onoff(mac, 1); 8382 mac->mac_phy.rf_on = 1; 8383 bwn_mac_enable(mac); 8384} 8385 8386static void 8387bwn_rf_turnoff(struct bwn_mac *mac) 8388{ 8389 8390 bwn_mac_suspend(mac); 8391 mac->mac_phy.rf_onoff(mac, 0); 8392 mac->mac_phy.rf_on = 0; 8393 bwn_mac_enable(mac); 8394} 8395 8396static void 8397bwn_phy_reset(struct bwn_mac *mac) 8398{ 8399 struct siba_dev_softc *sd = mac->mac_sd; 8400 8401 siba_write_4(sd, SIBA_TGSLOW, 8402 ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8403 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8404 DELAY(1000); 8405 siba_write_4(sd, SIBA_TGSLOW, 8406 (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8407 BWN_TGSLOW_PHYRESET); 8408 DELAY(1000); 8409} 8410 8411static int 8412bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8413{ 8414 struct bwn_vap *bvp = BWN_VAP(vap); 8415 struct ieee80211com *ic= vap->iv_ic; 8416 struct ifnet *ifp = ic->ic_ifp; 8417 enum ieee80211_state ostate = vap->iv_state; 8418 struct bwn_softc *sc = ifp->if_softc; 8419 struct bwn_mac *mac = sc->sc_curmac; 8420 int error; 8421 8422 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8423 ieee80211_state_name[vap->iv_state], 8424 ieee80211_state_name[nstate]); 8425 8426 error = bvp->bv_newstate(vap, nstate, arg); 8427 if (error != 0) 8428 return (error); 8429 8430 BWN_LOCK(sc); 8431 8432 bwn_led_newstate(mac, nstate); 8433 8434 /* 8435 * Clear the BSSID when we stop a STA 8436 */ 8437 if (vap->iv_opmode == IEEE80211_M_STA) { 8438 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8439 /* 8440 * Clear out the BSSID. If we reassociate to 8441 * the same AP, this will reinialize things 8442 * correctly... 8443 */ 8444 if (ic->ic_opmode == IEEE80211_M_STA && 8445 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8446 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8447 bwn_set_macaddr(mac); 8448 } 8449 } 8450 } 8451 8452 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8453 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8454 /* XXX nothing to do? */ 8455 } else if (nstate == IEEE80211_S_RUN) { 8456 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8457 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8458 bwn_set_opmode(mac); 8459 bwn_set_pretbtt(mac); 8460 bwn_spu_setdelay(mac, 0); 8461 bwn_set_macaddr(mac); 8462 } 8463 8464 BWN_UNLOCK(sc); 8465 8466 return (error); 8467} 8468 8469static void 8470bwn_set_pretbtt(struct bwn_mac *mac) 8471{ 8472 struct bwn_softc *sc = mac->mac_sc; 8473 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8474 uint16_t pretbtt; 8475 8476 if (ic->ic_opmode == IEEE80211_M_IBSS) 8477 pretbtt = 2; 8478 else 8479 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8480 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8481 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8482} 8483 8484static int 8485bwn_intr(void *arg) 8486{ 8487 struct bwn_mac *mac = arg; 8488 struct bwn_softc *sc = mac->mac_sc; 8489 struct siba_softc *siba = mac->mac_sd->sd_bus; 8490 uint32_t reason; 8491 8492 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) 8493 return (FILTER_STRAY); 8494 8495 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8496 if (reason == 0xffffffff) /* shared IRQ */ 8497 return (FILTER_STRAY); 8498 reason &= mac->mac_intr_mask; 8499 if (reason == 0) 8500 return (FILTER_HANDLED); 8501 8502 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8503 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8504 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8505 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8506 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8507 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8508 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8509 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8510 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8511 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8512 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8513 8514 /* Disable interrupts. */ 8515 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8516 8517 mac->mac_reason_intr = reason; 8518 8519 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8520 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8521 8522 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8523 return (FILTER_HANDLED); 8524} 8525 8526static void 8527bwn_intrtask(void *arg, int npending) 8528{ 8529 struct bwn_mac *mac = arg; 8530 struct bwn_softc *sc = mac->mac_sc; 8531 struct ifnet *ifp = sc->sc_ifp; 8532 struct siba_softc *siba = mac->mac_sd->sd_bus; 8533 uint32_t merged = 0; 8534 int i, tx = 0, rx = 0; 8535 8536 BWN_LOCK(sc); 8537 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) { 8538 BWN_UNLOCK(sc); 8539 return; 8540 } 8541 8542 for (i = 0; i < N(mac->mac_reason); i++) 8543 merged |= mac->mac_reason[i]; 8544 8545 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8546 device_printf(sc->sc_dev, "MAC trans error\n"); 8547 8548 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8549 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8550 mac->mac_phy.txerrors--; 8551 if (mac->mac_phy.txerrors == 0) { 8552 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8553 bwn_restart(mac, "PHY TX errors"); 8554 } 8555 } 8556 8557 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8558 if (merged & BWN_DMAINTR_FATALMASK) { 8559 device_printf(sc->sc_dev, 8560 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8561 mac->mac_reason[0], mac->mac_reason[1], 8562 mac->mac_reason[2], mac->mac_reason[3], 8563 mac->mac_reason[4], mac->mac_reason[5]); 8564 bwn_restart(mac, "DMA error"); 8565 BWN_UNLOCK(sc); 8566 return; 8567 } 8568 if (merged & BWN_DMAINTR_NONFATALMASK) { 8569 device_printf(sc->sc_dev, 8570 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8571 mac->mac_reason[0], mac->mac_reason[1], 8572 mac->mac_reason[2], mac->mac_reason[3], 8573 mac->mac_reason[4], mac->mac_reason[5]); 8574 } 8575 } 8576 8577 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8578 bwn_intr_ucode_debug(mac); 8579 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8580 bwn_intr_tbtt_indication(mac); 8581 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8582 bwn_intr_atim_end(mac); 8583 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8584 bwn_intr_beacon(mac); 8585 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8586 bwn_intr_pmq(mac); 8587 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8588 bwn_intr_noise(mac); 8589 8590 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8591 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8592 bwn_dma_rx(mac->mac_method.dma.rx); 8593 rx = 1; 8594 } 8595 } else 8596 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8597 8598 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8599 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8600 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8601 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8602 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8603 8604 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8605 bwn_intr_txeof(mac); 8606 tx = 1; 8607 } 8608 8609 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8610 8611 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8612 int evt = BWN_LED_EVENT_NONE; 8613 8614 if (tx && rx) { 8615 if (sc->sc_rx_rate > sc->sc_tx_rate) 8616 evt = BWN_LED_EVENT_RX; 8617 else 8618 evt = BWN_LED_EVENT_TX; 8619 } else if (tx) { 8620 evt = BWN_LED_EVENT_TX; 8621 } else if (rx) { 8622 evt = BWN_LED_EVENT_RX; 8623 } else if (rx == 0) { 8624 evt = BWN_LED_EVENT_POLL; 8625 } 8626 8627 if (evt != BWN_LED_EVENT_NONE) 8628 bwn_led_event(mac, evt); 8629 } 8630 8631 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8632 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8633 bwn_start_locked(ifp); 8634 } 8635 8636 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8637 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8638 8639 BWN_UNLOCK(sc); 8640} 8641 8642static void 8643bwn_restart(struct bwn_mac *mac, const char *msg) 8644{ 8645 struct bwn_softc *sc = mac->mac_sc; 8646 struct ifnet *ifp = sc->sc_ifp; 8647 struct ieee80211com *ic = ifp->if_l2com; 8648 8649 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8650 return; 8651 8652 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8653 ieee80211_runtask(ic, &mac->mac_hwreset); 8654} 8655 8656static void 8657bwn_intr_ucode_debug(struct bwn_mac *mac) 8658{ 8659 struct bwn_softc *sc = mac->mac_sc; 8660 uint16_t reason; 8661 8662 if (mac->mac_fw.opensource == 0) 8663 return; 8664 8665 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8666 switch (reason) { 8667 case BWN_DEBUGINTR_PANIC: 8668 bwn_handle_fwpanic(mac); 8669 break; 8670 case BWN_DEBUGINTR_DUMP_SHM: 8671 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8672 break; 8673 case BWN_DEBUGINTR_DUMP_REGS: 8674 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8675 break; 8676 case BWN_DEBUGINTR_MARKER: 8677 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8678 break; 8679 default: 8680 device_printf(sc->sc_dev, 8681 "ucode debug unknown reason: %#x\n", reason); 8682 } 8683 8684 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8685 BWN_DEBUGINTR_ACK); 8686} 8687 8688static void 8689bwn_intr_tbtt_indication(struct bwn_mac *mac) 8690{ 8691 struct bwn_softc *sc = mac->mac_sc; 8692 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8693 8694 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8695 bwn_psctl(mac, 0); 8696 if (ic->ic_opmode == IEEE80211_M_IBSS) 8697 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8698} 8699 8700static void 8701bwn_intr_atim_end(struct bwn_mac *mac) 8702{ 8703 8704 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8705 BWN_WRITE_4(mac, BWN_MACCMD, 8706 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8707 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8708 } 8709} 8710 8711static void 8712bwn_intr_beacon(struct bwn_mac *mac) 8713{ 8714 struct bwn_softc *sc = mac->mac_sc; 8715 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8716 uint32_t cmd, beacon0, beacon1; 8717 8718 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8719 ic->ic_opmode == IEEE80211_M_MBSS) 8720 return; 8721 8722 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8723 8724 cmd = BWN_READ_4(mac, BWN_MACCMD); 8725 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8726 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8727 8728 if (beacon0 && beacon1) { 8729 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8730 mac->mac_intr_mask |= BWN_INTR_BEACON; 8731 return; 8732 } 8733 8734 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8735 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8736 bwn_load_beacon0(mac); 8737 bwn_load_beacon1(mac); 8738 cmd = BWN_READ_4(mac, BWN_MACCMD); 8739 cmd |= BWN_MACCMD_BEACON0_VALID; 8740 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8741 } else { 8742 if (!beacon0) { 8743 bwn_load_beacon0(mac); 8744 cmd = BWN_READ_4(mac, BWN_MACCMD); 8745 cmd |= BWN_MACCMD_BEACON0_VALID; 8746 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8747 } else if (!beacon1) { 8748 bwn_load_beacon1(mac); 8749 cmd = BWN_READ_4(mac, BWN_MACCMD); 8750 cmd |= BWN_MACCMD_BEACON1_VALID; 8751 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8752 } 8753 } 8754} 8755 8756static void 8757bwn_intr_pmq(struct bwn_mac *mac) 8758{ 8759 uint32_t tmp; 8760 8761 while (1) { 8762 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8763 if (!(tmp & 0x00000008)) 8764 break; 8765 } 8766 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8767} 8768 8769static void 8770bwn_intr_noise(struct bwn_mac *mac) 8771{ 8772 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8773 uint16_t tmp; 8774 uint8_t noise[4]; 8775 uint8_t i, j; 8776 int32_t average; 8777 8778 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8779 return; 8780 8781 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8782 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8783 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8784 noise[3] == 0x7f) 8785 goto new; 8786 8787 KASSERT(mac->mac_noise.noi_nsamples < 8, 8788 ("%s:%d: fail", __func__, __LINE__)); 8789 i = mac->mac_noise.noi_nsamples; 8790 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8791 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8792 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8793 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8794 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8795 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8796 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8797 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8798 mac->mac_noise.noi_nsamples++; 8799 if (mac->mac_noise.noi_nsamples == 8) { 8800 average = 0; 8801 for (i = 0; i < 8; i++) { 8802 for (j = 0; j < 4; j++) 8803 average += mac->mac_noise.noi_samples[i][j]; 8804 } 8805 average = (((average / 32) * 125) + 64) / 128; 8806 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8807 if (tmp >= 8) 8808 average += 2; 8809 else 8810 average -= 25; 8811 average -= (tmp == 8) ? 72 : 48; 8812 8813 mac->mac_stats.link_noise = average; 8814 mac->mac_noise.noi_running = 0; 8815 return; 8816 } 8817new: 8818 bwn_noise_gensample(mac); 8819} 8820 8821static int 8822bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8823{ 8824 struct bwn_mac *mac = prq->prq_mac; 8825 struct bwn_softc *sc = mac->mac_sc; 8826 unsigned int i; 8827 8828 BWN_ASSERT_LOCKED(sc); 8829 8830 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8831 return (0); 8832 8833 for (i = 0; i < 5000; i++) { 8834 if (bwn_pio_rxeof(prq) == 0) 8835 break; 8836 } 8837 if (i >= 5000) 8838 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8839 return ((i > 0) ? 1 : 0); 8840} 8841 8842static void 8843bwn_dma_rx(struct bwn_dma_ring *dr) 8844{ 8845 int slot, curslot; 8846 8847 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8848 curslot = dr->get_curslot(dr); 8849 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8850 ("%s:%d: fail", __func__, __LINE__)); 8851 8852 slot = dr->dr_curslot; 8853 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8854 bwn_dma_rxeof(dr, &slot); 8855 8856 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8857 BUS_DMASYNC_PREWRITE); 8858 8859 dr->set_curslot(dr, slot); 8860 dr->dr_curslot = slot; 8861} 8862 8863static void 8864bwn_intr_txeof(struct bwn_mac *mac) 8865{ 8866 struct bwn_txstatus stat; 8867 uint32_t stat0, stat1; 8868 uint16_t tmp; 8869 8870 BWN_ASSERT_LOCKED(mac->mac_sc); 8871 8872 while (1) { 8873 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8874 if (!(stat0 & 0x00000001)) 8875 break; 8876 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8877 8878 stat.cookie = (stat0 >> 16); 8879 stat.seq = (stat1 & 0x0000ffff); 8880 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8881 tmp = (stat0 & 0x0000ffff); 8882 stat.framecnt = ((tmp & 0xf000) >> 12); 8883 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8884 stat.sreason = ((tmp & 0x001c) >> 2); 8885 stat.pm = (tmp & 0x0080) ? 1 : 0; 8886 stat.im = (tmp & 0x0040) ? 1 : 0; 8887 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8888 stat.ack = (tmp & 0x0002) ? 1 : 0; 8889 8890 bwn_handle_txeof(mac, &stat); 8891 } 8892} 8893 8894static void 8895bwn_hwreset(void *arg, int npending) 8896{ 8897 struct bwn_mac *mac = arg; 8898 struct bwn_softc *sc = mac->mac_sc; 8899 int error = 0; 8900 int prev_status; 8901 8902 BWN_LOCK(sc); 8903 8904 prev_status = mac->mac_status; 8905 if (prev_status >= BWN_MAC_STATUS_STARTED) 8906 bwn_core_stop(mac); 8907 if (prev_status >= BWN_MAC_STATUS_INITED) 8908 bwn_core_exit(mac); 8909 8910 if (prev_status >= BWN_MAC_STATUS_INITED) { 8911 error = bwn_core_init(mac); 8912 if (error) 8913 goto out; 8914 } 8915 if (prev_status >= BWN_MAC_STATUS_STARTED) 8916 bwn_core_start(mac); 8917out: 8918 if (error) { 8919 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8920 sc->sc_curmac = NULL; 8921 } 8922 BWN_UNLOCK(sc); 8923} 8924 8925static void 8926bwn_handle_fwpanic(struct bwn_mac *mac) 8927{ 8928 struct bwn_softc *sc = mac->mac_sc; 8929 uint16_t reason; 8930 8931 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8932 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8933 8934 if (reason == BWN_FWPANIC_RESTART) 8935 bwn_restart(mac, "ucode panic"); 8936} 8937 8938static void 8939bwn_load_beacon0(struct bwn_mac *mac) 8940{ 8941 8942 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8943} 8944 8945static void 8946bwn_load_beacon1(struct bwn_mac *mac) 8947{ 8948 8949 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8950} 8951 8952static uint32_t 8953bwn_jssi_read(struct bwn_mac *mac) 8954{ 8955 uint32_t val = 0; 8956 8957 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8958 val <<= 16; 8959 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8960 8961 return (val); 8962} 8963 8964static void 8965bwn_noise_gensample(struct bwn_mac *mac) 8966{ 8967 uint32_t jssi = 0x7f7f7f7f; 8968 8969 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8970 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8971 BWN_WRITE_4(mac, BWN_MACCMD, 8972 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8973} 8974 8975static int 8976bwn_dma_freeslot(struct bwn_dma_ring *dr) 8977{ 8978 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8979 8980 return (dr->dr_numslots - dr->dr_usedslot); 8981} 8982 8983static int 8984bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8985{ 8986 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8987 8988 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8989 ("%s:%d: fail", __func__, __LINE__)); 8990 if (slot == dr->dr_numslots - 1) 8991 return (0); 8992 return (slot + 1); 8993} 8994 8995static void 8996bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8997{ 8998 struct bwn_mac *mac = dr->dr_mac; 8999 struct bwn_softc *sc = mac->mac_sc; 9000 struct bwn_dma *dma = &mac->mac_method.dma; 9001 struct bwn_dmadesc_generic *desc; 9002 struct bwn_dmadesc_meta *meta; 9003 struct bwn_rxhdr4 *rxhdr; 9004 struct ifnet *ifp = sc->sc_ifp; 9005 struct mbuf *m; 9006 uint32_t macstat; 9007 int32_t tmp; 9008 int cnt = 0; 9009 uint16_t len; 9010 9011 dr->getdesc(dr, *slot, &desc, &meta); 9012 9013 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 9014 m = meta->mt_m; 9015 9016 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 9017 ifp->if_ierrors++; 9018 return; 9019 } 9020 9021 rxhdr = mtod(m, struct bwn_rxhdr4 *); 9022 len = le16toh(rxhdr->frame_len); 9023 if (len <= 0) { 9024 ifp->if_ierrors++; 9025 return; 9026 } 9027 if (bwn_dma_check_redzone(dr, m)) { 9028 device_printf(sc->sc_dev, "redzone error.\n"); 9029 bwn_dma_set_redzone(dr, m); 9030 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9031 BUS_DMASYNC_PREWRITE); 9032 return; 9033 } 9034 if (len > dr->dr_rx_bufsize) { 9035 tmp = len; 9036 while (1) { 9037 dr->getdesc(dr, *slot, &desc, &meta); 9038 bwn_dma_set_redzone(dr, meta->mt_m); 9039 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9040 BUS_DMASYNC_PREWRITE); 9041 *slot = bwn_dma_nextslot(dr, *slot); 9042 cnt++; 9043 tmp -= dr->dr_rx_bufsize; 9044 if (tmp <= 0) 9045 break; 9046 } 9047 device_printf(sc->sc_dev, "too small buffer " 9048 "(len %u buffer %u dropped %d)\n", 9049 len, dr->dr_rx_bufsize, cnt); 9050 return; 9051 } 9052 macstat = le32toh(rxhdr->mac_status); 9053 if (macstat & BWN_RX_MAC_FCSERR) { 9054 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9055 device_printf(sc->sc_dev, "RX drop\n"); 9056 return; 9057 } 9058 } 9059 9060 m->m_pkthdr.rcvif = ifp; 9061 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 9062 m_adj(m, dr->dr_frameoffset); 9063 9064 bwn_rxeof(dr->dr_mac, m, rxhdr); 9065} 9066 9067static void 9068bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 9069{ 9070 struct bwn_dma_ring *dr; 9071 struct bwn_dmadesc_generic *desc; 9072 struct bwn_dmadesc_meta *meta; 9073 struct bwn_node *bn; 9074 struct bwn_pio_txqueue *tq; 9075 struct bwn_pio_txpkt *tp = NULL; 9076 struct bwn_softc *sc = mac->mac_sc; 9077 struct bwn_stats *stats = &mac->mac_stats; 9078 struct ieee80211_node *ni; 9079 int slot; 9080 9081 BWN_ASSERT_LOCKED(mac->mac_sc); 9082 9083 if (status->im) 9084 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9085 if (status->ampdu) 9086 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9087 if (status->rtscnt) { 9088 if (status->rtscnt == 0xf) 9089 stats->rtsfail++; 9090 else 9091 stats->rts++; 9092 } 9093 9094 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9095 if (status->ack) { 9096 dr = bwn_dma_parse_cookie(mac, status, 9097 status->cookie, &slot); 9098 if (dr == NULL) { 9099 device_printf(sc->sc_dev, 9100 "failed to parse cookie\n"); 9101 return; 9102 } 9103 while (1) { 9104 dr->getdesc(dr, slot, &desc, &meta); 9105 if (meta->mt_islast) { 9106 ni = meta->mt_ni; 9107 bn = (struct bwn_node *)ni; 9108 ieee80211_amrr_tx_complete(&bn->bn_amn, 9109 status->ack, 0); 9110 break; 9111 } 9112 slot = bwn_dma_nextslot(dr, slot); 9113 } 9114 } 9115 bwn_dma_handle_txeof(mac, status); 9116 } else { 9117 if (status->ack) { 9118 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9119 if (tq == NULL) { 9120 device_printf(sc->sc_dev, 9121 "failed to parse cookie\n"); 9122 return; 9123 } 9124 ni = tp->tp_ni; 9125 bn = (struct bwn_node *)ni; 9126 ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0); 9127 } 9128 bwn_pio_handle_txeof(mac, status); 9129 } 9130 9131 bwn_phy_txpower_check(mac, 0); 9132} 9133 9134static uint8_t 9135bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9136{ 9137 struct bwn_mac *mac = prq->prq_mac; 9138 struct bwn_softc *sc = mac->mac_sc; 9139 struct bwn_rxhdr4 rxhdr; 9140 struct ifnet *ifp = sc->sc_ifp; 9141 struct mbuf *m; 9142 uint32_t ctl32, macstat, v32; 9143 unsigned int i, padding; 9144 uint16_t ctl16, len, v16; 9145 unsigned char *mp; 9146 char *data; 9147 9148 memset(&rxhdr, 0, sizeof(rxhdr)); 9149 9150 if (prq->prq_rev >= 8) { 9151 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9152 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9153 return (0); 9154 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9155 BWN_PIO8_RXCTL_FRAMEREADY); 9156 for (i = 0; i < 10; i++) { 9157 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9158 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9159 goto ready; 9160 DELAY(10); 9161 } 9162 } else { 9163 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9164 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9165 return (0); 9166 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9167 BWN_PIO_RXCTL_FRAMEREADY); 9168 for (i = 0; i < 10; i++) { 9169 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9170 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9171 goto ready; 9172 DELAY(10); 9173 } 9174 } 9175 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9176 return (1); 9177ready: 9178 if (prq->prq_rev >= 8) 9179 siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9180 prq->prq_base + BWN_PIO8_RXDATA); 9181 else 9182 siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9183 prq->prq_base + BWN_PIO_RXDATA); 9184 len = le16toh(rxhdr.frame_len); 9185 if (len > 0x700) { 9186 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9187 goto error; 9188 } 9189 if (len == 0) { 9190 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9191 goto error; 9192 } 9193 9194 macstat = le32toh(rxhdr.mac_status); 9195 if (macstat & BWN_RX_MAC_FCSERR) { 9196 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9197 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9198 goto error; 9199 } 9200 } 9201 9202 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9203 KASSERT(len + padding <= MCLBYTES, ("too big..\n")); 9204 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9205 if (m == NULL) { 9206 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9207 goto error; 9208 } 9209 mp = mtod(m, unsigned char *); 9210 if (prq->prq_rev >= 8) { 9211 siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3), 9212 prq->prq_base + BWN_PIO8_RXDATA); 9213 if (len & 3) { 9214 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9215 data = &(mp[len + padding - 1]); 9216 switch (len & 3) { 9217 case 3: 9218 *data = (v32 >> 16); 9219 data--; 9220 case 2: 9221 *data = (v32 >> 8); 9222 data--; 9223 case 1: 9224 *data = v32; 9225 } 9226 } 9227 } else { 9228 siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1), 9229 prq->prq_base + BWN_PIO_RXDATA); 9230 if (len & 1) { 9231 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9232 mp[len + padding - 1] = v16; 9233 } 9234 } 9235 9236 m->m_pkthdr.rcvif = ifp; 9237 m->m_len = m->m_pkthdr.len = len + padding; 9238 9239 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9240 9241 return (1); 9242error: 9243 if (prq->prq_rev >= 8) 9244 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9245 BWN_PIO8_RXCTL_DATAREADY); 9246 else 9247 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9248 return (1); 9249} 9250 9251static int 9252bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9253 struct bwn_dmadesc_meta *meta, int init) 9254{ 9255 struct bwn_mac *mac = dr->dr_mac; 9256 struct bwn_dma *dma = &mac->mac_method.dma; 9257 struct bwn_rxhdr4 *hdr; 9258 bus_dmamap_t map; 9259 bus_addr_t paddr; 9260 struct mbuf *m; 9261 int error; 9262 9263 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9264 if (m == NULL) { 9265 error = ENOBUFS; 9266 9267 /* 9268 * If the NIC is up and running, we need to: 9269 * - Clear RX buffer's header. 9270 * - Restore RX descriptor settings. 9271 */ 9272 if (init) 9273 return (error); 9274 else 9275 goto back; 9276 } 9277 m->m_len = m->m_pkthdr.len = MCLBYTES; 9278 9279 bwn_dma_set_redzone(dr, m); 9280 9281 /* 9282 * Try to load RX buf into temporary DMA map 9283 */ 9284 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9285 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9286 if (error) { 9287 m_freem(m); 9288 9289 /* 9290 * See the comment above 9291 */ 9292 if (init) 9293 return (error); 9294 else 9295 goto back; 9296 } 9297 9298 if (!init) 9299 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9300 meta->mt_m = m; 9301 meta->mt_paddr = paddr; 9302 9303 /* 9304 * Swap RX buf's DMA map with the loaded temporary one 9305 */ 9306 map = meta->mt_dmap; 9307 meta->mt_dmap = dr->dr_spare_dmap; 9308 dr->dr_spare_dmap = map; 9309 9310back: 9311 /* 9312 * Clear RX buf header 9313 */ 9314 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9315 bzero(hdr, sizeof(*hdr)); 9316 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9317 BUS_DMASYNC_PREWRITE); 9318 9319 /* 9320 * Setup RX buf descriptor 9321 */ 9322 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9323 sizeof(*hdr), 0, 0, 0); 9324 return (error); 9325} 9326 9327static void 9328bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9329 bus_size_t mapsz __unused, int error) 9330{ 9331 9332 if (!error) { 9333 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9334 *((bus_addr_t *)arg) = seg->ds_addr; 9335 } 9336} 9337 9338static int 9339bwn_hwrate2ieeerate(int rate) 9340{ 9341 9342 switch (rate) { 9343 case BWN_CCK_RATE_1MB: 9344 return (2); 9345 case BWN_CCK_RATE_2MB: 9346 return (4); 9347 case BWN_CCK_RATE_5MB: 9348 return (11); 9349 case BWN_CCK_RATE_11MB: 9350 return (22); 9351 case BWN_OFDM_RATE_6MB: 9352 return (12); 9353 case BWN_OFDM_RATE_9MB: 9354 return (18); 9355 case BWN_OFDM_RATE_12MB: 9356 return (24); 9357 case BWN_OFDM_RATE_18MB: 9358 return (36); 9359 case BWN_OFDM_RATE_24MB: 9360 return (48); 9361 case BWN_OFDM_RATE_36MB: 9362 return (72); 9363 case BWN_OFDM_RATE_48MB: 9364 return (96); 9365 case BWN_OFDM_RATE_54MB: 9366 return (108); 9367 default: 9368 printf("Ooops\n"); 9369 return (0); 9370 } 9371} 9372 9373static void 9374bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9375{ 9376 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9377 struct bwn_plcp6 *plcp; 9378 struct bwn_softc *sc = mac->mac_sc; 9379 struct ieee80211_frame_min *wh; 9380 struct ieee80211_node *ni; 9381 struct ifnet *ifp = sc->sc_ifp; 9382 struct ieee80211com *ic = ifp->if_l2com; 9383 uint32_t macstat; 9384 int padding, rate, rssi = 0, noise = 0, type; 9385 uint16_t phytype, phystat0, phystat3, chanstat; 9386 unsigned char *mp = mtod(m, unsigned char *); 9387 static int rx_mac_dec_rpt = 0; 9388 9389 BWN_ASSERT_LOCKED(sc); 9390 9391 phystat0 = le16toh(rxhdr->phy_status0); 9392 phystat3 = le16toh(rxhdr->phy_status3); 9393 macstat = le32toh(rxhdr->mac_status); 9394 chanstat = le16toh(rxhdr->channel); 9395 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9396 9397 if (macstat & BWN_RX_MAC_FCSERR) 9398 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9399 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9400 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9401 if (macstat & BWN_RX_MAC_DECERR) 9402 goto drop; 9403 9404 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9405 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9406 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9407 m->m_pkthdr.len); 9408 goto drop; 9409 } 9410 plcp = (struct bwn_plcp6 *)(mp + padding); 9411 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9412 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9413 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9414 m->m_pkthdr.len); 9415 goto drop; 9416 } 9417 wh = mtod(m, struct ieee80211_frame_min *); 9418 9419 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9420 device_printf(sc->sc_dev, 9421 "RX decryption attempted (old %d keyidx %#x)\n", 9422 BWN_ISOLDFMT(mac), 9423 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9424 9425 /* XXX calculating RSSI & noise & antenna */ 9426 9427 if (phystat0 & BWN_RX_PHYST0_OFDM) 9428 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9429 phytype == BWN_PHYTYPE_A); 9430 else 9431 rate = bwn_plcp_get_cckrate(mac, plcp); 9432 if (rate == -1) { 9433 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9434 goto drop; 9435 } 9436 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9437 9438 /* RX radio tap */ 9439 if (ieee80211_radiotap_active(ic)) 9440 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9441 m_adj(m, -IEEE80211_CRC_LEN); 9442 9443 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9444 noise = mac->mac_stats.link_noise; 9445 9446 BWN_UNLOCK(sc); 9447 9448 ni = ieee80211_find_rxnode(ic, wh); 9449 if (ni != NULL) { 9450 type = ieee80211_input(ni, m, rssi, noise); 9451 ieee80211_free_node(ni); 9452 } else 9453 type = ieee80211_input_all(ic, m, rssi, noise); 9454 9455 BWN_LOCK(sc); 9456 return; 9457drop: 9458 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9459} 9460 9461static void 9462bwn_dma_handle_txeof(struct bwn_mac *mac, 9463 const struct bwn_txstatus *status) 9464{ 9465 struct bwn_dma *dma = &mac->mac_method.dma; 9466 struct bwn_dma_ring *dr; 9467 struct bwn_dmadesc_generic *desc; 9468 struct bwn_dmadesc_meta *meta; 9469 struct bwn_softc *sc = mac->mac_sc; 9470 struct ieee80211_node *ni; 9471 struct ifnet *ifp = sc->sc_ifp; 9472 struct mbuf *m; 9473 int slot; 9474 9475 BWN_ASSERT_LOCKED(sc); 9476 9477 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9478 if (dr == NULL) { 9479 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9480 return; 9481 } 9482 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9483 9484 while (1) { 9485 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9486 ("%s:%d: fail", __func__, __LINE__)); 9487 dr->getdesc(dr, slot, &desc, &meta); 9488 9489 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9490 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9491 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9492 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9493 9494 if (meta->mt_islast) { 9495 KASSERT(meta->mt_m != NULL, 9496 ("%s:%d: fail", __func__, __LINE__)); 9497 9498 ni = meta->mt_ni; 9499 m = meta->mt_m; 9500 if (ni != NULL) { 9501 /* 9502 * Do any tx complete callback. Note this must 9503 * be done before releasing the node reference. 9504 */ 9505 if (m->m_flags & M_TXCB) 9506 ieee80211_process_callback(ni, m, 0); 9507 ieee80211_free_node(ni); 9508 meta->mt_ni = NULL; 9509 } 9510 m_freem(m); 9511 meta->mt_m = NULL; 9512 } else { 9513 KASSERT(meta->mt_m == NULL, 9514 ("%s:%d: fail", __func__, __LINE__)); 9515 } 9516 9517 dr->dr_usedslot--; 9518 if (meta->mt_islast) { 9519 ifp->if_opackets++; 9520 break; 9521 } 9522 slot = bwn_dma_nextslot(dr, slot); 9523 } 9524 sc->sc_watchdog_timer = 0; 9525 if (dr->dr_stop) { 9526 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9527 ("%s:%d: fail", __func__, __LINE__)); 9528 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9529 dr->dr_stop = 0; 9530 } 9531} 9532 9533static void 9534bwn_pio_handle_txeof(struct bwn_mac *mac, 9535 const struct bwn_txstatus *status) 9536{ 9537 struct bwn_pio_txqueue *tq; 9538 struct bwn_pio_txpkt *tp = NULL; 9539 struct bwn_softc *sc = mac->mac_sc; 9540 struct ifnet *ifp = sc->sc_ifp; 9541 9542 BWN_ASSERT_LOCKED(sc); 9543 9544 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9545 if (tq == NULL) 9546 return; 9547 9548 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9549 tq->tq_free++; 9550 9551 if (tp->tp_ni != NULL) { 9552 /* 9553 * Do any tx complete callback. Note this must 9554 * be done before releasing the node reference. 9555 */ 9556 if (tp->tp_m->m_flags & M_TXCB) 9557 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9558 ieee80211_free_node(tp->tp_ni); 9559 tp->tp_ni = NULL; 9560 } 9561 m_freem(tp->tp_m); 9562 tp->tp_m = NULL; 9563 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9564 9565 ifp->if_opackets++; 9566 9567 sc->sc_watchdog_timer = 0; 9568 if (tq->tq_stop) { 9569 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9570 tq->tq_stop = 0; 9571 } 9572} 9573 9574static void 9575bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9576{ 9577 struct bwn_softc *sc = mac->mac_sc; 9578 struct bwn_phy *phy = &mac->mac_phy; 9579 struct ifnet *ifp = sc->sc_ifp; 9580 struct ieee80211com *ic = ifp->if_l2com; 9581 struct siba_softc *siba = mac->mac_sd->sd_bus; 9582 unsigned long now; 9583 int result; 9584 9585 BWN_GETTIME(now); 9586 9587 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9588 return; 9589 phy->nexttime = now + 2 * 1000; 9590 9591 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 9592 siba->siba_board_type == SIBA_BOARD_BU4306) 9593 return; 9594 9595 if (phy->recalc_txpwr != NULL) { 9596 result = phy->recalc_txpwr(mac, 9597 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9598 if (result == BWN_TXPWR_RES_DONE) 9599 return; 9600 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9601 ("%s: fail", __func__)); 9602 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9603 9604 ieee80211_runtask(ic, &mac->mac_txpower); 9605 } 9606} 9607 9608static uint16_t 9609bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9610{ 9611 9612 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9613} 9614 9615static uint32_t 9616bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9617{ 9618 9619 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9620} 9621 9622static void 9623bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9624{ 9625 9626 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9627} 9628 9629static void 9630bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9631{ 9632 9633 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9634} 9635 9636static int 9637bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9638{ 9639 9640 switch (rate) { 9641 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9642 case 12: 9643 return (BWN_OFDM_RATE_6MB); 9644 case 18: 9645 return (BWN_OFDM_RATE_9MB); 9646 case 24: 9647 return (BWN_OFDM_RATE_12MB); 9648 case 36: 9649 return (BWN_OFDM_RATE_18MB); 9650 case 48: 9651 return (BWN_OFDM_RATE_24MB); 9652 case 72: 9653 return (BWN_OFDM_RATE_36MB); 9654 case 96: 9655 return (BWN_OFDM_RATE_48MB); 9656 case 108: 9657 return (BWN_OFDM_RATE_54MB); 9658 /* CCK rates (NB: not IEEE std, device-specific) */ 9659 case 2: 9660 return (BWN_CCK_RATE_1MB); 9661 case 4: 9662 return (BWN_CCK_RATE_2MB); 9663 case 11: 9664 return (BWN_CCK_RATE_5MB); 9665 case 22: 9666 return (BWN_CCK_RATE_11MB); 9667 } 9668 9669 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9670 return (BWN_CCK_RATE_1MB); 9671} 9672 9673static int 9674bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9675 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9676{ 9677 const struct bwn_phy *phy = &mac->mac_phy; 9678 struct bwn_softc *sc = mac->mac_sc; 9679 struct ieee80211_frame *wh; 9680 struct ieee80211_frame *protwh; 9681 struct ieee80211_frame_cts *cts; 9682 struct ieee80211_frame_rts *rts; 9683 const struct ieee80211_txparam *tp; 9684 struct ieee80211vap *vap = ni->ni_vap; 9685 struct ifnet *ifp = sc->sc_ifp; 9686 struct ieee80211com *ic = ifp->if_l2com; 9687 struct mbuf *mprot; 9688 unsigned int len; 9689 uint32_t macctl = 0; 9690 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9691 uint16_t phyctl = 0; 9692 uint8_t rate, rate_fb; 9693 9694 wh = mtod(m, struct ieee80211_frame *); 9695 memset(txhdr, 0, sizeof(*txhdr)); 9696 9697 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9698 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9699 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9700 9701 /* 9702 * Find TX rate 9703 */ 9704 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9705 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9706 rate = rate_fb = tp->mgmtrate; 9707 else if (ismcast) 9708 rate = rate_fb = tp->mcastrate; 9709 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9710 rate = rate_fb = tp->ucastrate; 9711 else { 9712 rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn); 9713 rate = ni->ni_txrate; 9714 9715 if (rix > 0) 9716 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9717 IEEE80211_RATE_VAL; 9718 else 9719 rate_fb = rate; 9720 } 9721 9722 sc->sc_tx_rate = rate; 9723 9724 rate = bwn_ieeerate2hwrate(sc, rate); 9725 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9726 9727 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9728 bwn_plcp_getcck(rate); 9729 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9730 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9731 9732 if ((rate_fb == rate) || 9733 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9734 (*(u_int16_t *)wh->i_dur == htole16(0))) 9735 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9736 else 9737 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9738 m->m_pkthdr.len, rate, isshort); 9739 9740 /* XXX TX encryption */ 9741 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9742 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9743 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9744 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9745 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9746 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9747 9748 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9749 BWN_TX_EFT_FB_CCK; 9750 txhdr->chan = phy->chan; 9751 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9752 BWN_TX_PHY_ENC_CCK; 9753 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9754 rate == BWN_CCK_RATE_11MB)) 9755 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9756 9757 /* XXX TX antenna selection */ 9758 9759 switch (bwn_antenna_sanitize(mac, 0)) { 9760 case 0: 9761 phyctl |= BWN_TX_PHY_ANT01AUTO; 9762 break; 9763 case 1: 9764 phyctl |= BWN_TX_PHY_ANT0; 9765 break; 9766 case 2: 9767 phyctl |= BWN_TX_PHY_ANT1; 9768 break; 9769 case 3: 9770 phyctl |= BWN_TX_PHY_ANT2; 9771 break; 9772 case 4: 9773 phyctl |= BWN_TX_PHY_ANT3; 9774 break; 9775 default: 9776 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9777 } 9778 9779 if (!ismcast) 9780 macctl |= BWN_TX_MAC_ACK; 9781 9782 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9783 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9784 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9785 macctl |= BWN_TX_MAC_LONGFRAME; 9786 9787 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9788 /* XXX RTS rate is always 1MB??? */ 9789 rts_rate = BWN_CCK_RATE_1MB; 9790 rts_rate_fb = bwn_get_fbrate(rts_rate); 9791 9792 protdur = ieee80211_compute_duration(ic->ic_rt, 9793 m->m_pkthdr.len, rate, isshort) + 9794 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9795 9796 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9797 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9798 (txhdr->body.old.rts_frame) : 9799 (txhdr->body.new.rts_frame)); 9800 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9801 protdur); 9802 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9803 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9804 mprot->m_pkthdr.len); 9805 m_freem(mprot); 9806 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9807 len = sizeof(struct ieee80211_frame_cts); 9808 } else { 9809 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9810 (txhdr->body.old.rts_frame) : 9811 (txhdr->body.new.rts_frame)); 9812 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9813 isshort); 9814 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9815 wh->i_addr2, protdur); 9816 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9817 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9818 mprot->m_pkthdr.len); 9819 m_freem(mprot); 9820 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9821 len = sizeof(struct ieee80211_frame_rts); 9822 } 9823 len += IEEE80211_CRC_LEN; 9824 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9825 &txhdr->body.old.rts_plcp : 9826 &txhdr->body.new.rts_plcp), len, rts_rate); 9827 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9828 rts_rate_fb); 9829 9830 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9831 (&txhdr->body.old.rts_frame) : 9832 (&txhdr->body.new.rts_frame)); 9833 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9834 9835 if (BWN_ISOFDMRATE(rts_rate)) { 9836 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9837 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9838 } else { 9839 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9840 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9841 } 9842 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9843 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9844 } 9845 9846 if (BWN_ISOLDFMT(mac)) 9847 txhdr->body.old.cookie = htole16(cookie); 9848 else 9849 txhdr->body.new.cookie = htole16(cookie); 9850 9851 txhdr->macctl = htole32(macctl); 9852 txhdr->phyctl = htole16(phyctl); 9853 9854 /* 9855 * TX radio tap 9856 */ 9857 if (ieee80211_radiotap_active_vap(vap)) { 9858 sc->sc_tx_th.wt_flags = 0; 9859 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9860 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9861 if (isshort && 9862 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9863 rate == BWN_CCK_RATE_11MB)) 9864 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9865 sc->sc_tx_th.wt_rate = rate; 9866 9867 ieee80211_radiotap_tx(vap, m); 9868 } 9869 9870 return (0); 9871} 9872 9873static void 9874bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9875 const uint8_t rate) 9876{ 9877 uint32_t d, plen; 9878 uint8_t *raw = plcp->o.raw; 9879 9880 if (BWN_ISOFDMRATE(rate)) { 9881 d = bwn_plcp_getofdm(rate); 9882 KASSERT(!(octets & 0xf000), 9883 ("%s:%d: fail", __func__, __LINE__)); 9884 d |= (octets << 5); 9885 plcp->o.data = htole32(d); 9886 } else { 9887 plen = octets * 16 / rate; 9888 if ((octets * 16 % rate) > 0) { 9889 plen++; 9890 if ((rate == BWN_CCK_RATE_11MB) 9891 && ((octets * 8 % 11) < 4)) { 9892 raw[1] = 0x84; 9893 } else 9894 raw[1] = 0x04; 9895 } else 9896 raw[1] = 0x04; 9897 plcp->o.data |= htole32(plen << 16); 9898 raw[0] = bwn_plcp_getcck(rate); 9899 } 9900} 9901 9902static uint8_t 9903bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9904{ 9905 uint8_t mask; 9906 9907 if (n == 0) 9908 return (0); 9909 if (mac->mac_phy.gmode) 9910 mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg; 9911 else 9912 mask = mac->mac_sd->sd_bus->siba_sprom.ant_a; 9913 if (!(mask & (1 << (n - 1)))) 9914 return (0); 9915 return (n); 9916} 9917 9918static uint8_t 9919bwn_get_fbrate(uint8_t bitrate) 9920{ 9921 switch (bitrate) { 9922 case BWN_CCK_RATE_1MB: 9923 return (BWN_CCK_RATE_1MB); 9924 case BWN_CCK_RATE_2MB: 9925 return (BWN_CCK_RATE_1MB); 9926 case BWN_CCK_RATE_5MB: 9927 return (BWN_CCK_RATE_2MB); 9928 case BWN_CCK_RATE_11MB: 9929 return (BWN_CCK_RATE_5MB); 9930 case BWN_OFDM_RATE_6MB: 9931 return (BWN_CCK_RATE_5MB); 9932 case BWN_OFDM_RATE_9MB: 9933 return (BWN_OFDM_RATE_6MB); 9934 case BWN_OFDM_RATE_12MB: 9935 return (BWN_OFDM_RATE_9MB); 9936 case BWN_OFDM_RATE_18MB: 9937 return (BWN_OFDM_RATE_12MB); 9938 case BWN_OFDM_RATE_24MB: 9939 return (BWN_OFDM_RATE_18MB); 9940 case BWN_OFDM_RATE_36MB: 9941 return (BWN_OFDM_RATE_24MB); 9942 case BWN_OFDM_RATE_48MB: 9943 return (BWN_OFDM_RATE_36MB); 9944 case BWN_OFDM_RATE_54MB: 9945 return (BWN_OFDM_RATE_48MB); 9946 } 9947 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9948 return (0); 9949} 9950 9951static uint32_t 9952bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9953 uint32_t ctl, const void *_data, int len) 9954{ 9955 uint32_t value = 0; 9956 const uint8_t *data = _data; 9957 9958 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9959 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9960 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9961 9962 siba_write_multi_4(mac->mac_sd, data, (len & ~3), 9963 tq->tq_base + BWN_PIO8_TXDATA); 9964 if (len & 3) { 9965 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9966 BWN_PIO8_TXCTL_24_31); 9967 data = &(data[len - 1]); 9968 switch (len & 3) { 9969 case 3: 9970 ctl |= BWN_PIO8_TXCTL_16_23; 9971 value |= (uint32_t)(*data) << 16; 9972 data--; 9973 case 2: 9974 ctl |= BWN_PIO8_TXCTL_8_15; 9975 value |= (uint32_t)(*data) << 8; 9976 data--; 9977 case 1: 9978 value |= (uint32_t)(*data); 9979 } 9980 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9981 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9982 } 9983 9984 return (ctl); 9985} 9986 9987static void 9988bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9989 uint16_t offset, uint32_t value) 9990{ 9991 9992 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9993} 9994 9995static uint16_t 9996bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9997 uint16_t ctl, const void *_data, int len) 9998{ 9999 const uint8_t *data = _data; 10000 10001 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10002 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10003 10004 siba_write_multi_2(mac->mac_sd, data, (len & ~1), 10005 tq->tq_base + BWN_PIO_TXDATA); 10006 if (len & 1) { 10007 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10008 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10009 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 10010 } 10011 10012 return (ctl); 10013} 10014 10015static uint16_t 10016bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 10017 uint16_t ctl, struct mbuf *m0) 10018{ 10019 int i, j = 0; 10020 uint16_t data = 0; 10021 const uint8_t *buf; 10022 struct mbuf *m = m0; 10023 10024 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10025 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10026 10027 for (; m != NULL; m = m->m_next) { 10028 buf = mtod(m, const uint8_t *); 10029 for (i = 0; i < m->m_len; i++) { 10030 if (!((j++) % 2)) 10031 data |= buf[i]; 10032 else { 10033 data |= (buf[i] << 8); 10034 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10035 data = 0; 10036 } 10037 } 10038 } 10039 if (m0->m_pkthdr.len % 2) { 10040 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10041 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10042 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10043 } 10044 10045 return (ctl); 10046} 10047 10048static void 10049bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 10050{ 10051 10052 if (mac->mac_phy.type != BWN_PHYTYPE_G) 10053 return; 10054 BWN_WRITE_2(mac, 0x684, 510 + time); 10055 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 10056} 10057 10058static struct bwn_dma_ring * 10059bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 10060{ 10061 10062 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 10063 return (mac->mac_method.dma.wme[WME_AC_BE]); 10064 10065 switch (prio) { 10066 case 3: 10067 return (mac->mac_method.dma.wme[WME_AC_VO]); 10068 case 2: 10069 return (mac->mac_method.dma.wme[WME_AC_VI]); 10070 case 0: 10071 return (mac->mac_method.dma.wme[WME_AC_BE]); 10072 case 1: 10073 return (mac->mac_method.dma.wme[WME_AC_BK]); 10074 } 10075 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10076 return (NULL); 10077} 10078 10079static int 10080bwn_dma_getslot(struct bwn_dma_ring *dr) 10081{ 10082 int slot; 10083 10084 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10085 10086 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10087 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10088 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10089 10090 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10091 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10092 dr->dr_curslot = slot; 10093 dr->dr_usedslot++; 10094 10095 return (slot); 10096} 10097 10098static int 10099bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10100{ 10101 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10102 unsigned int a, b, c, d; 10103 unsigned int avg; 10104 uint32_t tmp; 10105 10106 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10107 a = tmp & 0xff; 10108 b = (tmp >> 8) & 0xff; 10109 c = (tmp >> 16) & 0xff; 10110 d = (tmp >> 24) & 0xff; 10111 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10112 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10113 return (ENOENT); 10114 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10115 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10116 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10117 10118 if (ofdm) { 10119 a = (a + 32) & 0x3f; 10120 b = (b + 32) & 0x3f; 10121 c = (c + 32) & 0x3f; 10122 d = (d + 32) & 0x3f; 10123 } 10124 10125 avg = (a + b + c + d + 2) / 4; 10126 if (ofdm) { 10127 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10128 & BWN_HF_4DB_CCK_POWERBOOST) 10129 avg = (avg >= 13) ? (avg - 13) : 0; 10130 } 10131 return (avg); 10132} 10133 10134static void 10135bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10136{ 10137 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10138 int rfatt = *rfattp; 10139 int bbatt = *bbattp; 10140 10141 while (1) { 10142 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10143 break; 10144 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10145 break; 10146 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10147 break; 10148 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10149 break; 10150 if (bbatt > lo->bbatt.max) { 10151 bbatt -= 4; 10152 rfatt += 1; 10153 continue; 10154 } 10155 if (bbatt < lo->bbatt.min) { 10156 bbatt += 4; 10157 rfatt -= 1; 10158 continue; 10159 } 10160 if (rfatt > lo->rfatt.max) { 10161 rfatt -= 1; 10162 bbatt += 4; 10163 continue; 10164 } 10165 if (rfatt < lo->rfatt.min) { 10166 rfatt += 1; 10167 bbatt -= 4; 10168 continue; 10169 } 10170 break; 10171 } 10172 10173 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10174 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10175} 10176 10177static void 10178bwn_phy_lock(struct bwn_mac *mac) 10179{ 10180 struct bwn_softc *sc = mac->mac_sc; 10181 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10182 10183 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10184 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10185 10186 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10187 bwn_psctl(mac, BWN_PS_AWAKE); 10188} 10189 10190static void 10191bwn_phy_unlock(struct bwn_mac *mac) 10192{ 10193 struct bwn_softc *sc = mac->mac_sc; 10194 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10195 10196 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10197 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10198 10199 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10200 bwn_psctl(mac, 0); 10201} 10202 10203static void 10204bwn_rf_lock(struct bwn_mac *mac) 10205{ 10206 10207 BWN_WRITE_4(mac, BWN_MACCTL, 10208 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10209 BWN_READ_4(mac, BWN_MACCTL); 10210 DELAY(10); 10211} 10212 10213static void 10214bwn_rf_unlock(struct bwn_mac *mac) 10215{ 10216 10217 BWN_READ_2(mac, BWN_PHYVER); 10218 BWN_WRITE_4(mac, BWN_MACCTL, 10219 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10220} 10221 10222static struct bwn_pio_txqueue * 10223bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10224 struct bwn_pio_txpkt **pack) 10225{ 10226 struct bwn_pio *pio = &mac->mac_method.pio; 10227 struct bwn_pio_txqueue *tq = NULL; 10228 unsigned int index; 10229 10230 switch (cookie & 0xf000) { 10231 case 0x1000: 10232 tq = &pio->wme[WME_AC_BK]; 10233 break; 10234 case 0x2000: 10235 tq = &pio->wme[WME_AC_BE]; 10236 break; 10237 case 0x3000: 10238 tq = &pio->wme[WME_AC_VI]; 10239 break; 10240 case 0x4000: 10241 tq = &pio->wme[WME_AC_VO]; 10242 break; 10243 case 0x5000: 10244 tq = &pio->mcast; 10245 break; 10246 } 10247 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10248 if (tq == NULL) 10249 return (NULL); 10250 index = (cookie & 0x0fff); 10251 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10252 if (index >= N(tq->tq_pkts)) 10253 return (NULL); 10254 *pack = &tq->tq_pkts[index]; 10255 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10256 return (tq); 10257} 10258 10259static void 10260bwn_txpwr(void *arg, int npending) 10261{ 10262 struct bwn_mac *mac = arg; 10263 struct bwn_softc *sc = mac->mac_sc; 10264 10265 BWN_LOCK(sc); 10266 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10267 mac->mac_phy.set_txpwr != NULL) 10268 mac->mac_phy.set_txpwr(mac); 10269 BWN_UNLOCK(sc); 10270} 10271 10272static void 10273bwn_task_15s(struct bwn_mac *mac) 10274{ 10275 uint16_t reg; 10276 10277 if (mac->mac_fw.opensource) { 10278 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10279 if (reg) { 10280 bwn_restart(mac, "fw watchdog"); 10281 return; 10282 } 10283 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10284 } 10285 if (mac->mac_phy.task_15s) 10286 mac->mac_phy.task_15s(mac); 10287 10288 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10289} 10290 10291static void 10292bwn_task_30s(struct bwn_mac *mac) 10293{ 10294 10295 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10296 return; 10297 mac->mac_noise.noi_running = 1; 10298 mac->mac_noise.noi_nsamples = 0; 10299 10300 bwn_noise_gensample(mac); 10301} 10302 10303static void 10304bwn_task_60s(struct bwn_mac *mac) 10305{ 10306 10307 if (mac->mac_phy.task_60s) 10308 mac->mac_phy.task_60s(mac); 10309 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10310} 10311 10312static void 10313bwn_tasks(void *arg) 10314{ 10315 struct bwn_mac *mac = arg; 10316 struct bwn_softc *sc = mac->mac_sc; 10317 10318 BWN_ASSERT_LOCKED(sc); 10319 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10320 return; 10321 10322 if (mac->mac_task_state % 4 == 0) 10323 bwn_task_60s(mac); 10324 if (mac->mac_task_state % 2 == 0) 10325 bwn_task_30s(mac); 10326 bwn_task_15s(mac); 10327 10328 mac->mac_task_state++; 10329 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10330} 10331 10332static int 10333bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10334{ 10335 struct bwn_softc *sc = mac->mac_sc; 10336 10337 KASSERT(a == 0, ("not support APHY\n")); 10338 10339 switch (plcp->o.raw[0] & 0xf) { 10340 case 0xb: 10341 return (BWN_OFDM_RATE_6MB); 10342 case 0xf: 10343 return (BWN_OFDM_RATE_9MB); 10344 case 0xa: 10345 return (BWN_OFDM_RATE_12MB); 10346 case 0xe: 10347 return (BWN_OFDM_RATE_18MB); 10348 case 0x9: 10349 return (BWN_OFDM_RATE_24MB); 10350 case 0xd: 10351 return (BWN_OFDM_RATE_36MB); 10352 case 0x8: 10353 return (BWN_OFDM_RATE_48MB); 10354 case 0xc: 10355 return (BWN_OFDM_RATE_54MB); 10356 } 10357 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10358 plcp->o.raw[0] & 0xf); 10359 return (-1); 10360} 10361 10362static int 10363bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10364{ 10365 struct bwn_softc *sc = mac->mac_sc; 10366 10367 switch (plcp->o.raw[0]) { 10368 case 0x0a: 10369 return (BWN_CCK_RATE_1MB); 10370 case 0x14: 10371 return (BWN_CCK_RATE_2MB); 10372 case 0x37: 10373 return (BWN_CCK_RATE_5MB); 10374 case 0x6e: 10375 return (BWN_CCK_RATE_11MB); 10376 } 10377 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10378 return (-1); 10379} 10380 10381static void 10382bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10383 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10384 int rssi, int noise) 10385{ 10386 struct bwn_softc *sc = mac->mac_sc; 10387 const struct ieee80211_frame_min *wh; 10388 uint64_t tsf; 10389 uint16_t low_mactime_now; 10390 10391 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10392 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10393 10394 wh = mtod(m, const struct ieee80211_frame_min *); 10395 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10396 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10397 10398 bwn_tsf_read(mac, &tsf); 10399 low_mactime_now = tsf; 10400 tsf = tsf & ~0xffffULL; 10401 tsf += le16toh(rxhdr->mac_time); 10402 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10403 tsf -= 0x10000; 10404 10405 sc->sc_rx_th.wr_tsf = tsf; 10406 sc->sc_rx_th.wr_rate = rate; 10407 sc->sc_rx_th.wr_antsignal = rssi; 10408 sc->sc_rx_th.wr_antnoise = noise; 10409} 10410 10411static void 10412bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10413{ 10414 uint32_t low, high; 10415 10416 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10417 ("%s:%d: fail", __func__, __LINE__)); 10418 10419 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10420 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10421 *tsf = high; 10422 *tsf <<= 32; 10423 *tsf |= low; 10424} 10425 10426static int 10427bwn_dma_attach(struct bwn_mac *mac) 10428{ 10429 struct bwn_dma *dma = &mac->mac_method.dma; 10430 struct bwn_softc *sc = mac->mac_sc; 10431 struct siba_dev_softc *sd = mac->mac_sd; 10432 struct siba_softc *siba = sd->sd_bus; 10433 bus_addr_t lowaddr = 0; 10434 int error; 10435 10436 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10437 return (0); 10438 10439 KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__)); 10440 10441 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10442 10443 dma->dmatype = bwn_dma_gettype(mac); 10444 if (dma->dmatype == BWN_DMA_30BIT) 10445 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10446 else if (dma->dmatype == BWN_DMA_32BIT) 10447 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10448 else 10449 lowaddr = BUS_SPACE_MAXADDR; 10450 10451 /* 10452 * Create top level DMA tag 10453 */ 10454 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10455 BWN_ALIGN, 0, /* alignment, bounds */ 10456 lowaddr, /* lowaddr */ 10457 BUS_SPACE_MAXADDR, /* highaddr */ 10458 NULL, NULL, /* filter, filterarg */ 10459 MAXBSIZE, /* maxsize */ 10460 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10461 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10462 0, /* flags */ 10463 NULL, NULL, /* lockfunc, lockarg */ 10464 &dma->parent_dtag); 10465 if (error) { 10466 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10467 return (error); 10468 } 10469 10470 /* 10471 * Create TX/RX mbuf DMA tag 10472 */ 10473 error = bus_dma_tag_create(dma->parent_dtag, 10474 1, 10475 0, 10476 BUS_SPACE_MAXADDR, 10477 BUS_SPACE_MAXADDR, 10478 NULL, NULL, 10479 MCLBYTES, 10480 1, 10481 BUS_SPACE_MAXSIZE_32BIT, 10482 0, 10483 NULL, NULL, 10484 &dma->rxbuf_dtag); 10485 if (error) { 10486 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10487 goto fail0; 10488 } 10489 error = bus_dma_tag_create(dma->parent_dtag, 10490 1, 10491 0, 10492 BUS_SPACE_MAXADDR, 10493 BUS_SPACE_MAXADDR, 10494 NULL, NULL, 10495 MCLBYTES, 10496 1, 10497 BUS_SPACE_MAXSIZE_32BIT, 10498 0, 10499 NULL, NULL, 10500 &dma->txbuf_dtag); 10501 if (error) { 10502 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10503 goto fail1; 10504 } 10505 10506 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10507 if (!dma->wme[WME_AC_BK]) 10508 goto fail2; 10509 10510 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10511 if (!dma->wme[WME_AC_BE]) 10512 goto fail3; 10513 10514 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10515 if (!dma->wme[WME_AC_VI]) 10516 goto fail4; 10517 10518 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10519 if (!dma->wme[WME_AC_VO]) 10520 goto fail5; 10521 10522 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10523 if (!dma->mcast) 10524 goto fail6; 10525 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10526 if (!dma->rx) 10527 goto fail7; 10528 10529 return (error); 10530 10531fail7: bwn_dma_ringfree(&dma->mcast); 10532fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10533fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10534fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10535fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10536fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10537fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10538fail0: bus_dma_tag_destroy(dma->parent_dtag); 10539 return (error); 10540} 10541 10542static struct bwn_dma_ring * 10543bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10544 uint16_t cookie, int *slot) 10545{ 10546 struct bwn_dma *dma = &mac->mac_method.dma; 10547 struct bwn_dma_ring *dr; 10548 struct bwn_softc *sc = mac->mac_sc; 10549 10550 BWN_ASSERT_LOCKED(mac->mac_sc); 10551 10552 switch (cookie & 0xf000) { 10553 case 0x1000: 10554 dr = dma->wme[WME_AC_BK]; 10555 break; 10556 case 0x2000: 10557 dr = dma->wme[WME_AC_BE]; 10558 break; 10559 case 0x3000: 10560 dr = dma->wme[WME_AC_VI]; 10561 break; 10562 case 0x4000: 10563 dr = dma->wme[WME_AC_VO]; 10564 break; 10565 case 0x5000: 10566 dr = dma->mcast; 10567 break; 10568 default: 10569 dr = NULL; 10570 KASSERT(0 == 1, 10571 ("invalid cookie value %d", cookie & 0xf000)); 10572 } 10573 *slot = (cookie & 0x0fff); 10574 if (*slot < 0 || *slot >= dr->dr_numslots) { 10575 /* 10576 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10577 * that it occurs events which have same H/W sequence numbers. 10578 * When it's occurred just prints a WARNING msgs and ignores. 10579 */ 10580 KASSERT(status->seq == dma->lastseq, 10581 ("%s:%d: fail", __func__, __LINE__)); 10582 device_printf(sc->sc_dev, 10583 "out of slot ranges (0 < %d < %d)\n", *slot, 10584 dr->dr_numslots); 10585 return (NULL); 10586 } 10587 dma->lastseq = status->seq; 10588 return (dr); 10589} 10590 10591static void 10592bwn_dma_stop(struct bwn_mac *mac) 10593{ 10594 struct bwn_dma *dma; 10595 10596 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10597 return; 10598 dma = &mac->mac_method.dma; 10599 10600 bwn_dma_ringstop(&dma->rx); 10601 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10602 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10603 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10604 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10605 bwn_dma_ringstop(&dma->mcast); 10606} 10607 10608static void 10609bwn_dma_ringstop(struct bwn_dma_ring **dr) 10610{ 10611 10612 if (dr == NULL) 10613 return; 10614 10615 bwn_dma_cleanup(*dr); 10616} 10617 10618static void 10619bwn_pio_stop(struct bwn_mac *mac) 10620{ 10621 struct bwn_pio *pio; 10622 10623 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10624 return; 10625 pio = &mac->mac_method.pio; 10626 10627 bwn_destroy_queue_tx(&pio->mcast); 10628 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10629 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10630 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10631 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10632} 10633 10634static void 10635bwn_led_attach(struct bwn_mac *mac) 10636{ 10637 struct bwn_softc *sc = mac->mac_sc; 10638 struct siba_softc *siba = mac->mac_sd->sd_bus; 10639 const uint8_t *led_act = NULL; 10640 uint16_t val[BWN_LED_MAX]; 10641 int i; 10642 10643 sc->sc_led_idle = (2350 * hz) / 1000; 10644 sc->sc_led_blink = 1; 10645 10646 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10647 if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) { 10648 led_act = bwn_vendor_led_act[i].led_act; 10649 break; 10650 } 10651 } 10652 if (led_act == NULL) 10653 led_act = bwn_default_led_act; 10654 10655 val[0] = siba->siba_sprom.gpio0; 10656 val[1] = siba->siba_sprom.gpio1; 10657 val[2] = siba->siba_sprom.gpio2; 10658 val[3] = siba->siba_sprom.gpio3; 10659 10660 for (i = 0; i < BWN_LED_MAX; ++i) { 10661 struct bwn_led *led = &sc->sc_leds[i]; 10662 10663 if (val[i] == 0xff) { 10664 led->led_act = led_act[i]; 10665 } else { 10666 if (val[i] & BWN_LED_ACT_LOW) 10667 led->led_flags |= BWN_LED_F_ACTLOW; 10668 led->led_act = val[i] & BWN_LED_ACT_MASK; 10669 } 10670 led->led_mask = (1 << i); 10671 10672 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10673 led->led_act == BWN_LED_ACT_BLINK_POLL || 10674 led->led_act == BWN_LED_ACT_BLINK) { 10675 led->led_flags |= BWN_LED_F_BLINK; 10676 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10677 led->led_flags |= BWN_LED_F_POLLABLE; 10678 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10679 led->led_flags |= BWN_LED_F_SLOW; 10680 10681 if (sc->sc_blink_led == NULL) { 10682 sc->sc_blink_led = led; 10683 if (led->led_flags & BWN_LED_F_SLOW) 10684 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10685 } 10686 } 10687 10688 DPRINTF(sc, BWN_DEBUG_LED, 10689 "%dth led, act %d, lowact %d\n", i, 10690 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10691 } 10692 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10693} 10694 10695static __inline uint16_t 10696bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10697{ 10698 10699 if (led->led_flags & BWN_LED_F_ACTLOW) 10700 on = !on; 10701 if (on) 10702 val |= led->led_mask; 10703 else 10704 val &= ~led->led_mask; 10705 return val; 10706} 10707 10708static void 10709bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10710{ 10711 struct bwn_softc *sc = mac->mac_sc; 10712 struct ifnet *ifp = sc->sc_ifp; 10713 struct ieee80211com *ic = ifp->if_l2com; 10714 uint16_t val; 10715 int i; 10716 10717 if (nstate == IEEE80211_S_INIT) { 10718 callout_stop(&sc->sc_led_blink_ch); 10719 sc->sc_led_blinking = 0; 10720 } 10721 10722 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10723 return; 10724 10725 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10726 for (i = 0; i < BWN_LED_MAX; ++i) { 10727 struct bwn_led *led = &sc->sc_leds[i]; 10728 int on; 10729 10730 if (led->led_act == BWN_LED_ACT_UNKN || 10731 led->led_act == BWN_LED_ACT_NULL) 10732 continue; 10733 10734 if ((led->led_flags & BWN_LED_F_BLINK) && 10735 nstate != IEEE80211_S_INIT) 10736 continue; 10737 10738 switch (led->led_act) { 10739 case BWN_LED_ACT_ON: /* Always on */ 10740 on = 1; 10741 break; 10742 case BWN_LED_ACT_OFF: /* Always off */ 10743 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10744 on = 0; 10745 break; 10746 default: 10747 on = 1; 10748 switch (nstate) { 10749 case IEEE80211_S_INIT: 10750 on = 0; 10751 break; 10752 case IEEE80211_S_RUN: 10753 if (led->led_act == BWN_LED_ACT_11G && 10754 ic->ic_curmode != IEEE80211_MODE_11G) 10755 on = 0; 10756 break; 10757 default: 10758 if (led->led_act == BWN_LED_ACT_ASSOC) 10759 on = 0; 10760 break; 10761 } 10762 break; 10763 } 10764 10765 val = bwn_led_onoff(led, val, on); 10766 } 10767 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10768} 10769 10770static void 10771bwn_led_event(struct bwn_mac *mac, int event) 10772{ 10773 struct bwn_softc *sc = mac->mac_sc; 10774 struct bwn_led *led = sc->sc_blink_led; 10775 int rate; 10776 10777 if (event == BWN_LED_EVENT_POLL) { 10778 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10779 return; 10780 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10781 return; 10782 } 10783 10784 sc->sc_led_ticks = ticks; 10785 if (sc->sc_led_blinking) 10786 return; 10787 10788 switch (event) { 10789 case BWN_LED_EVENT_RX: 10790 rate = sc->sc_rx_rate; 10791 break; 10792 case BWN_LED_EVENT_TX: 10793 rate = sc->sc_tx_rate; 10794 break; 10795 case BWN_LED_EVENT_POLL: 10796 rate = 0; 10797 break; 10798 default: 10799 panic("unknown LED event %d\n", event); 10800 break; 10801 } 10802 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10803 bwn_led_duration[rate].off_dur); 10804} 10805 10806static void 10807bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10808{ 10809 struct bwn_softc *sc = mac->mac_sc; 10810 struct bwn_led *led = sc->sc_blink_led; 10811 uint16_t val; 10812 10813 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10814 val = bwn_led_onoff(led, val, 1); 10815 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10816 10817 if (led->led_flags & BWN_LED_F_SLOW) { 10818 BWN_LED_SLOWDOWN(on_dur); 10819 BWN_LED_SLOWDOWN(off_dur); 10820 } 10821 10822 sc->sc_led_blinking = 1; 10823 sc->sc_led_blink_offdur = off_dur; 10824 10825 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10826} 10827 10828static void 10829bwn_led_blink_next(void *arg) 10830{ 10831 struct bwn_mac *mac = arg; 10832 struct bwn_softc *sc = mac->mac_sc; 10833 uint16_t val; 10834 10835 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10836 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10837 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10838 10839 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10840 bwn_led_blink_end, mac); 10841} 10842 10843static void 10844bwn_led_blink_end(void *arg) 10845{ 10846 struct bwn_mac *mac = arg; 10847 struct bwn_softc *sc = mac->mac_sc; 10848 10849 sc->sc_led_blinking = 0; 10850} 10851 10852static int 10853bwn_suspend(device_t dev) 10854{ 10855 struct bwn_softc *sc = device_get_softc(dev); 10856 10857 bwn_stop(sc, 1); 10858 return (0); 10859} 10860 10861static int 10862bwn_resume(device_t dev) 10863{ 10864 struct bwn_softc *sc = device_get_softc(dev); 10865 struct ifnet *ifp = sc->sc_ifp; 10866 10867 if (ifp->if_flags & IFF_UP) 10868 bwn_init(sc); 10869 return (0); 10870} 10871 10872static void 10873bwn_rfswitch(void *arg) 10874{ 10875 struct bwn_softc *sc = arg; 10876 struct bwn_mac *mac = sc->sc_curmac; 10877 int cur = 0, prev = 0; 10878 10879 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10880 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10881 10882 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10883 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10884 & BWN_RF_HWENABLED_HI_MASK)) 10885 cur = 1; 10886 } else { 10887 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10888 & BWN_RF_HWENABLED_LO_MASK) 10889 cur = 1; 10890 } 10891 10892 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10893 prev = 1; 10894 10895 if (cur != prev) { 10896 if (cur) 10897 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10898 else 10899 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10900 10901 device_printf(sc->sc_dev, 10902 "status of RF switch is changed to %s\n", 10903 cur ? "ON" : "OFF"); 10904 if (cur != mac->mac_phy.rf_on) { 10905 if (cur) 10906 bwn_rf_turnon(mac); 10907 else 10908 bwn_rf_turnoff(mac); 10909 } 10910 } 10911 10912 callout_schedule(&sc->sc_rfswitch_ch, hz); 10913} 10914 10915static void 10916bwn_phy_lp_init_pre(struct bwn_mac *mac) 10917{ 10918 struct bwn_phy *phy = &mac->mac_phy; 10919 struct bwn_phy_lp *plp = &phy->phy_lp; 10920 10921 plp->plp_antenna = BWN_ANT_DEFAULT; 10922} 10923 10924static int 10925bwn_phy_lp_init(struct bwn_mac *mac) 10926{ 10927 static const struct bwn_stxtable tables[] = { 10928 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10929 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10930 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10931 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10932 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10933 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10934 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10935 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10936 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10937 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10938 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10939 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10940 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10941 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10942 { 2, 11, 0x40, 0, 0x0f } 10943 }; 10944 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10945 struct bwn_softc *sc = mac->mac_sc; 10946 const struct bwn_stxtable *st; 10947 struct ifnet *ifp = sc->sc_ifp; 10948 struct ieee80211com *ic = ifp->if_l2com; 10949 int i, error; 10950 uint16_t tmp; 10951 10952 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10953 bwn_phy_lp_bbinit(mac); 10954 10955 /* initialize RF */ 10956 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10957 DELAY(1); 10958 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10959 DELAY(1); 10960 10961 if (mac->mac_phy.rf_ver == 0x2062) 10962 bwn_phy_lp_b2062_init(mac); 10963 else { 10964 bwn_phy_lp_b2063_init(mac); 10965 10966 /* synchronize stx table. */ 10967 for (i = 0; i < N(tables); i++) { 10968 st = &tables[i]; 10969 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10970 tmp >>= st->st_rfshift; 10971 tmp <<= st->st_physhift; 10972 BWN_PHY_SETMASK(mac, 10973 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10974 ~(st->st_mask << st->st_physhift), tmp); 10975 } 10976 10977 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10978 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10979 } 10980 10981 /* calibrate RC */ 10982 if (mac->mac_phy.rev >= 2) 10983 bwn_phy_lp_rxcal_r2(mac); 10984 else if (!plp->plp_rccap) { 10985 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10986 bwn_phy_lp_rccal_r12(mac); 10987 } else 10988 bwn_phy_lp_set_rccap(mac); 10989 10990 error = bwn_phy_lp_switch_channel(mac, 7); 10991 if (error) 10992 device_printf(sc->sc_dev, 10993 "failed to change channel 7 (%d)\n", error); 10994 bwn_phy_lp_txpctl_init(mac); 10995 bwn_phy_lp_calib(mac); 10996 return (0); 10997} 10998 10999static uint16_t 11000bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 11001{ 11002 11003 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11004 return (BWN_READ_2(mac, BWN_PHYDATA)); 11005} 11006 11007static void 11008bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11009{ 11010 11011 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11012 BWN_WRITE_2(mac, BWN_PHYDATA, value); 11013} 11014 11015static void 11016bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 11017 uint16_t set) 11018{ 11019 11020 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11021 BWN_WRITE_2(mac, BWN_PHYDATA, 11022 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 11023} 11024 11025static uint16_t 11026bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 11027{ 11028 11029 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11030 if (mac->mac_phy.rev < 2 && reg != 0x4001) 11031 reg |= 0x100; 11032 if (mac->mac_phy.rev >= 2) 11033 reg |= 0x200; 11034 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11035 return BWN_READ_2(mac, BWN_RFDATALO); 11036} 11037 11038static void 11039bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11040{ 11041 11042 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11043 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11044 BWN_WRITE_2(mac, BWN_RFDATALO, value); 11045} 11046 11047static void 11048bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 11049{ 11050 11051 if (on) { 11052 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 11053 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 11054 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 11055 return; 11056 } 11057 11058 if (mac->mac_phy.rev >= 2) { 11059 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 11060 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11061 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 11062 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 11063 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 11064 return; 11065 } 11066 11067 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 11068 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11069 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 11070 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 11071} 11072 11073static int 11074bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11075{ 11076 struct bwn_phy *phy = &mac->mac_phy; 11077 struct bwn_phy_lp *plp = &phy->phy_lp; 11078 int error; 11079 11080 if (phy->rf_ver == 0x2063) { 11081 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11082 if (error) 11083 return (error); 11084 } else { 11085 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11086 if (error) 11087 return (error); 11088 bwn_phy_lp_set_anafilter(mac, chan); 11089 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11090 } 11091 11092 plp->plp_chan = chan; 11093 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11094 return (0); 11095} 11096 11097static uint32_t 11098bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11099{ 11100 struct bwn_softc *sc = mac->mac_sc; 11101 struct ifnet *ifp = sc->sc_ifp; 11102 struct ieee80211com *ic = ifp->if_l2com; 11103 11104 device_printf(sc->sc_dev, "correct?\n"); 11105 11106 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11107} 11108 11109static void 11110bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11111{ 11112 struct bwn_phy *phy = &mac->mac_phy; 11113 struct bwn_phy_lp *plp = &phy->phy_lp; 11114 11115 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11116 return; 11117 11118 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11119 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11120 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11121 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11122 plp->plp_antenna = antenna; 11123} 11124 11125static void 11126bwn_phy_lp_task_60s(struct bwn_mac *mac) 11127{ 11128 11129 bwn_phy_lp_calib(mac); 11130} 11131 11132static void 11133bwn_phy_lp_readsprom(struct bwn_mac *mac) 11134{ 11135 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11136 struct bwn_softc *sc = mac->mac_sc; 11137 struct ifnet *ifp = sc->sc_ifp; 11138 struct ieee80211com *ic = ifp->if_l2com; 11139 struct siba_dev_softc *sd = mac->mac_sd; 11140 struct siba_softc *siba = sd->sd_bus; 11141 struct siba_sprom *sprom = &siba->siba_sprom; 11142 11143 device_printf(sc->sc_dev, "XXX using %dghz\n", 11144 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5); 11145 11146 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11147 plp->plp_txisoband_m = sprom->tri2g; 11148 plp->plp_bxarch = sprom->bxa2g; 11149 plp->plp_rxpwroffset = sprom->rxpo2g; 11150 plp->plp_rssivf = sprom->rssismf2g; 11151 plp->plp_rssivc = sprom->rssismc2g; 11152 plp->plp_rssigs = sprom->rssisav2g; 11153 return; 11154 } 11155 11156 plp->plp_txisoband_l = sprom->tri5gl; 11157 plp->plp_txisoband_m = sprom->tri5g; 11158 plp->plp_txisoband_h = sprom->tri5gh; 11159 plp->plp_bxarch = sprom->bxa5g; 11160 plp->plp_rxpwroffset = sprom->rxpo5g; 11161 plp->plp_rssivf = sprom->rssismf5g; 11162 plp->plp_rssivc = sprom->rssismc5g; 11163 plp->plp_rssigs = sprom->rssisav5g; 11164} 11165 11166static void 11167bwn_phy_lp_bbinit(struct bwn_mac *mac) 11168{ 11169 11170 bwn_phy_lp_tblinit(mac); 11171 if (mac->mac_phy.rev >= 2) 11172 bwn_phy_lp_bbinit_r2(mac); 11173 else 11174 bwn_phy_lp_bbinit_r01(mac); 11175} 11176 11177static void 11178bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11179{ 11180 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11181 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11182 struct bwn_softc *sc = mac->mac_sc; 11183 struct ifnet *ifp = sc->sc_ifp; 11184 struct ieee80211com *ic = ifp->if_l2com; 11185 11186 bwn_phy_lp_set_txgain(mac, 11187 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11188 bwn_phy_lp_set_bbmult(mac, 150); 11189} 11190 11191static void 11192bwn_phy_lp_calib(struct bwn_mac *mac) 11193{ 11194 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11195 struct siba_dev_softc *sd = mac->mac_sd; 11196 struct siba_softc *siba = sd->sd_bus; 11197 struct bwn_softc *sc = mac->mac_sc; 11198 struct ifnet *ifp = sc->sc_ifp; 11199 struct ieee80211com *ic = ifp->if_l2com; 11200 const struct bwn_rxcompco *rc = NULL; 11201 struct bwn_txgain ogain; 11202 int i, omode, oafeovr, orf, obbmult; 11203 uint8_t mode, fc = 0; 11204 11205 if (plp->plp_chanfullcal != plp->plp_chan) { 11206 plp->plp_chanfullcal = plp->plp_chan; 11207 fc = 1; 11208 } 11209 11210 bwn_mac_suspend(mac); 11211 11212 /* BlueTooth Coexistance Override */ 11213 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11214 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11215 11216 if (mac->mac_phy.rev >= 2) 11217 bwn_phy_lp_digflt_save(mac); 11218 bwn_phy_lp_get_txpctlmode(mac); 11219 mode = plp->plp_txpctlmode; 11220 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11221 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11222 bwn_phy_lp_bugfix(mac); 11223 if (mac->mac_phy.rev >= 2 && fc == 1) { 11224 bwn_phy_lp_get_txpctlmode(mac); 11225 omode = plp->plp_txpctlmode; 11226 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11227 if (oafeovr) 11228 ogain = bwn_phy_lp_get_txgain(mac); 11229 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11230 obbmult = bwn_phy_lp_get_bbmult(mac); 11231 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11232 if (oafeovr) 11233 bwn_phy_lp_set_txgain(mac, &ogain); 11234 bwn_phy_lp_set_bbmult(mac, obbmult); 11235 bwn_phy_lp_set_txpctlmode(mac, omode); 11236 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11237 } 11238 bwn_phy_lp_set_txpctlmode(mac, mode); 11239 if (mac->mac_phy.rev >= 2) 11240 bwn_phy_lp_digflt_restore(mac); 11241 11242 /* do RX IQ Calculation; assumes that noise is true. */ 11243 if (siba->siba_chipid == 0x5354) { 11244 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11245 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11246 rc = &bwn_rxcompco_5354[i]; 11247 } 11248 } else if (mac->mac_phy.rev >= 2) 11249 rc = &bwn_rxcompco_r2; 11250 else { 11251 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11252 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11253 rc = &bwn_rxcompco_r12[i]; 11254 } 11255 } 11256 if (rc == NULL) 11257 goto fail; 11258 11259 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11260 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11261 11262 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11263 11264 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11265 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11266 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11267 } else { 11268 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11269 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11270 } 11271 11272 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11273 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11274 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11275 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11276 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11277 bwn_phy_lp_set_deaf(mac, 0); 11278 /* XXX no checking return value? */ 11279 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11280 bwn_phy_lp_clear_deaf(mac, 0); 11281 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11282 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11283 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11284 11285 /* disable RX GAIN override. */ 11286 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11287 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11288 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11289 if (mac->mac_phy.rev >= 2) { 11290 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11291 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11293 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11294 } 11295 } else { 11296 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11297 } 11298 11299 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11300 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11301fail: 11302 bwn_mac_enable(mac); 11303} 11304 11305static void 11306bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11307{ 11308 11309 if (on) { 11310 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11311 return; 11312 } 11313 11314 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11315 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11316} 11317 11318static int 11319bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11320{ 11321 struct siba_dev_softc *sd = mac->mac_sd; 11322 struct siba_softc *siba = sd->sd_bus; 11323 static const struct bwn_b206x_chan *bc = NULL; 11324 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11325 tmp[6]; 11326 uint16_t old, scale, tmp16; 11327 int i, div; 11328 11329 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11330 if (bwn_b2063_chantable[i].bc_chan == chan) { 11331 bc = &bwn_b2063_chantable[i]; 11332 break; 11333 } 11334 } 11335 if (bc == NULL) 11336 return (EINVAL); 11337 11338 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11339 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11340 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11341 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11342 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11343 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11344 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11345 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11346 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11347 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11348 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11349 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11350 11351 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11352 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11353 11354 freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11355 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11356 freqref = freqxtal * 3; 11357 div = (freqxtal <= 26000000 ? 1 : 2); 11358 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11359 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11360 999999) / 1000000) + 1; 11361 11362 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11363 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11364 0xfff8, timeout >> 2); 11365 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11366 0xff9f,timeout << 5); 11367 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11368 11369 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11370 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11371 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11372 11373 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11374 (timeoutref + 1)) - 1; 11375 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11376 0xf0, count >> 8); 11377 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11378 11379 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11380 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11381 while (tmp[1] >= freqref) { 11382 tmp[0]++; 11383 tmp[1] -= freqref; 11384 } 11385 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11386 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11387 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11388 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11389 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11390 11391 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11392 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11393 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11394 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11395 11396 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11397 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11398 11399 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11400 scale = 1; 11401 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11402 } else { 11403 scale = 0; 11404 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11405 } 11406 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11407 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11408 11409 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11410 (scale + 1); 11411 if (tmp[5] > 150) 11412 tmp[5] = 0; 11413 11414 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11415 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11416 11417 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11418 if (freqxtal > 26000000) 11419 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11420 else 11421 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11422 11423 if (val[0] == 45) 11424 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11425 else 11426 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11427 11428 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11429 DELAY(1); 11430 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11431 11432 /* VCO Calibration */ 11433 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11434 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11435 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11436 DELAY(1); 11437 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11438 DELAY(1); 11439 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11440 DELAY(1); 11441 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11442 DELAY(300); 11443 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11444 11445 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11446 return (0); 11447} 11448 11449static int 11450bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11451{ 11452 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11453 struct siba_dev_softc *sd = mac->mac_sd; 11454 struct siba_softc *siba = sd->sd_bus; 11455 const struct bwn_b206x_chan *bc = NULL; 11456 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11457 uint32_t tmp[9]; 11458 int i; 11459 11460 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11461 if (bwn_b2062_chantable[i].bc_chan == chan) { 11462 bc = &bwn_b2062_chantable[i]; 11463 break; 11464 } 11465 } 11466 11467 if (bc == NULL) 11468 return (EINVAL); 11469 11470 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11471 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11472 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11473 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11474 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11475 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11476 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11477 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11478 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11479 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11480 11481 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11482 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11483 bwn_phy_lp_b2062_reset_pllbias(mac); 11484 tmp[0] = freqxtal / 1000; 11485 tmp[1] = plp->plp_div * 1000; 11486 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11487 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11488 tmp[2] *= 2; 11489 tmp[3] = 48 * tmp[0]; 11490 tmp[5] = tmp[2] / tmp[3]; 11491 tmp[6] = tmp[2] % tmp[3]; 11492 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11493 tmp[4] = tmp[6] * 0x100; 11494 tmp[5] = tmp[4] / tmp[3]; 11495 tmp[6] = tmp[4] % tmp[3]; 11496 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11497 tmp[4] = tmp[6] * 0x100; 11498 tmp[5] = tmp[4] / tmp[3]; 11499 tmp[6] = tmp[4] % tmp[3]; 11500 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11501 tmp[4] = tmp[6] * 0x100; 11502 tmp[5] = tmp[4] / tmp[3]; 11503 tmp[6] = tmp[4] % tmp[3]; 11504 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11505 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11506 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11507 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11508 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11509 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11510 11511 bwn_phy_lp_b2062_vco_calib(mac); 11512 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11513 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11514 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11515 bwn_phy_lp_b2062_reset_pllbias(mac); 11516 bwn_phy_lp_b2062_vco_calib(mac); 11517 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11518 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11519 return (EIO); 11520 } 11521 } 11522 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11523 return (0); 11524} 11525 11526static void 11527bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11528{ 11529 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11530 uint16_t tmp = (channel == 14); 11531 11532 if (mac->mac_phy.rev < 2) { 11533 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11534 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11535 bwn_phy_lp_set_rccap(mac); 11536 return; 11537 } 11538 11539 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11540} 11541 11542static void 11543bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11544{ 11545 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11546 struct bwn_softc *sc = mac->mac_sc; 11547 struct ifnet *ifp = sc->sc_ifp; 11548 struct ieee80211com *ic = ifp->if_l2com; 11549 uint16_t iso, tmp[3]; 11550 11551 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11552 11553 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11554 iso = plp->plp_txisoband_m; 11555 else if (freq <= 5320) 11556 iso = plp->plp_txisoband_l; 11557 else if (freq <= 5700) 11558 iso = plp->plp_txisoband_m; 11559 else 11560 iso = plp->plp_txisoband_h; 11561 11562 tmp[0] = ((iso - 26) / 12) << 12; 11563 tmp[1] = tmp[0] + 0x1000; 11564 tmp[2] = tmp[0] + 0x2000; 11565 11566 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11567 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11568} 11569 11570static void 11571bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11572{ 11573 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11574 int i; 11575 static const uint16_t addr[] = { 11576 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11577 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11578 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11579 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11580 BWN_PHY_OFDM(0xcf), 11581 }; 11582 static const uint16_t val[] = { 11583 0xde5e, 0xe832, 0xe331, 0x4d26, 11584 0x0026, 0x1420, 0x0020, 0xfe08, 11585 0x0008, 11586 }; 11587 11588 for (i = 0; i < N(addr); i++) { 11589 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11590 BWN_PHY_WRITE(mac, addr[i], val[i]); 11591 } 11592} 11593 11594static void 11595bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11596{ 11597 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11598 struct bwn_softc *sc = mac->mac_sc; 11599 uint16_t ctl; 11600 11601 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11602 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11603 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11604 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11605 break; 11606 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11607 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11608 break; 11609 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11610 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11611 break; 11612 default: 11613 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11614 device_printf(sc->sc_dev, "unknown command mode\n"); 11615 break; 11616 } 11617} 11618 11619static void 11620bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11621{ 11622 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11623 uint16_t ctl; 11624 uint8_t old; 11625 11626 bwn_phy_lp_get_txpctlmode(mac); 11627 old = plp->plp_txpctlmode; 11628 if (old == mode) 11629 return; 11630 plp->plp_txpctlmode = mode; 11631 11632 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11633 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11634 plp->plp_tssiidx); 11635 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11636 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11637 11638 /* disable TX GAIN override */ 11639 if (mac->mac_phy.rev < 2) 11640 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11641 else { 11642 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11643 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11644 } 11645 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11646 11647 plp->plp_txpwridx = -1; 11648 } 11649 if (mac->mac_phy.rev >= 2) { 11650 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11651 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11652 else 11653 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11654 } 11655 11656 /* writes TX Power Control mode */ 11657 switch (plp->plp_txpctlmode) { 11658 case BWN_PHYLP_TXPCTL_OFF: 11659 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11660 break; 11661 case BWN_PHYLP_TXPCTL_ON_HW: 11662 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11663 break; 11664 case BWN_PHYLP_TXPCTL_ON_SW: 11665 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11666 break; 11667 default: 11668 ctl = 0; 11669 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11670 } 11671 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11672 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11673} 11674 11675static void 11676bwn_phy_lp_bugfix(struct bwn_mac *mac) 11677{ 11678 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11679 struct bwn_softc *sc = mac->mac_sc; 11680 const unsigned int size = 256; 11681 struct bwn_txgain tg; 11682 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11683 uint16_t tssinpt, tssiidx, value[2]; 11684 uint8_t mode; 11685 int8_t txpwridx; 11686 11687 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11688 M_NOWAIT | M_ZERO); 11689 if (tabs == NULL) { 11690 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11691 return; 11692 } 11693 11694 bwn_phy_lp_get_txpctlmode(mac); 11695 mode = plp->plp_txpctlmode; 11696 txpwridx = plp->plp_txpwridx; 11697 tssinpt = plp->plp_tssinpt; 11698 tssiidx = plp->plp_tssiidx; 11699 11700 bwn_tab_read_multi(mac, 11701 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11702 BWN_TAB_4(7, 0x140), size, tabs); 11703 11704 bwn_phy_lp_tblinit(mac); 11705 bwn_phy_lp_bbinit(mac); 11706 bwn_phy_lp_txpctl_init(mac); 11707 bwn_phy_lp_rf_onoff(mac, 1); 11708 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11709 11710 bwn_tab_write_multi(mac, 11711 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11712 BWN_TAB_4(7, 0x140), size, tabs); 11713 11714 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11715 plp->plp_tssinpt = tssinpt; 11716 plp->plp_tssiidx = tssiidx; 11717 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11718 if (txpwridx != -1) { 11719 /* set TX power by index */ 11720 plp->plp_txpwridx = txpwridx; 11721 bwn_phy_lp_get_txpctlmode(mac); 11722 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11723 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11724 if (mac->mac_phy.rev >= 2) { 11725 rxcomp = bwn_tab_read(mac, 11726 BWN_TAB_4(7, txpwridx + 320)); 11727 txgain = bwn_tab_read(mac, 11728 BWN_TAB_4(7, txpwridx + 192)); 11729 tg.tg_pad = (txgain >> 16) & 0xff; 11730 tg.tg_gm = txgain & 0xff; 11731 tg.tg_pga = (txgain >> 8) & 0xff; 11732 tg.tg_dac = (rxcomp >> 28) & 0xff; 11733 bwn_phy_lp_set_txgain(mac, &tg); 11734 } else { 11735 rxcomp = bwn_tab_read(mac, 11736 BWN_TAB_4(10, txpwridx + 320)); 11737 txgain = bwn_tab_read(mac, 11738 BWN_TAB_4(10, txpwridx + 192)); 11739 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11740 0xf800, (txgain >> 4) & 0x7fff); 11741 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11742 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11743 } 11744 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11745 11746 /* set TX IQCC */ 11747 value[0] = (rxcomp >> 10) & 0x3ff; 11748 value[1] = rxcomp & 0x3ff; 11749 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11750 11751 coeff = bwn_tab_read(mac, 11752 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11753 BWN_TAB_4(10, txpwridx + 448)); 11754 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11755 if (mac->mac_phy.rev >= 2) { 11756 rfpwr = bwn_tab_read(mac, 11757 BWN_TAB_4(7, txpwridx + 576)); 11758 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11759 rfpwr & 0xffff); 11760 } 11761 bwn_phy_lp_set_txgain_override(mac); 11762 } 11763 if (plp->plp_rccap) 11764 bwn_phy_lp_set_rccap(mac); 11765 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11766 bwn_phy_lp_set_txpctlmode(mac, mode); 11767 free(tabs, M_DEVBUF); 11768} 11769 11770static void 11771bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11772{ 11773 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11774 int i; 11775 static const uint16_t addr[] = { 11776 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11777 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11778 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11779 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11780 BWN_PHY_OFDM(0xcf), 11781 }; 11782 11783 for (i = 0; i < N(addr); i++) 11784 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11785} 11786 11787static void 11788bwn_phy_lp_tblinit(struct bwn_mac *mac) 11789{ 11790 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11791 11792 if (mac->mac_phy.rev < 2) { 11793 bwn_phy_lp_tblinit_r01(mac); 11794 bwn_phy_lp_tblinit_txgain(mac); 11795 bwn_phy_lp_set_gaintbl(mac, freq); 11796 return; 11797 } 11798 11799 bwn_phy_lp_tblinit_r2(mac); 11800 bwn_phy_lp_tblinit_txgain(mac); 11801} 11802 11803struct bwn_wpair { 11804 uint16_t reg; 11805 uint16_t value; 11806}; 11807 11808struct bwn_smpair { 11809 uint16_t offset; 11810 uint16_t mask; 11811 uint16_t set; 11812}; 11813 11814static void 11815bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11816{ 11817 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11818 struct siba_dev_softc *sd = mac->mac_sd; 11819 struct siba_softc *siba = sd->sd_bus; 11820 struct bwn_softc *sc = mac->mac_sc; 11821 struct ifnet *ifp = sc->sc_ifp; 11822 struct ieee80211com *ic = ifp->if_l2com; 11823 static const struct bwn_wpair v1[] = { 11824 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11825 { BWN_PHY_AFE_CTL, 0x8800 }, 11826 { BWN_PHY_AFE_CTL_OVR, 0 }, 11827 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11828 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11829 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11830 { BWN_PHY_OFDM(0xf9), 0 }, 11831 { BWN_PHY_TR_LOOKUP_1, 0 } 11832 }; 11833 static const struct bwn_smpair v2[] = { 11834 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11835 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11836 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11837 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11838 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11839 }; 11840 static const struct bwn_smpair v3[] = { 11841 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11842 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11843 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11844 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11845 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11846 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11847 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11848 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11849 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11850 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11851 11852 }; 11853 int i; 11854 11855 for (i = 0; i < N(v1); i++) 11856 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11857 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11858 for (i = 0; i < N(v2); i++) 11859 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11860 11861 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11862 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11863 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11864 if (siba->siba_board_rev >= 0x18) { 11865 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11866 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11867 } else { 11868 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11869 } 11870 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11871 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11872 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11873 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11874 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11875 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11876 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11877 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11878 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11879 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11880 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11881 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11882 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11883 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11884 } else { 11885 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11886 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11887 } 11888 for (i = 0; i < N(v3); i++) 11889 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11890 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11891 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11892 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11893 } 11894 11895 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11896 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11897 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11898 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11899 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11900 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11901 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11902 } else 11903 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11904 11905 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11906 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11907 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11908 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11909 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11910 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11911 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11912 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11913 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11914 11915 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11916 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11918 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11919 } 11920 11921 bwn_phy_lp_digflt_save(mac); 11922} 11923 11924static void 11925bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11926{ 11927 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11928 struct siba_dev_softc *sd = mac->mac_sd; 11929 struct siba_softc *siba = sd->sd_bus; 11930 struct bwn_softc *sc = mac->mac_sc; 11931 struct ifnet *ifp = sc->sc_ifp; 11932 struct ieee80211com *ic = ifp->if_l2com; 11933 static const struct bwn_smpair v1[] = { 11934 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11935 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11936 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11937 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11938 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11939 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11940 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11941 }; 11942 static const struct bwn_smpair v2[] = { 11943 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11944 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11945 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11946 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11947 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11948 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11949 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11950 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11951 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11952 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11953 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11954 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11955 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11956 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11957 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11958 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11959 }; 11960 static const struct bwn_smpair v3[] = { 11961 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11962 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11963 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11964 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11965 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11966 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11967 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11968 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11969 }; 11970 static const struct bwn_smpair v4[] = { 11971 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11972 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11973 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11974 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11975 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11976 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11977 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11978 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11979 }; 11980 static const struct bwn_smpair v5[] = { 11981 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11982 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11983 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11984 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11985 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11986 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11987 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11988 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11989 }; 11990 int i; 11991 uint16_t tmp, tmp2; 11992 11993 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11994 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11995 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11996 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11997 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11998 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11999 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 12000 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 12001 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 12002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 12003 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 12004 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 12005 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 12006 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 12007 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 12008 for (i = 0; i < N(v1); i++) 12009 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 12010 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 12011 0xff00, plp->plp_rxpwroffset); 12012 if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) && 12013 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 12014 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) { 12015 siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28); 12016 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1); 12017 if (mac->mac_phy.rev == 0) 12018 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 12019 0xffcf, 0x0010); 12020 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 12021 } else { 12022 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0); 12023 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 12024 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 12025 } 12026 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 12027 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 12028 if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV) 12029 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 12030 else 12031 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 12032 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 12033 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 12034 0xfff9, (plp->plp_bxarch << 1)); 12035 if (mac->mac_phy.rev == 1 && 12036 (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) { 12037 for (i = 0; i < N(v2); i++) 12038 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 12039 v2[i].set); 12040 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 12041 (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) && 12042 (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) { 12043 for (i = 0; i < N(v3); i++) 12044 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 12045 v3[i].set); 12046 } else if (mac->mac_phy.rev == 1 || 12047 (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) { 12048 for (i = 0; i < N(v4); i++) 12049 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 12050 v4[i].set); 12051 } else { 12052 for (i = 0; i < N(v5); i++) 12053 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 12054 v5[i].set); 12055 } 12056 if (mac->mac_phy.rev == 1 && 12057 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) { 12058 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 12059 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 12060 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 12061 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 12062 } 12063 if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) && 12064 (siba->siba_chipid == 0x5354) && 12065 (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) { 12066 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 12067 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 12068 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 12069 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 12070 } 12071 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12072 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 12073 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 12074 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 12075 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 12076 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 12077 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 12078 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 12079 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 12080 } else { 12081 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 12082 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 12083 } 12084 if (mac->mac_phy.rev == 1) { 12085 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12086 tmp2 = (tmp & 0x03e0) >> 5; 12087 tmp2 |= tmp2 << 5; 12088 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12089 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12090 tmp2 = (tmp & 0x1f00) >> 8; 12091 tmp2 |= tmp2 << 5; 12092 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12093 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12094 tmp2 = tmp & 0x00ff; 12095 tmp2 |= tmp << 8; 12096 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12097 } 12098} 12099 12100struct bwn_b2062_freq { 12101 uint16_t freq; 12102 uint8_t value[6]; 12103}; 12104 12105static void 12106bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12107{ 12108#define CALC_CTL7(freq, div) \ 12109 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12110#define CALC_CTL18(freq, div) \ 12111 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12112#define CALC_CTL19(freq, div) \ 12113 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12114 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12115 struct siba_dev_softc *sd = mac->mac_sd; 12116 struct siba_softc *siba = sd->sd_bus; 12117 struct bwn_softc *sc = mac->mac_sc; 12118 struct ifnet *ifp = sc->sc_ifp; 12119 struct ieee80211com *ic = ifp->if_l2com; 12120 static const struct bwn_b2062_freq freqdata_tab[] = { 12121 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12122 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12123 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12124 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12125 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12126 { 19200, { 1, 1, 1, 1, 14, 9 } } 12127 }; 12128 static const struct bwn_wpair v1[] = { 12129 { BWN_B2062_N_TXCTL3, 0 }, 12130 { BWN_B2062_N_TXCTL4, 0 }, 12131 { BWN_B2062_N_TXCTL5, 0 }, 12132 { BWN_B2062_N_TXCTL6, 0 }, 12133 { BWN_B2062_N_PDNCTL0, 0x40 }, 12134 { BWN_B2062_N_PDNCTL0, 0 }, 12135 { BWN_B2062_N_CALIB_TS, 0x10 }, 12136 { BWN_B2062_N_CALIB_TS, 0 } 12137 }; 12138 const struct bwn_b2062_freq *f = NULL; 12139 uint32_t xtalfreq, ref; 12140 unsigned int i; 12141 12142 bwn_phy_lp_b2062_tblinit(mac); 12143 12144 for (i = 0; i < N(v1); i++) 12145 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12146 if (mac->mac_phy.rev > 0) 12147 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12148 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12149 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12150 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12151 else 12152 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12153 12154 KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU, 12155 ("%s:%d: fail", __func__, __LINE__)); 12156 xtalfreq = siba->siba_cc.scc_pmu.freq * 1000; 12157 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12158 12159 if (xtalfreq <= 30000000) { 12160 plp->plp_div = 1; 12161 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12162 } else { 12163 plp->plp_div = 2; 12164 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12165 } 12166 12167 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12168 CALC_CTL7(xtalfreq, plp->plp_div)); 12169 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12170 CALC_CTL18(xtalfreq, plp->plp_div)); 12171 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12172 CALC_CTL19(xtalfreq, plp->plp_div)); 12173 12174 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12175 ref &= 0xffff; 12176 for (i = 0; i < N(freqdata_tab); i++) { 12177 if (ref < freqdata_tab[i].freq) { 12178 f = &freqdata_tab[i]; 12179 break; 12180 } 12181 } 12182 if (f == NULL) 12183 f = &freqdata_tab[N(freqdata_tab) - 1]; 12184 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12185 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12186 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12187 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12188 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12189 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12190#undef CALC_CTL7 12191#undef CALC_CTL18 12192#undef CALC_CTL19 12193} 12194 12195static void 12196bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12197{ 12198 12199 bwn_phy_lp_b2063_tblinit(mac); 12200 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12201 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12202 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12203 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12204 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12205 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12206 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12207 if (mac->mac_phy.rev == 2) { 12208 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12209 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12210 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12211 } else { 12212 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12213 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12214 } 12215} 12216 12217static void 12218bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12219{ 12220 struct siba_dev_softc *sd = mac->mac_sd; 12221 struct siba_softc *siba = sd->sd_bus; 12222 static const struct bwn_wpair v1[] = { 12223 { BWN_B2063_RX_BB_SP8, 0x0 }, 12224 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12225 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12226 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12227 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12228 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12229 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12230 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12231 }; 12232 static const struct bwn_wpair v2[] = { 12233 { BWN_B2063_TX_BB_SP3, 0x0 }, 12234 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12235 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12236 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12237 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12238 }; 12239 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 12240 int i; 12241 uint8_t tmp; 12242 12243 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12244 12245 for (i = 0; i < 2; i++) 12246 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12247 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12248 for (i = 2; i < N(v1); i++) 12249 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12250 for (i = 0; i < 10000; i++) { 12251 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12252 break; 12253 DELAY(1000); 12254 } 12255 12256 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12257 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12258 12259 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12260 12261 for (i = 0; i < N(v2); i++) 12262 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12263 if (freqxtal == 24000000) { 12264 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12265 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12266 } else { 12267 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12268 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12269 } 12270 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12271 for (i = 0; i < 10000; i++) { 12272 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12273 break; 12274 DELAY(1000); 12275 } 12276 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12277 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12278 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12279} 12280 12281static void 12282bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12283{ 12284 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12285 struct bwn_softc *sc = mac->mac_sc; 12286 struct bwn_phy_lp_iq_est ie; 12287 struct bwn_txgain tx_gains; 12288 static const uint32_t pwrtbl[21] = { 12289 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12290 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12291 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12292 0x0004c, 0x0002c, 0x0001a, 12293 }; 12294 uint32_t npwr, ipwr, sqpwr, tmp; 12295 int loopback, i, j, sum, error; 12296 uint16_t save[7]; 12297 uint8_t txo, bbmult, txpctlmode; 12298 12299 error = bwn_phy_lp_switch_channel(mac, 7); 12300 if (error) 12301 device_printf(sc->sc_dev, 12302 "failed to change channel to 7 (%d)\n", error); 12303 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12304 bbmult = bwn_phy_lp_get_bbmult(mac); 12305 if (txo) 12306 tx_gains = bwn_phy_lp_get_txgain(mac); 12307 12308 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12309 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12310 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12311 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12312 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12313 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12314 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12315 12316 bwn_phy_lp_get_txpctlmode(mac); 12317 txpctlmode = plp->plp_txpctlmode; 12318 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12319 12320 /* disable CRS */ 12321 bwn_phy_lp_set_deaf(mac, 1); 12322 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12323 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12324 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12325 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12326 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12327 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12328 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12329 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12330 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12331 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12332 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12333 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12334 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12335 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12336 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12337 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12338 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12339 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12340 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12341 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12342 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12343 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12344 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12345 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12346 12347 loopback = bwn_phy_lp_loopback(mac); 12348 if (loopback == -1) 12349 goto done; 12350 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12351 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12352 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12353 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12354 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12355 12356 tmp = 0; 12357 memset(&ie, 0, sizeof(ie)); 12358 for (i = 128; i <= 159; i++) { 12359 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12360 sum = 0; 12361 for (j = 5; j <= 25; j++) { 12362 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12363 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12364 goto done; 12365 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12366 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12367 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12368 12); 12369 sum += ((ipwr - npwr) * (ipwr - npwr)); 12370 if ((i == 128) || (sum < tmp)) { 12371 plp->plp_rccap = i; 12372 tmp = sum; 12373 } 12374 } 12375 } 12376 bwn_phy_lp_ddfs_turnoff(mac); 12377done: 12378 /* restore CRS */ 12379 bwn_phy_lp_clear_deaf(mac, 1); 12380 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12381 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12382 12383 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12384 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12385 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12386 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12387 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12388 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12389 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12390 12391 bwn_phy_lp_set_bbmult(mac, bbmult); 12392 if (txo) 12393 bwn_phy_lp_set_txgain(mac, &tx_gains); 12394 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12395 if (plp->plp_rccap) 12396 bwn_phy_lp_set_rccap(mac); 12397} 12398 12399static void 12400bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12401{ 12402 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12403 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12404 12405 if (mac->mac_phy.rev == 1) 12406 rc_cap = MIN(rc_cap + 5, 15); 12407 12408 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12409 MAX(plp->plp_rccap - 4, 0x80)); 12410 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12411 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12412 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12413} 12414 12415static uint32_t 12416bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12417{ 12418 uint32_t i, q, r; 12419 12420 if (div == 0) 12421 return (0); 12422 12423 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12424 q <<= 1; 12425 if (r << 1 >= div) { 12426 q++; 12427 r = (r << 1) - div; 12428 } 12429 } 12430 if (r << 1 >= div) 12431 q++; 12432 return (q); 12433} 12434 12435static void 12436bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12437{ 12438 struct siba_dev_softc *sd = mac->mac_sd; 12439 struct siba_softc *siba = sd->sd_bus; 12440 12441 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12442 DELAY(20); 12443 if (siba->siba_chipid == 0x5354) { 12444 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12445 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12446 } else { 12447 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12448 } 12449 DELAY(5); 12450} 12451 12452static void 12453bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12454{ 12455 12456 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12457 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12458 DELAY(200); 12459} 12460 12461static void 12462bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12463{ 12464#define FLAG_A 0x01 12465#define FLAG_G 0x02 12466 struct bwn_softc *sc = mac->mac_sc; 12467 struct ifnet *ifp = sc->sc_ifp; 12468 struct ieee80211com *ic = ifp->if_l2com; 12469 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12470 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12471 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12472 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12473 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12474 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12475 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12476 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12477 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12478 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12479 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12480 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12481 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12482 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12483 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12484 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12485 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12486 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12487 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12488 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12489 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12490 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12491 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12492 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12493 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12494 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12495 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12496 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12497 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12498 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12499 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12500 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12501 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12502 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12503 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12504 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12505 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12506 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12507 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12508 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12509 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12510 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12511 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12512 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12513 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12514 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12515 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12516 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12517 }; 12518 const struct bwn_b206x_rfinit_entry *br; 12519 unsigned int i; 12520 12521 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12522 br = &bwn_b2062_init_tab[i]; 12523 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12524 if (br->br_flags & FLAG_G) 12525 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12526 } else { 12527 if (br->br_flags & FLAG_A) 12528 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12529 } 12530 } 12531#undef FLAG_A 12532#undef FLAG_B 12533} 12534 12535static void 12536bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12537{ 12538#define FLAG_A 0x01 12539#define FLAG_G 0x02 12540 struct bwn_softc *sc = mac->mac_sc; 12541 struct ifnet *ifp = sc->sc_ifp; 12542 struct ieee80211com *ic = ifp->if_l2com; 12543 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12544 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12545 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12546 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12547 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12548 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12549 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12550 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12551 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12552 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12553 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12554 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12555 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12556 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12557 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12558 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12559 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12560 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12561 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12562 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12563 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12564 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12565 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12566 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12567 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12568 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12569 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12570 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12571 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12572 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12573 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12574 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12575 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12576 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12577 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12578 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12579 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12580 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12581 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12582 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12583 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12584 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12585 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12586 }; 12587 const struct bwn_b206x_rfinit_entry *br; 12588 unsigned int i; 12589 12590 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12591 br = &bwn_b2063_init_tab[i]; 12592 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12593 if (br->br_flags & FLAG_G) 12594 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12595 } else { 12596 if (br->br_flags & FLAG_A) 12597 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12598 } 12599 } 12600#undef FLAG_A 12601#undef FLAG_B 12602} 12603 12604static void 12605bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12606 int count, void *_data) 12607{ 12608 unsigned int i; 12609 uint32_t offset, type; 12610 uint8_t *data = _data; 12611 12612 type = BWN_TAB_GETTYPE(typenoffset); 12613 offset = BWN_TAB_GETOFFSET(typenoffset); 12614 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12615 12616 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12617 12618 for (i = 0; i < count; i++) { 12619 switch (type) { 12620 case BWN_TAB_8BIT: 12621 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12622 data++; 12623 break; 12624 case BWN_TAB_16BIT: 12625 *((uint16_t *)data) = BWN_PHY_READ(mac, 12626 BWN_PHY_TABLEDATALO); 12627 data += 2; 12628 break; 12629 case BWN_TAB_32BIT: 12630 *((uint32_t *)data) = BWN_PHY_READ(mac, 12631 BWN_PHY_TABLEDATAHI); 12632 *((uint32_t *)data) <<= 16; 12633 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12634 BWN_PHY_TABLEDATALO); 12635 data += 4; 12636 break; 12637 default: 12638 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12639 } 12640 } 12641} 12642 12643static void 12644bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12645 int count, const void *_data) 12646{ 12647 uint32_t offset, type, value; 12648 const uint8_t *data = _data; 12649 unsigned int i; 12650 12651 type = BWN_TAB_GETTYPE(typenoffset); 12652 offset = BWN_TAB_GETOFFSET(typenoffset); 12653 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12654 12655 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12656 12657 for (i = 0; i < count; i++) { 12658 switch (type) { 12659 case BWN_TAB_8BIT: 12660 value = *data; 12661 data++; 12662 KASSERT(!(value & ~0xff), 12663 ("%s:%d: fail", __func__, __LINE__)); 12664 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12665 break; 12666 case BWN_TAB_16BIT: 12667 value = *((const uint16_t *)data); 12668 data += 2; 12669 KASSERT(!(value & ~0xffff), 12670 ("%s:%d: fail", __func__, __LINE__)); 12671 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12672 break; 12673 case BWN_TAB_32BIT: 12674 value = *((const uint32_t *)data); 12675 data += 4; 12676 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12677 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12678 break; 12679 default: 12680 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12681 } 12682 } 12683} 12684 12685static struct bwn_txgain 12686bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12687{ 12688 struct bwn_txgain tg; 12689 uint16_t tmp; 12690 12691 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12692 if (mac->mac_phy.rev < 2) { 12693 tmp = BWN_PHY_READ(mac, 12694 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12695 tg.tg_gm = tmp & 0x0007; 12696 tg.tg_pga = (tmp & 0x0078) >> 3; 12697 tg.tg_pad = (tmp & 0x780) >> 7; 12698 return (tg); 12699 } 12700 12701 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12702 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12703 tg.tg_gm = tmp & 0xff; 12704 tg.tg_pga = (tmp >> 8) & 0xff; 12705 return (tg); 12706} 12707 12708static uint8_t 12709bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12710{ 12711 12712 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12713} 12714 12715static void 12716bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12717{ 12718 uint16_t pa; 12719 12720 if (mac->mac_phy.rev < 2) { 12721 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12722 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12723 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12724 bwn_phy_lp_set_txgain_override(mac); 12725 return; 12726 } 12727 12728 pa = bwn_phy_lp_get_pa_gain(mac); 12729 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12730 (tg->tg_pga << 8) | tg->tg_gm); 12731 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12732 tg->tg_pad | (pa << 6)); 12733 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12734 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12735 tg->tg_pad | (pa << 8)); 12736 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12737 bwn_phy_lp_set_txgain_override(mac); 12738} 12739 12740static void 12741bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12742{ 12743 12744 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12745} 12746 12747static void 12748bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12749{ 12750 uint16_t trsw = (tx << 1) | rx; 12751 12752 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12753 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12754} 12755 12756static void 12757bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12758{ 12759 struct bwn_softc *sc = mac->mac_sc; 12760 struct ifnet *ifp = sc->sc_ifp; 12761 struct ieee80211com *ic = ifp->if_l2com; 12762 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12763 12764 if (mac->mac_phy.rev < 2) { 12765 trsw = gain & 0x1; 12766 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12767 ext_lna = (gain & 2) >> 1; 12768 12769 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12770 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12771 0xfbff, ext_lna << 10); 12772 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12773 0xf7ff, ext_lna << 11); 12774 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12775 } else { 12776 low_gain = gain & 0xffff; 12777 high_gain = (gain >> 16) & 0xf; 12778 ext_lna = (gain >> 21) & 0x1; 12779 trsw = ~(gain >> 20) & 0x1; 12780 12781 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12782 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12783 0xfdff, ext_lna << 9); 12784 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12785 0xfbff, ext_lna << 10); 12786 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12787 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12788 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12789 tmp = (gain >> 2) & 0x3; 12790 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12791 0xe7ff, tmp<<11); 12792 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12793 tmp << 3); 12794 } 12795 } 12796 12797 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12798 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12799 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12800 if (mac->mac_phy.rev >= 2) { 12801 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12802 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12803 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12804 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12805 } 12806 return; 12807 } 12808 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12809} 12810 12811static void 12812bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12813{ 12814 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12815 12816 if (user) 12817 plp->plp_crsusr_off = 1; 12818 else 12819 plp->plp_crssys_off = 1; 12820 12821 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12822} 12823 12824static void 12825bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12826{ 12827 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12828 struct bwn_softc *sc = mac->mac_sc; 12829 struct ifnet *ifp = sc->sc_ifp; 12830 struct ieee80211com *ic = ifp->if_l2com; 12831 12832 if (user) 12833 plp->plp_crsusr_off = 0; 12834 else 12835 plp->plp_crssys_off = 0; 12836 12837 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12838 return; 12839 12840 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12841 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12842 else 12843 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12844} 12845 12846static unsigned int 12847bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12848{ 12849 struct bwn_softc *sc = mac->mac_sc; 12850 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12851 static uint8_t sqrt_table[256] = { 12852 10, 14, 17, 20, 22, 24, 26, 28, 12853 30, 31, 33, 34, 36, 37, 38, 40, 12854 41, 42, 43, 44, 45, 46, 47, 48, 12855 50, 50, 51, 52, 53, 54, 55, 56, 12856 57, 58, 59, 60, 60, 61, 62, 63, 12857 64, 64, 65, 66, 67, 67, 68, 69, 12858 70, 70, 71, 72, 72, 73, 74, 74, 12859 75, 76, 76, 77, 78, 78, 79, 80, 12860 80, 81, 81, 82, 83, 83, 84, 84, 12861 85, 86, 86, 87, 87, 88, 88, 89, 12862 90, 90, 91, 91, 92, 92, 93, 93, 12863 94, 94, 95, 95, 96, 96, 97, 97, 12864 98, 98, 99, 100, 100, 100, 101, 101, 12865 102, 102, 103, 103, 104, 104, 105, 105, 12866 106, 106, 107, 107, 108, 108, 109, 109, 12867 110, 110, 110, 111, 111, 112, 112, 113, 12868 113, 114, 114, 114, 115, 115, 116, 116, 12869 117, 117, 117, 118, 118, 119, 119, 120, 12870 120, 120, 121, 121, 122, 122, 122, 123, 12871 123, 124, 124, 124, 125, 125, 126, 126, 12872 126, 127, 127, 128, 128, 128, 129, 129, 12873 130, 130, 130, 131, 131, 131, 132, 132, 12874 133, 133, 133, 134, 134, 134, 135, 135, 12875 136, 136, 136, 137, 137, 137, 138, 138, 12876 138, 139, 139, 140, 140, 140, 141, 141, 12877 141, 142, 142, 142, 143, 143, 143, 144, 12878 144, 144, 145, 145, 145, 146, 146, 146, 12879 147, 147, 147, 148, 148, 148, 149, 149, 12880 150, 150, 150, 150, 151, 151, 151, 152, 12881 152, 152, 153, 153, 153, 154, 154, 154, 12882 155, 155, 155, 156, 156, 156, 157, 157, 12883 157, 158, 158, 158, 159, 159, 159, 160 12884 }; 12885 12886 if (x == 0) 12887 return (0); 12888 if (x >= 256) { 12889 device_printf(sc->sc_dev, 12890 "out of bounds of the square-root table (%d)\n", x); 12891 return (16); 12892 } 12893 return (sqrt_table[x - 1] / 10); 12894} 12895 12896static int 12897bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12898{ 12899#define CALC_COEFF(_v, _x, _y, _z) do { \ 12900 int _t; \ 12901 _t = _x - 20; \ 12902 if (_t >= 0) { \ 12903 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12904 } else { \ 12905 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12906 } \ 12907} while (0) 12908#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12909 int _t; \ 12910 _t = _x - 11; \ 12911 if (_t >= 0) \ 12912 tmp[3] = (_y << (31 - _x)) / (_z >> _t); \ 12913 else \ 12914 tmp[3] = (_y << (31 - _x)) / (_z << -_t); \ 12915} while (0) 12916 struct bwn_phy_lp_iq_est ie; 12917 uint16_t v0, v1; 12918 int tmp[2], ret; 12919 12920 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12921 v0 = v1 >> 8; 12922 v1 |= 0xff; 12923 12924 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12925 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12926 12927 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12928 if (ret == 0) 12929 goto done; 12930 12931 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12932 ret = 0; 12933 goto done; 12934 } 12935 12936 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12937 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12938 12939 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12940 v0 = tmp[0] >> 3; 12941 v1 = tmp[1] >> 4; 12942done: 12943 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12944 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12945 return ret; 12946#undef CALC_COEFF 12947#undef CALC_COEFF2 12948} 12949 12950static void 12951bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12952{ 12953 static const uint16_t noisescale[] = { 12954 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12955 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12956 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12957 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12958 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12959 }; 12960 static const uint16_t crsgainnft[] = { 12961 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12962 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12963 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12964 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12965 0x013d, 12966 }; 12967 static const uint16_t filterctl[] = { 12968 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12969 0xff53, 0x0127, 12970 }; 12971 static const uint32_t psctl[] = { 12972 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12973 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12974 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12975 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12976 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12977 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12978 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12979 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12980 }; 12981 static const uint16_t ofdmcckgain_r0[] = { 12982 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12983 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12984 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12985 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12986 0x755d, 12987 }; 12988 static const uint16_t ofdmcckgain_r1[] = { 12989 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12990 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12991 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12992 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12993 0x755d, 12994 }; 12995 static const uint16_t gaindelta[] = { 12996 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12997 0x0000, 12998 }; 12999 static const uint32_t txpwrctl[] = { 13000 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 13001 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 13002 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 13003 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 13004 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 13005 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 13006 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 13007 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 13008 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 13009 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 13010 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 13011 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 13012 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 13013 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13014 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13015 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13016 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13017 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13018 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13019 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13020 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13021 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13022 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13023 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13024 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13025 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13026 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13027 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13028 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13029 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13030 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13031 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13032 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13033 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13034 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13037 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13038 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 13039 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 13040 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 13041 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 13042 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 13043 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 13044 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 13045 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 13046 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 13047 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 13048 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 13049 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 13050 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 13051 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 13052 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 13053 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 13054 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 13055 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 13056 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 13057 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 13058 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 13059 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 13060 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 13061 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 13062 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 13063 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 13064 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13065 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13066 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13067 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13068 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13069 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13070 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13071 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13072 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13073 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13074 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13075 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13076 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13077 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13078 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13079 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13080 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13081 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13082 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13083 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13084 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13085 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13086 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13087 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13088 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13089 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13090 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13091 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13092 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13093 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13094 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13095 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13096 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13097 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13098 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13099 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13100 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13101 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13102 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13103 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13104 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13105 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13106 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13107 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13108 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13109 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13110 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13111 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13112 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13113 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13114 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13115 0x00000702, 13116 }; 13117 13118 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13119 13120 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13121 bwn_tab_sigsq_tbl); 13122 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13123 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13124 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13125 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13126 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13127 bwn_tab_pllfrac_tbl); 13128 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13129 bwn_tabl_iqlocal_tbl); 13130 if (mac->mac_phy.rev == 0) { 13131 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13132 ofdmcckgain_r0); 13133 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13134 ofdmcckgain_r0); 13135 } else { 13136 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13137 ofdmcckgain_r1); 13138 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13139 ofdmcckgain_r1); 13140 } 13141 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13142 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13143} 13144 13145static void 13146bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13147{ 13148 struct siba_dev_softc *sd = mac->mac_sd; 13149 struct siba_softc *siba = sd->sd_bus; 13150 int i; 13151 static const uint16_t noisescale[] = { 13152 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13153 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13154 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13155 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13156 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13157 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13158 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13159 }; 13160 static const uint32_t filterctl[] = { 13161 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13162 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13163 }; 13164 static const uint32_t psctl[] = { 13165 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13166 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13167 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13168 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13169 }; 13170 static const uint32_t gainidx[] = { 13171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13172 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13173 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13174 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13175 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13176 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13177 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13178 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13179 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13180 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13181 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13182 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13183 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13184 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13185 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13186 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13187 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13188 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13189 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13190 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13191 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13192 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13193 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13194 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13195 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13196 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13197 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13198 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13199 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13200 0x0000001a, 0x64ca55ad, 0x0000001a 13201 }; 13202 static const uint16_t auxgainidx[] = { 13203 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13204 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13205 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13206 0x0004, 0x0016 13207 }; 13208 static const uint16_t swctl[] = { 13209 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13210 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13211 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13212 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13213 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13214 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13215 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13216 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13217 }; 13218 static const uint8_t hf[] = { 13219 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13220 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13221 }; 13222 static const uint32_t gainval[] = { 13223 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13224 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13225 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13226 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13227 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13228 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13230 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13231 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13232 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13233 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13234 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13236 0x000000f1, 0x00000000, 0x00000000 13237 }; 13238 static const uint16_t gain[] = { 13239 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13240 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13241 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13242 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13243 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13244 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13245 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13246 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13247 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13248 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13251 }; 13252 static const uint32_t papdeps[] = { 13253 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13254 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13255 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13256 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13257 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13258 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13259 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13260 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13261 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13262 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13263 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13264 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13265 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13266 }; 13267 static const uint32_t papdmult[] = { 13268 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13269 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13270 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13271 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13272 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13273 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13274 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13275 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13276 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13277 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13278 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13279 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13280 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13281 }; 13282 static const uint32_t gainidx_a0[] = { 13283 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13284 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13285 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13286 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13287 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13288 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13289 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13290 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13291 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13292 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13293 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13294 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13295 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13296 }; 13297 static const uint16_t auxgainidx_a0[] = { 13298 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13299 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13300 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13301 0x0002, 0x0014 13302 }; 13303 static const uint32_t gainval_a0[] = { 13304 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13305 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13306 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13307 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13308 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13309 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13310 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13311 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13312 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13313 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13314 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13315 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13316 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13317 0x000000f7, 0x00000000, 0x00000000 13318 }; 13319 static const uint16_t gain_a0[] = { 13320 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13321 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13322 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13323 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13324 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13325 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13326 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13327 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13328 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13329 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13330 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13331 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13332 }; 13333 13334 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13335 13336 for (i = 0; i < 704; i++) 13337 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13338 13339 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13340 bwn_tab_sigsq_tbl); 13341 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13342 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13343 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13344 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13345 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13346 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13347 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13348 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13349 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13350 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13351 bwn_tab_pllfrac_tbl); 13352 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13353 bwn_tabl_iqlocal_tbl); 13354 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13355 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13356 13357 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 13358 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13359 gainidx_a0); 13360 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13361 auxgainidx_a0); 13362 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13363 gainval_a0); 13364 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13365 } 13366} 13367 13368static void 13369bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13370{ 13371 struct siba_dev_softc *sd = mac->mac_sd; 13372 struct siba_softc *siba = sd->sd_bus; 13373 struct bwn_softc *sc = mac->mac_sc; 13374 struct ifnet *ifp = sc->sc_ifp; 13375 struct ieee80211com *ic = ifp->if_l2com; 13376 static struct bwn_txgain_entry txgain_r2[] = { 13377 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13378 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13379 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13380 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13381 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13382 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13383 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13384 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13385 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13386 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13387 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13388 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13389 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13390 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13391 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13392 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13393 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13394 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13395 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13396 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13397 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13398 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13399 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13400 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13401 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13402 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13403 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13404 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13405 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13406 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13407 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13408 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13409 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13410 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13411 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13412 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13413 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13414 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13415 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13416 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13417 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13418 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13419 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13420 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13421 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13422 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13423 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13424 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13425 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13426 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13427 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13428 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13429 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13430 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13431 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13432 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13433 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13434 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13435 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13436 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13437 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13438 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13439 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13440 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13441 }; 13442 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13443 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13444 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13445 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13446 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13447 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13448 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13449 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13450 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13451 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13452 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13453 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13454 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13455 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13456 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13457 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13458 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13459 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13460 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13461 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13462 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13463 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13464 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13465 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13466 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13467 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13468 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13469 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13470 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13471 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13472 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13473 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13474 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13475 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13476 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13477 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13478 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13479 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13480 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13481 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13482 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13483 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13484 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13485 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13486 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13487 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13488 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13489 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13490 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13491 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13492 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13493 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13494 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13495 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13496 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13497 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13498 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13499 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13500 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13501 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13502 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13503 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13504 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13505 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13506 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13507 }; 13508 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13509 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13510 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13511 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13512 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13513 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13514 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13515 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13516 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13517 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13518 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13519 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13520 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13521 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13522 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13523 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13524 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13525 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13526 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13527 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13528 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13529 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13530 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13531 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13532 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13533 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13534 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13535 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13536 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13537 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13538 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13539 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13540 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13541 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13542 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13543 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13544 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13545 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13546 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13547 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13548 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13549 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13550 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13551 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13552 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13553 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13554 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13555 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13556 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13557 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13558 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13559 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13560 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13561 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13562 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13563 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13564 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13565 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13566 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13567 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13568 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13569 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13570 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13571 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13572 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13573 }; 13574 static struct bwn_txgain_entry txgain_r0[] = { 13575 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13576 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13577 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13578 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13579 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13580 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13581 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13582 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13583 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13584 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13585 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13586 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13587 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13588 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13589 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13590 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13591 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13592 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13593 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13594 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13595 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13596 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13597 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13598 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13599 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13600 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13601 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13602 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13603 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13604 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13605 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13606 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13607 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13608 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13609 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13610 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13611 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13612 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13613 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13614 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13615 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13616 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13617 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13618 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13619 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13620 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13621 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13622 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13623 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13624 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13625 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13626 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13627 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13628 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13629 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13630 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13631 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13632 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13633 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13634 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13635 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13636 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13637 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13638 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13639 }; 13640 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13641 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13642 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13643 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13644 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13645 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13646 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13647 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13648 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13649 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13650 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13651 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13652 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13653 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13654 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13655 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13656 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13657 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13658 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13659 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13660 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13661 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13662 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13663 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13664 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13665 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13666 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13667 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13668 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13669 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13670 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13671 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13672 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13673 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13674 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13675 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13676 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13677 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13678 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13679 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13680 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13681 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13682 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13683 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13684 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13685 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13686 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13687 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13688 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13689 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13690 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13691 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13692 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13693 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13694 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13695 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13696 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13697 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13698 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13699 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13700 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13701 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13702 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13703 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13704 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13705 }; 13706 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13707 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13708 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13709 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13710 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13711 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13712 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13713 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13714 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13715 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13716 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13717 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13718 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13719 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13720 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13721 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13722 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13723 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13724 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13725 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13726 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13727 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13728 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13729 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13730 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13731 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13732 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13733 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13734 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13735 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13736 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13737 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13738 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13739 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13740 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13741 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13742 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13743 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13744 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13745 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13746 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13747 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13748 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13749 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13750 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13751 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13752 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13753 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13754 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13755 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13756 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13757 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13758 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13759 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13760 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13761 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13762 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13763 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13764 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13765 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13766 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13767 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13768 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13769 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13770 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13771 }; 13772 static struct bwn_txgain_entry txgain_r1[] = { 13773 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13774 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13775 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13776 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13777 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13778 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13779 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13780 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13781 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13782 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13783 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13784 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13785 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13786 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13787 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13788 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13789 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13790 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13791 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13792 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13793 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13794 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13795 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13796 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13797 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13798 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13799 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13800 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13801 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13802 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13803 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13804 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13805 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13806 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13807 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13808 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13809 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13810 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13811 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13812 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13813 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13814 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13815 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13816 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13817 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13818 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13819 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13820 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13821 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13822 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13823 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13824 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13825 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13826 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13827 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13828 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13829 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13830 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13831 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13832 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13833 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13834 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13835 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13836 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13837 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13838 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13839 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13840 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13841 { 7, 11, 6, 0, 71 } 13842 }; 13843 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13844 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13845 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13846 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13847 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13848 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13849 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13850 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13851 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13852 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13853 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13854 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13855 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13856 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13857 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13858 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13859 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13860 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13861 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13862 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13863 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13864 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13865 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13866 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13867 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13868 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13869 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13870 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13871 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13872 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13873 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13874 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13875 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13876 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13877 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13878 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13879 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13880 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13881 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13882 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13883 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13884 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13885 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13886 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13887 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13888 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13889 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13890 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13891 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13892 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13893 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13894 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13895 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13896 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13897 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13898 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13899 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13900 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13901 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13902 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13903 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13904 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13905 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13906 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13907 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13908 }; 13909 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13910 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13911 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13912 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13913 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13914 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13915 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13916 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13917 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13918 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13919 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13920 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13921 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13922 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13923 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13924 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13925 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13926 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13927 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13928 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13929 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13930 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13931 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13932 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13933 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13934 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13935 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13936 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13937 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13938 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13939 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13940 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13941 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13942 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13943 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13944 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13945 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13946 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13947 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13948 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13949 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13950 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13951 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13952 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13953 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13954 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13955 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13956 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13957 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13958 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13959 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13960 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13961 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13962 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13963 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13964 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13965 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13966 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13967 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13968 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13969 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13970 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13971 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13972 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13973 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13974 }; 13975 13976 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13977 if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA) 13978 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13979 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13980 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13981 txgain_2ghz_r2); 13982 else 13983 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13984 txgain_5ghz_r2); 13985 return; 13986 } 13987 13988 if (mac->mac_phy.rev == 0) { 13989 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 13990 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 13991 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13992 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13993 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13994 txgain_2ghz_r0); 13995 else 13996 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13997 txgain_5ghz_r0); 13998 return; 13999 } 14000 14001 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 14002 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 14003 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 14004 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 14005 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 14006 else 14007 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 14008} 14009 14010static void 14011bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 14012{ 14013 uint32_t offset, type; 14014 14015 type = BWN_TAB_GETTYPE(typeoffset); 14016 offset = BWN_TAB_GETOFFSET(typeoffset); 14017 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14018 14019 switch (type) { 14020 case BWN_TAB_8BIT: 14021 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 14022 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14023 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14024 break; 14025 case BWN_TAB_16BIT: 14026 KASSERT(!(value & ~0xffff), 14027 ("%s:%d: fail", __func__, __LINE__)); 14028 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14029 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14030 break; 14031 case BWN_TAB_32BIT: 14032 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14033 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 14034 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14035 break; 14036 default: 14037 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14038 } 14039} 14040 14041static int 14042bwn_phy_lp_loopback(struct bwn_mac *mac) 14043{ 14044 struct bwn_phy_lp_iq_est ie; 14045 int i, index = -1; 14046 uint32_t tmp; 14047 14048 memset(&ie, 0, sizeof(ie)); 14049 14050 bwn_phy_lp_set_trsw_over(mac, 1, 1); 14051 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 14052 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 14053 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 14054 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 14055 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 14056 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 14057 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 14058 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 14059 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 14060 for (i = 0; i < 32; i++) { 14061 bwn_phy_lp_set_rxgain_idx(mac, i); 14062 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 14063 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 14064 continue; 14065 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 14066 if ((tmp > 4000) && (tmp < 10000)) { 14067 index = i; 14068 break; 14069 } 14070 } 14071 bwn_phy_lp_ddfs_turnoff(mac); 14072 return (index); 14073} 14074 14075static void 14076bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 14077{ 14078 14079 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 14080} 14081 14082static void 14083bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 14084 int incr1, int incr2, int scale_idx) 14085{ 14086 14087 bwn_phy_lp_ddfs_turnoff(mac); 14088 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 14089 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 14090 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14091 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14092 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14093 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14094 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14095 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14096 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14097 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14098} 14099 14100static uint8_t 14101bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14102 struct bwn_phy_lp_iq_est *ie) 14103{ 14104 int i; 14105 14106 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14107 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14108 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14109 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14110 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14111 14112 for (i = 0; i < 500; i++) { 14113 if (!(BWN_PHY_READ(mac, 14114 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14115 break; 14116 DELAY(1000); 14117 } 14118 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14119 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14120 return 0; 14121 } 14122 14123 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14124 ie->ie_iqprod <<= 16; 14125 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14126 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14127 ie->ie_ipwr <<= 16; 14128 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14129 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14130 ie->ie_qpwr <<= 16; 14131 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14132 14133 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14134 return 1; 14135} 14136 14137static uint32_t 14138bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14139{ 14140 uint32_t offset, type, value; 14141 14142 type = BWN_TAB_GETTYPE(typeoffset); 14143 offset = BWN_TAB_GETOFFSET(typeoffset); 14144 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14145 14146 switch (type) { 14147 case BWN_TAB_8BIT: 14148 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14149 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14150 break; 14151 case BWN_TAB_16BIT: 14152 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14153 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14154 break; 14155 case BWN_TAB_32BIT: 14156 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14157 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14158 value <<= 16; 14159 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14160 break; 14161 default: 14162 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14163 value = 0; 14164 } 14165 14166 return (value); 14167} 14168 14169static void 14170bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14171{ 14172 14173 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14174 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14175} 14176 14177static void 14178bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14179{ 14180 uint16_t ctl; 14181 14182 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14183 ctl |= dac << 7; 14184 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14185} 14186 14187static void 14188bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14189{ 14190 14191 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14192 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14193} 14194 14195static void 14196bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14197{ 14198 14199 if (mac->mac_phy.rev < 2) 14200 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14201 else { 14202 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14203 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14204 } 14205 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14206} 14207 14208static uint16_t 14209bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14210{ 14211 14212 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14213} 14214 14215static uint8_t 14216bwn_nbits(int32_t val) 14217{ 14218 uint32_t tmp; 14219 uint8_t nbits = 0; 14220 14221 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14222 nbits++; 14223 return (nbits); 14224} 14225 14226static void 14227bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14228 struct bwn_txgain_entry *table) 14229{ 14230 int i; 14231 14232 for (i = offset; i < count; i++) 14233 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14234} 14235 14236static void 14237bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14238 struct bwn_txgain_entry data) 14239{ 14240 14241 if (mac->mac_phy.rev >= 2) 14242 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14243 else 14244 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14245} 14246 14247static void 14248bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14249 struct bwn_txgain_entry te) 14250{ 14251 struct bwn_softc *sc = mac->mac_sc; 14252 struct ifnet *ifp = sc->sc_ifp; 14253 struct ieee80211com *ic = ifp->if_l2com; 14254 uint32_t tmp; 14255 14256 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14257 14258 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14259 if (mac->mac_phy.rev >= 3) { 14260 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14261 (0x10 << 24) : (0x70 << 24)); 14262 } else { 14263 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14264 (0x14 << 24) : (0x7f << 24)); 14265 } 14266 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14267 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14268 te.te_bbmult << 20 | te.te_dac << 28); 14269} 14270 14271static void 14272bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14273 struct bwn_txgain_entry te) 14274{ 14275 14276 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14277 14278 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14279 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14280 te.te_dac); 14281 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14282} 14283 14284static void 14285bwn_sysctl_node(struct bwn_softc *sc) 14286{ 14287 device_t dev = sc->sc_dev; 14288 struct bwn_mac *mac; 14289 struct bwn_stats *stats; 14290 14291 /* XXX assume that count of MAC is only 1. */ 14292 14293 if ((mac = sc->sc_curmac) == NULL) 14294 return; 14295 stats = &mac->mac_stats; 14296 14297 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14298 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14299 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14300 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14301 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14302 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14303 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14304 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14305 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14306 14307#ifdef BWN_DEBUG 14308 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14309 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14310 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14311#endif 14312} 14313 14314static void 14315bwn_identify(driver_t *driver, device_t parent) 14316{ 14317 14318 BUS_ADD_CHILD(parent, 0, "bwn", -1); 14319} 14320 14321static device_method_t bwn_methods[] = { 14322 /* Device interface */ 14323 DEVMETHOD(device_identify, bwn_identify), 14324 DEVMETHOD(device_probe, bwn_probe), 14325 DEVMETHOD(device_attach, bwn_attach), 14326 DEVMETHOD(device_detach, bwn_detach), 14327 DEVMETHOD(device_suspend, bwn_suspend), 14328 DEVMETHOD(device_resume, bwn_resume), 14329 { 0,0 } 14330}; 14331static driver_t bwn_driver = { 14332 "bwn", 14333 bwn_methods, 14334 sizeof(struct bwn_softc) 14335}; 14336static devclass_t bwn_devclass; 14337DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14338MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14339MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14340MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14341MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14342