if_bwn.c revision 204436
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 204436 2010-02-27 23:04:29Z 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", 7793 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name); 7794 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7795 fw = firmware_get(namebuf); 7796 if (fw == NULL) { 7797 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7798 namebuf); 7799 return (ENOENT); 7800 } 7801 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7802 goto fail; 7803 hdr = (const struct bwn_fwhdr *)(fw->data); 7804 switch (hdr->type) { 7805 case BWN_FWTYPE_UCODE: 7806 case BWN_FWTYPE_PCM: 7807 if (be32toh(hdr->size) != 7808 (fw->datasize - sizeof(struct bwn_fwhdr))) 7809 goto fail; 7810 /* FALLTHROUGH */ 7811 case BWN_FWTYPE_IV: 7812 if (hdr->ver != 1) 7813 goto fail; 7814 break; 7815 default: 7816 goto fail; 7817 } 7818 bfw->filename = name; 7819 bfw->fw = fw; 7820 bfw->type = type; 7821 return (0); 7822fail: 7823 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7824 if (fw != NULL) 7825 firmware_put(fw, FIRMWARE_UNLOAD); 7826 return (EPROTO); 7827} 7828 7829static void 7830bwn_release_firmware(struct bwn_mac *mac) 7831{ 7832 7833 bwn_do_release_fw(&mac->mac_fw.ucode); 7834 bwn_do_release_fw(&mac->mac_fw.pcm); 7835 bwn_do_release_fw(&mac->mac_fw.initvals); 7836 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7837} 7838 7839static void 7840bwn_do_release_fw(struct bwn_fwfile *bfw) 7841{ 7842 7843 if (bfw->fw != NULL) 7844 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7845 bfw->fw = NULL; 7846 bfw->filename = NULL; 7847} 7848 7849static int 7850bwn_fw_loaducode(struct bwn_mac *mac) 7851{ 7852#define GETFWOFFSET(fwp, offset) \ 7853 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7854#define GETFWSIZE(fwp, offset) \ 7855 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7856 struct bwn_softc *sc = mac->mac_sc; 7857 const uint32_t *data; 7858 unsigned int i; 7859 uint32_t ctl; 7860 uint16_t date, fwcaps, time; 7861 int error = 0; 7862 7863 ctl = BWN_READ_4(mac, BWN_MACCTL); 7864 ctl |= BWN_MACCTL_MCODE_JMP0; 7865 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7866 __LINE__)); 7867 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7868 for (i = 0; i < 64; i++) 7869 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7870 for (i = 0; i < 4096; i += 2) 7871 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7872 7873 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7874 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7875 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7876 i++) { 7877 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7878 DELAY(10); 7879 } 7880 7881 if (mac->mac_fw.pcm.fw) { 7882 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7883 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7884 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7885 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7886 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7887 sizeof(struct bwn_fwhdr)); i++) { 7888 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7889 DELAY(10); 7890 } 7891 } 7892 7893 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7894 BWN_WRITE_4(mac, BWN_MACCTL, 7895 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7896 BWN_MACCTL_MCODE_RUN); 7897 7898 for (i = 0; i < 21; i++) { 7899 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7900 break; 7901 if (i >= 20) { 7902 device_printf(sc->sc_dev, "ucode timeout\n"); 7903 error = ENXIO; 7904 goto error; 7905 } 7906 DELAY(50000); 7907 } 7908 BWN_READ_4(mac, BWN_INTR_REASON); 7909 7910 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7911 if (mac->mac_fw.rev <= 0x128) { 7912 device_printf(sc->sc_dev, "the firmware is too old\n"); 7913 error = EOPNOTSUPP; 7914 goto error; 7915 } 7916 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7917 BWN_SHARED_UCODE_PATCH); 7918 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7919 mac->mac_fw.opensource = (date == 0xffff); 7920 if (bwn_wme != 0) 7921 mac->mac_flags |= BWN_MAC_FLAG_WME; 7922 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7923 7924 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7925 if (mac->mac_fw.opensource == 0) { 7926 device_printf(sc->sc_dev, 7927 "firmware version (rev %u patch %u date %#x time %#x)\n", 7928 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7929 if (mac->mac_fw.no_pcmfile) 7930 device_printf(sc->sc_dev, 7931 "no HW crypto acceleration due to pcm5\n"); 7932 } else { 7933 mac->mac_fw.patch = time; 7934 fwcaps = bwn_fwcaps_read(mac); 7935 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7936 device_printf(sc->sc_dev, 7937 "disabling HW crypto acceleration\n"); 7938 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7939 } 7940 if (!(fwcaps & BWN_FWCAPS_WME)) { 7941 device_printf(sc->sc_dev, "disabling WME support\n"); 7942 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7943 } 7944 } 7945 7946 if (BWN_ISOLDFMT(mac)) 7947 device_printf(sc->sc_dev, "using old firmware image\n"); 7948 7949 return (0); 7950 7951error: 7952 BWN_WRITE_4(mac, BWN_MACCTL, 7953 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7954 BWN_MACCTL_MCODE_JMP0); 7955 7956 return (error); 7957#undef GETFWSIZE 7958#undef GETFWOFFSET 7959} 7960 7961/* OpenFirmware only */ 7962static uint16_t 7963bwn_fwcaps_read(struct bwn_mac *mac) 7964{ 7965 7966 KASSERT(mac->mac_fw.opensource == 1, 7967 ("%s:%d: fail", __func__, __LINE__)); 7968 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7969} 7970 7971static int 7972bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7973 size_t count, size_t array_size) 7974{ 7975#define GET_NEXTIV16(iv) \ 7976 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7977 sizeof(uint16_t) + sizeof(uint16_t))) 7978#define GET_NEXTIV32(iv) \ 7979 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7980 sizeof(uint16_t) + sizeof(uint32_t))) 7981 struct bwn_softc *sc = mac->mac_sc; 7982 const struct bwn_fwinitvals *iv; 7983 uint16_t offset; 7984 size_t i; 7985 uint8_t bit32; 7986 7987 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7988 ("%s:%d: fail", __func__, __LINE__)); 7989 iv = ivals; 7990 for (i = 0; i < count; i++) { 7991 if (array_size < sizeof(iv->offset_size)) 7992 goto fail; 7993 array_size -= sizeof(iv->offset_size); 7994 offset = be16toh(iv->offset_size); 7995 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7996 offset &= BWN_FWINITVALS_OFFSET_MASK; 7997 if (offset >= 0x1000) 7998 goto fail; 7999 if (bit32) { 8000 if (array_size < sizeof(iv->data.d32)) 8001 goto fail; 8002 array_size -= sizeof(iv->data.d32); 8003 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 8004 iv = GET_NEXTIV32(iv); 8005 } else { 8006 8007 if (array_size < sizeof(iv->data.d16)) 8008 goto fail; 8009 array_size -= sizeof(iv->data.d16); 8010 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 8011 8012 iv = GET_NEXTIV16(iv); 8013 } 8014 } 8015 if (array_size != 0) 8016 goto fail; 8017 return (0); 8018fail: 8019 device_printf(sc->sc_dev, "initvals: invalid format\n"); 8020 return (EPROTO); 8021#undef GET_NEXTIV16 8022#undef GET_NEXTIV32 8023} 8024 8025static int 8026bwn_switch_channel(struct bwn_mac *mac, int chan) 8027{ 8028 struct bwn_phy *phy = &(mac->mac_phy); 8029 struct bwn_softc *sc = mac->mac_sc; 8030 struct ifnet *ifp = sc->sc_ifp; 8031 struct ieee80211com *ic = ifp->if_l2com; 8032 uint16_t channelcookie, savedcookie; 8033 int error; 8034 8035 if (chan == 0xffff) 8036 chan = phy->get_default_chan(mac); 8037 8038 channelcookie = chan; 8039 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 8040 channelcookie |= 0x100; 8041 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 8042 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 8043 error = phy->switch_channel(mac, chan); 8044 if (error) 8045 goto fail; 8046 8047 mac->mac_phy.chan = chan; 8048 DELAY(8000); 8049 return (0); 8050fail: 8051 device_printf(sc->sc_dev, "failed to switch channel\n"); 8052 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 8053 return (error); 8054} 8055 8056static uint16_t 8057bwn_ant2phy(int antenna) 8058{ 8059 8060 switch (antenna) { 8061 case BWN_ANT0: 8062 return (BWN_TX_PHY_ANT0); 8063 case BWN_ANT1: 8064 return (BWN_TX_PHY_ANT1); 8065 case BWN_ANT2: 8066 return (BWN_TX_PHY_ANT2); 8067 case BWN_ANT3: 8068 return (BWN_TX_PHY_ANT3); 8069 case BWN_ANTAUTO: 8070 return (BWN_TX_PHY_ANT01AUTO); 8071 } 8072 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8073 return (0); 8074} 8075 8076static void 8077bwn_wme_load(struct bwn_mac *mac) 8078{ 8079 struct bwn_softc *sc = mac->mac_sc; 8080 int i; 8081 8082 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8083 ("%s:%d: fail", __func__, __LINE__)); 8084 8085 bwn_mac_suspend(mac); 8086 for (i = 0; i < N(sc->sc_wmeParams); i++) 8087 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8088 bwn_wme_shm_offsets[i]); 8089 bwn_mac_enable(mac); 8090} 8091 8092static void 8093bwn_wme_loadparams(struct bwn_mac *mac, 8094 const struct wmeParams *p, uint16_t shm_offset) 8095{ 8096#define SM(_v, _f) (((_v) << _f##_S) & _f) 8097 struct bwn_softc *sc = mac->mac_sc; 8098 uint16_t params[BWN_NR_WMEPARAMS]; 8099 int slot, tmp; 8100 unsigned int i; 8101 8102 slot = BWN_READ_2(mac, BWN_RNG) & 8103 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8104 8105 memset(¶ms, 0, sizeof(params)); 8106 8107 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8108 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8109 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8110 8111 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8112 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8113 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8114 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8115 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8116 params[BWN_WMEPARAM_BSLOTS] = slot; 8117 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8118 8119 for (i = 0; i < N(params); i++) { 8120 if (i == BWN_WMEPARAM_STATUS) { 8121 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8122 shm_offset + (i * 2)); 8123 tmp |= 0x100; 8124 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8125 tmp); 8126 } else { 8127 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8128 params[i]); 8129 } 8130 } 8131} 8132 8133static void 8134bwn_mac_write_bssid(struct bwn_mac *mac) 8135{ 8136 struct bwn_softc *sc = mac->mac_sc; 8137 uint32_t tmp; 8138 int i; 8139 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8140 8141 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8142 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8143 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8144 IEEE80211_ADDR_LEN); 8145 8146 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8147 tmp = (uint32_t) (mac_bssid[i + 0]); 8148 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8149 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8150 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8151 bwn_ram_write(mac, 0x20 + i, tmp); 8152 } 8153} 8154 8155static void 8156bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8157 const uint8_t *macaddr) 8158{ 8159 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8160 uint16_t data; 8161 8162 if (!mac) 8163 macaddr = zero; 8164 8165 offset |= 0x0020; 8166 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8167 8168 data = macaddr[0]; 8169 data |= macaddr[1] << 8; 8170 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8171 data = macaddr[2]; 8172 data |= macaddr[3] << 8; 8173 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8174 data = macaddr[4]; 8175 data |= macaddr[5] << 8; 8176 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8177} 8178 8179static void 8180bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8181 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8182{ 8183 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8184 uint8_t per_sta_keys_start = 8; 8185 8186 if (BWN_SEC_NEWAPI(mac)) 8187 per_sta_keys_start = 4; 8188 8189 KASSERT(index < mac->mac_max_nr_keys, 8190 ("%s:%d: fail", __func__, __LINE__)); 8191 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8192 ("%s:%d: fail", __func__, __LINE__)); 8193 8194 if (index >= per_sta_keys_start) 8195 bwn_key_macwrite(mac, index, NULL); 8196 if (key) 8197 memcpy(buf, key, key_len); 8198 bwn_key_write(mac, index, algorithm, buf); 8199 if (index >= per_sta_keys_start) 8200 bwn_key_macwrite(mac, index, mac_addr); 8201 8202 mac->mac_key[index].algorithm = algorithm; 8203} 8204 8205static void 8206bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8207{ 8208 uint32_t addrtmp[2] = { 0, 0 }; 8209 uint8_t start = 8; 8210 8211 if (BWN_SEC_NEWAPI(mac)) 8212 start = 4; 8213 8214 KASSERT(index >= start, 8215 ("%s:%d: fail", __func__, __LINE__)); 8216 index -= start; 8217 8218 if (addr) { 8219 addrtmp[0] = addr[0]; 8220 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8221 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8222 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8223 addrtmp[1] = addr[4]; 8224 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8225 } 8226 8227 if (mac->mac_sd->sd_id.sd_rev >= 5) { 8228 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8229 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8230 } else { 8231 if (index >= 8) { 8232 bwn_shm_write_4(mac, BWN_SHARED, 8233 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8234 bwn_shm_write_2(mac, BWN_SHARED, 8235 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8236 } 8237 } 8238} 8239 8240static void 8241bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8242 const uint8_t *key) 8243{ 8244 unsigned int i; 8245 uint32_t offset; 8246 uint16_t kidx, value; 8247 8248 kidx = BWN_SEC_KEY2FW(mac, index); 8249 bwn_shm_write_2(mac, BWN_SHARED, 8250 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8251 8252 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8253 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8254 value = key[i]; 8255 value |= (uint16_t)(key[i + 1]) << 8; 8256 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8257 } 8258} 8259 8260static void 8261bwn_phy_exit(struct bwn_mac *mac) 8262{ 8263 8264 mac->mac_phy.rf_onoff(mac, 0); 8265 if (mac->mac_phy.exit != NULL) 8266 mac->mac_phy.exit(mac); 8267} 8268 8269static void 8270bwn_dma_free(struct bwn_mac *mac) 8271{ 8272 struct bwn_dma *dma; 8273 8274 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8275 return; 8276 dma = &mac->mac_method.dma; 8277 8278 bwn_dma_ringfree(&dma->rx); 8279 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8280 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8281 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8282 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8283 bwn_dma_ringfree(&dma->mcast); 8284} 8285 8286static void 8287bwn_core_stop(struct bwn_mac *mac) 8288{ 8289 struct bwn_softc *sc = mac->mac_sc; 8290 8291 BWN_ASSERT_LOCKED(sc); 8292 8293 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8294 return; 8295 8296 callout_stop(&sc->sc_rfswitch_ch); 8297 callout_stop(&sc->sc_task_ch); 8298 callout_stop(&sc->sc_watchdog_ch); 8299 sc->sc_watchdog_timer = 0; 8300 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8301 BWN_READ_4(mac, BWN_INTR_MASK); 8302 bwn_mac_suspend(mac); 8303 8304 mac->mac_status = BWN_MAC_STATUS_INITED; 8305} 8306 8307static int 8308bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8309{ 8310 struct bwn_mac *up_dev = NULL; 8311 struct bwn_mac *down_dev; 8312 struct bwn_mac *mac; 8313 int err, status; 8314 uint8_t gmode; 8315 8316 BWN_ASSERT_LOCKED(sc); 8317 8318 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8319 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8320 mac->mac_phy.supports_2ghz) { 8321 up_dev = mac; 8322 gmode = 1; 8323 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8324 mac->mac_phy.supports_5ghz) { 8325 up_dev = mac; 8326 gmode = 0; 8327 } else { 8328 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8329 return (EINVAL); 8330 } 8331 if (up_dev != NULL) 8332 break; 8333 } 8334 if (up_dev == NULL) { 8335 device_printf(sc->sc_dev, "Could not find a device\n"); 8336 return (ENODEV); 8337 } 8338 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8339 return (0); 8340 8341 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8342 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8343 8344 down_dev = sc->sc_curmac;; 8345 status = down_dev->mac_status; 8346 if (status >= BWN_MAC_STATUS_STARTED) 8347 bwn_core_stop(down_dev); 8348 if (status >= BWN_MAC_STATUS_INITED) 8349 bwn_core_exit(down_dev); 8350 8351 if (down_dev != up_dev) 8352 bwn_phy_reset(down_dev); 8353 8354 up_dev->mac_phy.gmode = gmode; 8355 if (status >= BWN_MAC_STATUS_INITED) { 8356 err = bwn_core_init(up_dev); 8357 if (err) { 8358 device_printf(sc->sc_dev, 8359 "fatal: failed to initialize for %s-GHz\n", 8360 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8361 goto fail; 8362 } 8363 } 8364 if (status >= BWN_MAC_STATUS_STARTED) 8365 bwn_core_start(up_dev); 8366 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8367 sc->sc_curmac = up_dev; 8368 8369 return (0); 8370fail: 8371 sc->sc_curmac = NULL; 8372 return (err); 8373} 8374 8375static void 8376bwn_rf_turnon(struct bwn_mac *mac) 8377{ 8378 8379 bwn_mac_suspend(mac); 8380 mac->mac_phy.rf_onoff(mac, 1); 8381 mac->mac_phy.rf_on = 1; 8382 bwn_mac_enable(mac); 8383} 8384 8385static void 8386bwn_rf_turnoff(struct bwn_mac *mac) 8387{ 8388 8389 bwn_mac_suspend(mac); 8390 mac->mac_phy.rf_onoff(mac, 0); 8391 mac->mac_phy.rf_on = 0; 8392 bwn_mac_enable(mac); 8393} 8394 8395static void 8396bwn_phy_reset(struct bwn_mac *mac) 8397{ 8398 struct siba_dev_softc *sd = mac->mac_sd; 8399 8400 siba_write_4(sd, SIBA_TGSLOW, 8401 ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8402 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8403 DELAY(1000); 8404 siba_write_4(sd, SIBA_TGSLOW, 8405 (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8406 BWN_TGSLOW_PHYRESET); 8407 DELAY(1000); 8408} 8409 8410static int 8411bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8412{ 8413 struct bwn_vap *bvp = BWN_VAP(vap); 8414 struct ieee80211com *ic= vap->iv_ic; 8415 struct ifnet *ifp = ic->ic_ifp; 8416 enum ieee80211_state ostate = vap->iv_state; 8417 struct bwn_softc *sc = ifp->if_softc; 8418 struct bwn_mac *mac = sc->sc_curmac; 8419 int error; 8420 8421 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8422 ieee80211_state_name[vap->iv_state], 8423 ieee80211_state_name[nstate]); 8424 8425 error = bvp->bv_newstate(vap, nstate, arg); 8426 if (error != 0) 8427 return (error); 8428 8429 BWN_LOCK(sc); 8430 8431 bwn_led_newstate(mac, nstate); 8432 8433 /* 8434 * Clear the BSSID when we stop a STA 8435 */ 8436 if (vap->iv_opmode == IEEE80211_M_STA) { 8437 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8438 /* 8439 * Clear out the BSSID. If we reassociate to 8440 * the same AP, this will reinialize things 8441 * correctly... 8442 */ 8443 if (ic->ic_opmode == IEEE80211_M_STA && 8444 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8445 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8446 bwn_set_macaddr(mac); 8447 } 8448 } 8449 } 8450 8451 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8452 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8453 /* XXX nothing to do? */ 8454 } else if (nstate == IEEE80211_S_RUN) { 8455 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8456 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8457 bwn_set_opmode(mac); 8458 bwn_set_pretbtt(mac); 8459 bwn_spu_setdelay(mac, 0); 8460 bwn_set_macaddr(mac); 8461 } 8462 8463 BWN_UNLOCK(sc); 8464 8465 return (error); 8466} 8467 8468static void 8469bwn_set_pretbtt(struct bwn_mac *mac) 8470{ 8471 struct bwn_softc *sc = mac->mac_sc; 8472 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8473 uint16_t pretbtt; 8474 8475 if (ic->ic_opmode == IEEE80211_M_IBSS) 8476 pretbtt = 2; 8477 else 8478 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8479 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8480 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8481} 8482 8483static int 8484bwn_intr(void *arg) 8485{ 8486 struct bwn_mac *mac = arg; 8487 struct bwn_softc *sc = mac->mac_sc; 8488 struct siba_softc *siba = mac->mac_sd->sd_bus; 8489 uint32_t reason; 8490 8491 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) 8492 return (FILTER_STRAY); 8493 8494 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8495 if (reason == 0xffffffff) /* shared IRQ */ 8496 return (FILTER_STRAY); 8497 reason &= mac->mac_intr_mask; 8498 if (reason == 0) 8499 return (FILTER_HANDLED); 8500 8501 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8502 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8503 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8504 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8505 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8506 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8507 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8508 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8509 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8510 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8511 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8512 8513 /* Disable interrupts. */ 8514 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8515 8516 mac->mac_reason_intr = reason; 8517 8518 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8519 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8520 8521 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8522 return (FILTER_HANDLED); 8523} 8524 8525static void 8526bwn_intrtask(void *arg, int npending) 8527{ 8528 struct bwn_mac *mac = arg; 8529 struct bwn_softc *sc = mac->mac_sc; 8530 struct ifnet *ifp = sc->sc_ifp; 8531 struct siba_softc *siba = mac->mac_sd->sd_bus; 8532 uint32_t merged = 0; 8533 int i, tx = 0, rx = 0; 8534 8535 BWN_LOCK(sc); 8536 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) { 8537 BWN_UNLOCK(sc); 8538 return; 8539 } 8540 8541 for (i = 0; i < N(mac->mac_reason); i++) 8542 merged |= mac->mac_reason[i]; 8543 8544 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8545 device_printf(sc->sc_dev, "MAC trans error\n"); 8546 8547 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8548 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8549 mac->mac_phy.txerrors--; 8550 if (mac->mac_phy.txerrors == 0) { 8551 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8552 bwn_restart(mac, "PHY TX errors"); 8553 } 8554 } 8555 8556 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8557 if (merged & BWN_DMAINTR_FATALMASK) { 8558 device_printf(sc->sc_dev, 8559 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8560 mac->mac_reason[0], mac->mac_reason[1], 8561 mac->mac_reason[2], mac->mac_reason[3], 8562 mac->mac_reason[4], mac->mac_reason[5]); 8563 bwn_restart(mac, "DMA error"); 8564 BWN_UNLOCK(sc); 8565 return; 8566 } 8567 if (merged & BWN_DMAINTR_NONFATALMASK) { 8568 device_printf(sc->sc_dev, 8569 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8570 mac->mac_reason[0], mac->mac_reason[1], 8571 mac->mac_reason[2], mac->mac_reason[3], 8572 mac->mac_reason[4], mac->mac_reason[5]); 8573 } 8574 } 8575 8576 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8577 bwn_intr_ucode_debug(mac); 8578 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8579 bwn_intr_tbtt_indication(mac); 8580 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8581 bwn_intr_atim_end(mac); 8582 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8583 bwn_intr_beacon(mac); 8584 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8585 bwn_intr_pmq(mac); 8586 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8587 bwn_intr_noise(mac); 8588 8589 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8590 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8591 bwn_dma_rx(mac->mac_method.dma.rx); 8592 rx = 1; 8593 } 8594 } else 8595 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8596 8597 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8598 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8599 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8600 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8601 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8602 8603 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8604 bwn_intr_txeof(mac); 8605 tx = 1; 8606 } 8607 8608 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8609 8610 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8611 int evt = BWN_LED_EVENT_NONE; 8612 8613 if (tx && rx) { 8614 if (sc->sc_rx_rate > sc->sc_tx_rate) 8615 evt = BWN_LED_EVENT_RX; 8616 else 8617 evt = BWN_LED_EVENT_TX; 8618 } else if (tx) { 8619 evt = BWN_LED_EVENT_TX; 8620 } else if (rx) { 8621 evt = BWN_LED_EVENT_RX; 8622 } else if (rx == 0) { 8623 evt = BWN_LED_EVENT_POLL; 8624 } 8625 8626 if (evt != BWN_LED_EVENT_NONE) 8627 bwn_led_event(mac, evt); 8628 } 8629 8630 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8631 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8632 bwn_start_locked(ifp); 8633 } 8634 8635 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8636 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8637 8638 BWN_UNLOCK(sc); 8639} 8640 8641static void 8642bwn_restart(struct bwn_mac *mac, const char *msg) 8643{ 8644 struct bwn_softc *sc = mac->mac_sc; 8645 struct ifnet *ifp = sc->sc_ifp; 8646 struct ieee80211com *ic = ifp->if_l2com; 8647 8648 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8649 return; 8650 8651 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8652 ieee80211_runtask(ic, &mac->mac_hwreset); 8653} 8654 8655static void 8656bwn_intr_ucode_debug(struct bwn_mac *mac) 8657{ 8658 struct bwn_softc *sc = mac->mac_sc; 8659 uint16_t reason; 8660 8661 if (mac->mac_fw.opensource == 0) 8662 return; 8663 8664 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8665 switch (reason) { 8666 case BWN_DEBUGINTR_PANIC: 8667 bwn_handle_fwpanic(mac); 8668 break; 8669 case BWN_DEBUGINTR_DUMP_SHM: 8670 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8671 break; 8672 case BWN_DEBUGINTR_DUMP_REGS: 8673 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8674 break; 8675 case BWN_DEBUGINTR_MARKER: 8676 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8677 break; 8678 default: 8679 device_printf(sc->sc_dev, 8680 "ucode debug unknown reason: %#x\n", reason); 8681 } 8682 8683 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8684 BWN_DEBUGINTR_ACK); 8685} 8686 8687static void 8688bwn_intr_tbtt_indication(struct bwn_mac *mac) 8689{ 8690 struct bwn_softc *sc = mac->mac_sc; 8691 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8692 8693 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8694 bwn_psctl(mac, 0); 8695 if (ic->ic_opmode == IEEE80211_M_IBSS) 8696 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8697} 8698 8699static void 8700bwn_intr_atim_end(struct bwn_mac *mac) 8701{ 8702 8703 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8704 BWN_WRITE_4(mac, BWN_MACCMD, 8705 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8706 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8707 } 8708} 8709 8710static void 8711bwn_intr_beacon(struct bwn_mac *mac) 8712{ 8713 struct bwn_softc *sc = mac->mac_sc; 8714 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8715 uint32_t cmd, beacon0, beacon1; 8716 8717 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8718 ic->ic_opmode == IEEE80211_M_MBSS) 8719 return; 8720 8721 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8722 8723 cmd = BWN_READ_4(mac, BWN_MACCMD); 8724 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8725 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8726 8727 if (beacon0 && beacon1) { 8728 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8729 mac->mac_intr_mask |= BWN_INTR_BEACON; 8730 return; 8731 } 8732 8733 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8734 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8735 bwn_load_beacon0(mac); 8736 bwn_load_beacon1(mac); 8737 cmd = BWN_READ_4(mac, BWN_MACCMD); 8738 cmd |= BWN_MACCMD_BEACON0_VALID; 8739 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8740 } else { 8741 if (!beacon0) { 8742 bwn_load_beacon0(mac); 8743 cmd = BWN_READ_4(mac, BWN_MACCMD); 8744 cmd |= BWN_MACCMD_BEACON0_VALID; 8745 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8746 } else if (!beacon1) { 8747 bwn_load_beacon1(mac); 8748 cmd = BWN_READ_4(mac, BWN_MACCMD); 8749 cmd |= BWN_MACCMD_BEACON1_VALID; 8750 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8751 } 8752 } 8753} 8754 8755static void 8756bwn_intr_pmq(struct bwn_mac *mac) 8757{ 8758 uint32_t tmp; 8759 8760 while (1) { 8761 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8762 if (!(tmp & 0x00000008)) 8763 break; 8764 } 8765 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8766} 8767 8768static void 8769bwn_intr_noise(struct bwn_mac *mac) 8770{ 8771 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8772 uint16_t tmp; 8773 uint8_t noise[4]; 8774 uint8_t i, j; 8775 int32_t average; 8776 8777 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8778 return; 8779 8780 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8781 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8782 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8783 noise[3] == 0x7f) 8784 goto new; 8785 8786 KASSERT(mac->mac_noise.noi_nsamples < 8, 8787 ("%s:%d: fail", __func__, __LINE__)); 8788 i = mac->mac_noise.noi_nsamples; 8789 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8790 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8791 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8792 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8793 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8794 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8795 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8796 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8797 mac->mac_noise.noi_nsamples++; 8798 if (mac->mac_noise.noi_nsamples == 8) { 8799 average = 0; 8800 for (i = 0; i < 8; i++) { 8801 for (j = 0; j < 4; j++) 8802 average += mac->mac_noise.noi_samples[i][j]; 8803 } 8804 average = (((average / 32) * 125) + 64) / 128; 8805 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8806 if (tmp >= 8) 8807 average += 2; 8808 else 8809 average -= 25; 8810 average -= (tmp == 8) ? 72 : 48; 8811 8812 mac->mac_stats.link_noise = average; 8813 mac->mac_noise.noi_running = 0; 8814 return; 8815 } 8816new: 8817 bwn_noise_gensample(mac); 8818} 8819 8820static int 8821bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8822{ 8823 struct bwn_mac *mac = prq->prq_mac; 8824 struct bwn_softc *sc = mac->mac_sc; 8825 unsigned int i; 8826 8827 BWN_ASSERT_LOCKED(sc); 8828 8829 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8830 return (0); 8831 8832 for (i = 0; i < 5000; i++) { 8833 if (bwn_pio_rxeof(prq) == 0) 8834 break; 8835 } 8836 if (i >= 5000) 8837 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8838 return ((i > 0) ? 1 : 0); 8839} 8840 8841static void 8842bwn_dma_rx(struct bwn_dma_ring *dr) 8843{ 8844 int slot, curslot; 8845 8846 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8847 curslot = dr->get_curslot(dr); 8848 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8849 ("%s:%d: fail", __func__, __LINE__)); 8850 8851 slot = dr->dr_curslot; 8852 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8853 bwn_dma_rxeof(dr, &slot); 8854 8855 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8856 BUS_DMASYNC_PREWRITE); 8857 8858 dr->set_curslot(dr, slot); 8859 dr->dr_curslot = slot; 8860} 8861 8862static void 8863bwn_intr_txeof(struct bwn_mac *mac) 8864{ 8865 struct bwn_txstatus stat; 8866 uint32_t stat0, stat1; 8867 uint16_t tmp; 8868 8869 BWN_ASSERT_LOCKED(mac->mac_sc); 8870 8871 while (1) { 8872 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8873 if (!(stat0 & 0x00000001)) 8874 break; 8875 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8876 8877 stat.cookie = (stat0 >> 16); 8878 stat.seq = (stat1 & 0x0000ffff); 8879 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8880 tmp = (stat0 & 0x0000ffff); 8881 stat.framecnt = ((tmp & 0xf000) >> 12); 8882 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8883 stat.sreason = ((tmp & 0x001c) >> 2); 8884 stat.pm = (tmp & 0x0080) ? 1 : 0; 8885 stat.im = (tmp & 0x0040) ? 1 : 0; 8886 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8887 stat.ack = (tmp & 0x0002) ? 1 : 0; 8888 8889 bwn_handle_txeof(mac, &stat); 8890 } 8891} 8892 8893static void 8894bwn_hwreset(void *arg, int npending) 8895{ 8896 struct bwn_mac *mac = arg; 8897 struct bwn_softc *sc = mac->mac_sc; 8898 int error = 0; 8899 int prev_status; 8900 8901 BWN_LOCK(sc); 8902 8903 prev_status = mac->mac_status; 8904 if (prev_status >= BWN_MAC_STATUS_STARTED) 8905 bwn_core_stop(mac); 8906 if (prev_status >= BWN_MAC_STATUS_INITED) 8907 bwn_core_exit(mac); 8908 8909 if (prev_status >= BWN_MAC_STATUS_INITED) { 8910 error = bwn_core_init(mac); 8911 if (error) 8912 goto out; 8913 } 8914 if (prev_status >= BWN_MAC_STATUS_STARTED) 8915 bwn_core_start(mac); 8916out: 8917 if (error) { 8918 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8919 sc->sc_curmac = NULL; 8920 } 8921 BWN_UNLOCK(sc); 8922} 8923 8924static void 8925bwn_handle_fwpanic(struct bwn_mac *mac) 8926{ 8927 struct bwn_softc *sc = mac->mac_sc; 8928 uint16_t reason; 8929 8930 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8931 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8932 8933 if (reason == BWN_FWPANIC_RESTART) 8934 bwn_restart(mac, "ucode panic"); 8935} 8936 8937static void 8938bwn_load_beacon0(struct bwn_mac *mac) 8939{ 8940 8941 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8942} 8943 8944static void 8945bwn_load_beacon1(struct bwn_mac *mac) 8946{ 8947 8948 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8949} 8950 8951static uint32_t 8952bwn_jssi_read(struct bwn_mac *mac) 8953{ 8954 uint32_t val = 0; 8955 8956 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8957 val <<= 16; 8958 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8959 8960 return (val); 8961} 8962 8963static void 8964bwn_noise_gensample(struct bwn_mac *mac) 8965{ 8966 uint32_t jssi = 0x7f7f7f7f; 8967 8968 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8969 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8970 BWN_WRITE_4(mac, BWN_MACCMD, 8971 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8972} 8973 8974static int 8975bwn_dma_freeslot(struct bwn_dma_ring *dr) 8976{ 8977 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8978 8979 return (dr->dr_numslots - dr->dr_usedslot); 8980} 8981 8982static int 8983bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8984{ 8985 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8986 8987 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8988 ("%s:%d: fail", __func__, __LINE__)); 8989 if (slot == dr->dr_numslots - 1) 8990 return (0); 8991 return (slot + 1); 8992} 8993 8994static void 8995bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8996{ 8997 struct bwn_mac *mac = dr->dr_mac; 8998 struct bwn_softc *sc = mac->mac_sc; 8999 struct bwn_dma *dma = &mac->mac_method.dma; 9000 struct bwn_dmadesc_generic *desc; 9001 struct bwn_dmadesc_meta *meta; 9002 struct bwn_rxhdr4 *rxhdr; 9003 struct ifnet *ifp = sc->sc_ifp; 9004 struct mbuf *m; 9005 uint32_t macstat; 9006 int32_t tmp; 9007 int cnt = 0; 9008 uint16_t len; 9009 9010 dr->getdesc(dr, *slot, &desc, &meta); 9011 9012 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 9013 m = meta->mt_m; 9014 9015 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 9016 ifp->if_ierrors++; 9017 return; 9018 } 9019 9020 rxhdr = mtod(m, struct bwn_rxhdr4 *); 9021 len = le16toh(rxhdr->frame_len); 9022 if (len <= 0) { 9023 ifp->if_ierrors++; 9024 return; 9025 } 9026 if (bwn_dma_check_redzone(dr, m)) { 9027 device_printf(sc->sc_dev, "redzone error.\n"); 9028 bwn_dma_set_redzone(dr, m); 9029 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9030 BUS_DMASYNC_PREWRITE); 9031 return; 9032 } 9033 if (len > dr->dr_rx_bufsize) { 9034 tmp = len; 9035 while (1) { 9036 dr->getdesc(dr, *slot, &desc, &meta); 9037 bwn_dma_set_redzone(dr, meta->mt_m); 9038 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9039 BUS_DMASYNC_PREWRITE); 9040 *slot = bwn_dma_nextslot(dr, *slot); 9041 cnt++; 9042 tmp -= dr->dr_rx_bufsize; 9043 if (tmp <= 0) 9044 break; 9045 } 9046 device_printf(sc->sc_dev, "too small buffer " 9047 "(len %u buffer %u dropped %d)\n", 9048 len, dr->dr_rx_bufsize, cnt); 9049 return; 9050 } 9051 macstat = le32toh(rxhdr->mac_status); 9052 if (macstat & BWN_RX_MAC_FCSERR) { 9053 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9054 device_printf(sc->sc_dev, "RX drop\n"); 9055 return; 9056 } 9057 } 9058 9059 m->m_pkthdr.rcvif = ifp; 9060 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 9061 m_adj(m, dr->dr_frameoffset); 9062 9063 bwn_rxeof(dr->dr_mac, m, rxhdr); 9064} 9065 9066static void 9067bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 9068{ 9069 struct bwn_dma_ring *dr; 9070 struct bwn_dmadesc_generic *desc; 9071 struct bwn_dmadesc_meta *meta; 9072 struct bwn_node *bn; 9073 struct bwn_pio_txqueue *tq; 9074 struct bwn_pio_txpkt *tp = NULL; 9075 struct bwn_softc *sc = mac->mac_sc; 9076 struct bwn_stats *stats = &mac->mac_stats; 9077 struct ieee80211_node *ni; 9078 int slot; 9079 9080 BWN_ASSERT_LOCKED(mac->mac_sc); 9081 9082 if (status->im) 9083 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9084 if (status->ampdu) 9085 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9086 if (status->rtscnt) { 9087 if (status->rtscnt == 0xf) 9088 stats->rtsfail++; 9089 else 9090 stats->rts++; 9091 } 9092 9093 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9094 if (status->ack) { 9095 dr = bwn_dma_parse_cookie(mac, status, 9096 status->cookie, &slot); 9097 if (dr == NULL) { 9098 device_printf(sc->sc_dev, 9099 "failed to parse cookie\n"); 9100 return; 9101 } 9102 while (1) { 9103 dr->getdesc(dr, slot, &desc, &meta); 9104 if (meta->mt_islast) { 9105 ni = meta->mt_ni; 9106 bn = (struct bwn_node *)ni; 9107 ieee80211_amrr_tx_complete(&bn->bn_amn, 9108 status->ack, 0); 9109 break; 9110 } 9111 slot = bwn_dma_nextslot(dr, slot); 9112 } 9113 } 9114 bwn_dma_handle_txeof(mac, status); 9115 } else { 9116 if (status->ack) { 9117 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9118 if (tq == NULL) { 9119 device_printf(sc->sc_dev, 9120 "failed to parse cookie\n"); 9121 return; 9122 } 9123 ni = tp->tp_ni; 9124 bn = (struct bwn_node *)ni; 9125 ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0); 9126 } 9127 bwn_pio_handle_txeof(mac, status); 9128 } 9129 9130 bwn_phy_txpower_check(mac, 0); 9131} 9132 9133static uint8_t 9134bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9135{ 9136 struct bwn_mac *mac = prq->prq_mac; 9137 struct bwn_softc *sc = mac->mac_sc; 9138 struct bwn_rxhdr4 rxhdr; 9139 struct ifnet *ifp = sc->sc_ifp; 9140 struct mbuf *m; 9141 uint32_t ctl32, macstat, v32; 9142 unsigned int i, padding; 9143 uint16_t ctl16, len, v16; 9144 unsigned char *mp; 9145 char *data; 9146 9147 memset(&rxhdr, 0, sizeof(rxhdr)); 9148 9149 if (prq->prq_rev >= 8) { 9150 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9151 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9152 return (0); 9153 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9154 BWN_PIO8_RXCTL_FRAMEREADY); 9155 for (i = 0; i < 10; i++) { 9156 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9157 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9158 goto ready; 9159 DELAY(10); 9160 } 9161 } else { 9162 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9163 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9164 return (0); 9165 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9166 BWN_PIO_RXCTL_FRAMEREADY); 9167 for (i = 0; i < 10; i++) { 9168 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9169 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9170 goto ready; 9171 DELAY(10); 9172 } 9173 } 9174 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9175 return (1); 9176ready: 9177 if (prq->prq_rev >= 8) 9178 siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9179 prq->prq_base + BWN_PIO8_RXDATA); 9180 else 9181 siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9182 prq->prq_base + BWN_PIO_RXDATA); 9183 len = le16toh(rxhdr.frame_len); 9184 if (len > 0x700) { 9185 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9186 goto error; 9187 } 9188 if (len == 0) { 9189 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9190 goto error; 9191 } 9192 9193 macstat = le32toh(rxhdr.mac_status); 9194 if (macstat & BWN_RX_MAC_FCSERR) { 9195 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9196 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9197 goto error; 9198 } 9199 } 9200 9201 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9202 KASSERT(len + padding <= MCLBYTES, ("too big..\n")); 9203 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9204 if (m == NULL) { 9205 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9206 goto error; 9207 } 9208 mp = mtod(m, unsigned char *); 9209 if (prq->prq_rev >= 8) { 9210 siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3), 9211 prq->prq_base + BWN_PIO8_RXDATA); 9212 if (len & 3) { 9213 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9214 data = &(mp[len + padding - 1]); 9215 switch (len & 3) { 9216 case 3: 9217 *data = (v32 >> 16); 9218 data--; 9219 case 2: 9220 *data = (v32 >> 8); 9221 data--; 9222 case 1: 9223 *data = v32; 9224 } 9225 } 9226 } else { 9227 siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1), 9228 prq->prq_base + BWN_PIO_RXDATA); 9229 if (len & 1) { 9230 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9231 mp[len + padding - 1] = v16; 9232 } 9233 } 9234 9235 m->m_pkthdr.rcvif = ifp; 9236 m->m_len = m->m_pkthdr.len = len + padding; 9237 9238 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9239 9240 return (1); 9241error: 9242 if (prq->prq_rev >= 8) 9243 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9244 BWN_PIO8_RXCTL_DATAREADY); 9245 else 9246 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9247 return (1); 9248} 9249 9250static int 9251bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9252 struct bwn_dmadesc_meta *meta, int init) 9253{ 9254 struct bwn_mac *mac = dr->dr_mac; 9255 struct bwn_dma *dma = &mac->mac_method.dma; 9256 struct bwn_rxhdr4 *hdr; 9257 bus_dmamap_t map; 9258 bus_addr_t paddr; 9259 struct mbuf *m; 9260 int error; 9261 9262 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9263 if (m == NULL) { 9264 error = ENOBUFS; 9265 9266 /* 9267 * If the NIC is up and running, we need to: 9268 * - Clear RX buffer's header. 9269 * - Restore RX descriptor settings. 9270 */ 9271 if (init) 9272 return (error); 9273 else 9274 goto back; 9275 } 9276 m->m_len = m->m_pkthdr.len = MCLBYTES; 9277 9278 bwn_dma_set_redzone(dr, m); 9279 9280 /* 9281 * Try to load RX buf into temporary DMA map 9282 */ 9283 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9284 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9285 if (error) { 9286 m_freem(m); 9287 9288 /* 9289 * See the comment above 9290 */ 9291 if (init) 9292 return (error); 9293 else 9294 goto back; 9295 } 9296 9297 if (!init) 9298 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9299 meta->mt_m = m; 9300 meta->mt_paddr = paddr; 9301 9302 /* 9303 * Swap RX buf's DMA map with the loaded temporary one 9304 */ 9305 map = meta->mt_dmap; 9306 meta->mt_dmap = dr->dr_spare_dmap; 9307 dr->dr_spare_dmap = map; 9308 9309back: 9310 /* 9311 * Clear RX buf header 9312 */ 9313 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9314 bzero(hdr, sizeof(*hdr)); 9315 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9316 BUS_DMASYNC_PREWRITE); 9317 9318 /* 9319 * Setup RX buf descriptor 9320 */ 9321 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9322 sizeof(*hdr), 0, 0, 0); 9323 return (error); 9324} 9325 9326static void 9327bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9328 bus_size_t mapsz __unused, int error) 9329{ 9330 9331 if (!error) { 9332 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9333 *((bus_addr_t *)arg) = seg->ds_addr; 9334 } 9335} 9336 9337static int 9338bwn_hwrate2ieeerate(int rate) 9339{ 9340 9341 switch (rate) { 9342 case BWN_CCK_RATE_1MB: 9343 return (2); 9344 case BWN_CCK_RATE_2MB: 9345 return (4); 9346 case BWN_CCK_RATE_5MB: 9347 return (11); 9348 case BWN_CCK_RATE_11MB: 9349 return (22); 9350 case BWN_OFDM_RATE_6MB: 9351 return (12); 9352 case BWN_OFDM_RATE_9MB: 9353 return (18); 9354 case BWN_OFDM_RATE_12MB: 9355 return (24); 9356 case BWN_OFDM_RATE_18MB: 9357 return (36); 9358 case BWN_OFDM_RATE_24MB: 9359 return (48); 9360 case BWN_OFDM_RATE_36MB: 9361 return (72); 9362 case BWN_OFDM_RATE_48MB: 9363 return (96); 9364 case BWN_OFDM_RATE_54MB: 9365 return (108); 9366 default: 9367 printf("Ooops\n"); 9368 return (0); 9369 } 9370} 9371 9372static void 9373bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9374{ 9375 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9376 struct bwn_plcp6 *plcp; 9377 struct bwn_softc *sc = mac->mac_sc; 9378 struct ieee80211_frame_min *wh; 9379 struct ieee80211_node *ni; 9380 struct ifnet *ifp = sc->sc_ifp; 9381 struct ieee80211com *ic = ifp->if_l2com; 9382 uint32_t macstat; 9383 int padding, rate, rssi = 0, noise = 0, type; 9384 uint16_t phytype, phystat0, phystat3, chanstat; 9385 unsigned char *mp = mtod(m, unsigned char *); 9386 static int rx_mac_dec_rpt = 0; 9387 9388 BWN_ASSERT_LOCKED(sc); 9389 9390 phystat0 = le16toh(rxhdr->phy_status0); 9391 phystat3 = le16toh(rxhdr->phy_status3); 9392 macstat = le32toh(rxhdr->mac_status); 9393 chanstat = le16toh(rxhdr->channel); 9394 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9395 9396 if (macstat & BWN_RX_MAC_FCSERR) 9397 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9398 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9399 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9400 if (macstat & BWN_RX_MAC_DECERR) 9401 goto drop; 9402 9403 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9404 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9405 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9406 m->m_pkthdr.len); 9407 goto drop; 9408 } 9409 plcp = (struct bwn_plcp6 *)(mp + padding); 9410 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9411 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9412 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9413 m->m_pkthdr.len); 9414 goto drop; 9415 } 9416 wh = mtod(m, struct ieee80211_frame_min *); 9417 9418 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9419 device_printf(sc->sc_dev, 9420 "RX decryption attempted (old %d keyidx %#x)\n", 9421 BWN_ISOLDFMT(mac), 9422 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9423 9424 /* XXX calculating RSSI & noise & antenna */ 9425 9426 if (phystat0 & BWN_RX_PHYST0_OFDM) 9427 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9428 phytype == BWN_PHYTYPE_A); 9429 else 9430 rate = bwn_plcp_get_cckrate(mac, plcp); 9431 if (rate == -1) { 9432 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9433 goto drop; 9434 } 9435 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9436 9437 /* RX radio tap */ 9438 if (ieee80211_radiotap_active(ic)) 9439 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9440 m_adj(m, -IEEE80211_CRC_LEN); 9441 9442 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9443 noise = mac->mac_stats.link_noise; 9444 9445 BWN_UNLOCK(sc); 9446 9447 ni = ieee80211_find_rxnode(ic, wh); 9448 if (ni != NULL) { 9449 type = ieee80211_input(ni, m, rssi, noise); 9450 ieee80211_free_node(ni); 9451 } else 9452 type = ieee80211_input_all(ic, m, rssi, noise); 9453 9454 BWN_LOCK(sc); 9455 return; 9456drop: 9457 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9458} 9459 9460static void 9461bwn_dma_handle_txeof(struct bwn_mac *mac, 9462 const struct bwn_txstatus *status) 9463{ 9464 struct bwn_dma *dma = &mac->mac_method.dma; 9465 struct bwn_dma_ring *dr; 9466 struct bwn_dmadesc_generic *desc; 9467 struct bwn_dmadesc_meta *meta; 9468 struct bwn_softc *sc = mac->mac_sc; 9469 struct ieee80211_node *ni; 9470 struct ifnet *ifp = sc->sc_ifp; 9471 struct mbuf *m; 9472 int slot; 9473 9474 BWN_ASSERT_LOCKED(sc); 9475 9476 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9477 if (dr == NULL) { 9478 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9479 return; 9480 } 9481 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9482 9483 while (1) { 9484 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9485 ("%s:%d: fail", __func__, __LINE__)); 9486 dr->getdesc(dr, slot, &desc, &meta); 9487 9488 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9489 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9490 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9491 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9492 9493 if (meta->mt_islast) { 9494 KASSERT(meta->mt_m != NULL, 9495 ("%s:%d: fail", __func__, __LINE__)); 9496 9497 ni = meta->mt_ni; 9498 m = meta->mt_m; 9499 if (ni != NULL) { 9500 /* 9501 * Do any tx complete callback. Note this must 9502 * be done before releasing the node reference. 9503 */ 9504 if (m->m_flags & M_TXCB) 9505 ieee80211_process_callback(ni, m, 0); 9506 ieee80211_free_node(ni); 9507 meta->mt_ni = NULL; 9508 } 9509 m_freem(m); 9510 meta->mt_m = NULL; 9511 } else { 9512 KASSERT(meta->mt_m == NULL, 9513 ("%s:%d: fail", __func__, __LINE__)); 9514 } 9515 9516 dr->dr_usedslot--; 9517 if (meta->mt_islast) { 9518 ifp->if_opackets++; 9519 break; 9520 } 9521 slot = bwn_dma_nextslot(dr, slot); 9522 } 9523 sc->sc_watchdog_timer = 0; 9524 if (dr->dr_stop) { 9525 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9526 ("%s:%d: fail", __func__, __LINE__)); 9527 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9528 dr->dr_stop = 0; 9529 } 9530} 9531 9532static void 9533bwn_pio_handle_txeof(struct bwn_mac *mac, 9534 const struct bwn_txstatus *status) 9535{ 9536 struct bwn_pio_txqueue *tq; 9537 struct bwn_pio_txpkt *tp = NULL; 9538 struct bwn_softc *sc = mac->mac_sc; 9539 struct ifnet *ifp = sc->sc_ifp; 9540 9541 BWN_ASSERT_LOCKED(sc); 9542 9543 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9544 if (tq == NULL) 9545 return; 9546 9547 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9548 tq->tq_free++; 9549 9550 if (tp->tp_ni != NULL) { 9551 /* 9552 * Do any tx complete callback. Note this must 9553 * be done before releasing the node reference. 9554 */ 9555 if (tp->tp_m->m_flags & M_TXCB) 9556 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9557 ieee80211_free_node(tp->tp_ni); 9558 tp->tp_ni = NULL; 9559 } 9560 m_freem(tp->tp_m); 9561 tp->tp_m = NULL; 9562 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9563 9564 ifp->if_opackets++; 9565 9566 sc->sc_watchdog_timer = 0; 9567 if (tq->tq_stop) { 9568 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9569 tq->tq_stop = 0; 9570 } 9571} 9572 9573static void 9574bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9575{ 9576 struct bwn_softc *sc = mac->mac_sc; 9577 struct bwn_phy *phy = &mac->mac_phy; 9578 struct ifnet *ifp = sc->sc_ifp; 9579 struct ieee80211com *ic = ifp->if_l2com; 9580 struct siba_softc *siba = mac->mac_sd->sd_bus; 9581 unsigned long now; 9582 int result; 9583 9584 BWN_GETTIME(now); 9585 9586 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9587 return; 9588 phy->nexttime = now + 2 * 1000; 9589 9590 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 9591 siba->siba_board_type == SIBA_BOARD_BU4306) 9592 return; 9593 9594 if (phy->recalc_txpwr != NULL) { 9595 result = phy->recalc_txpwr(mac, 9596 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9597 if (result == BWN_TXPWR_RES_DONE) 9598 return; 9599 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9600 ("%s: fail", __func__)); 9601 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9602 9603 ieee80211_runtask(ic, &mac->mac_txpower); 9604 } 9605} 9606 9607static uint16_t 9608bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9609{ 9610 9611 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9612} 9613 9614static uint32_t 9615bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9616{ 9617 9618 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9619} 9620 9621static void 9622bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9623{ 9624 9625 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9626} 9627 9628static void 9629bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9630{ 9631 9632 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9633} 9634 9635static int 9636bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9637{ 9638 9639 switch (rate) { 9640 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9641 case 12: 9642 return (BWN_OFDM_RATE_6MB); 9643 case 18: 9644 return (BWN_OFDM_RATE_9MB); 9645 case 24: 9646 return (BWN_OFDM_RATE_12MB); 9647 case 36: 9648 return (BWN_OFDM_RATE_18MB); 9649 case 48: 9650 return (BWN_OFDM_RATE_24MB); 9651 case 72: 9652 return (BWN_OFDM_RATE_36MB); 9653 case 96: 9654 return (BWN_OFDM_RATE_48MB); 9655 case 108: 9656 return (BWN_OFDM_RATE_54MB); 9657 /* CCK rates (NB: not IEEE std, device-specific) */ 9658 case 2: 9659 return (BWN_CCK_RATE_1MB); 9660 case 4: 9661 return (BWN_CCK_RATE_2MB); 9662 case 11: 9663 return (BWN_CCK_RATE_5MB); 9664 case 22: 9665 return (BWN_CCK_RATE_11MB); 9666 } 9667 9668 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9669 return (BWN_CCK_RATE_1MB); 9670} 9671 9672static int 9673bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9674 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9675{ 9676 const struct bwn_phy *phy = &mac->mac_phy; 9677 struct bwn_softc *sc = mac->mac_sc; 9678 struct ieee80211_frame *wh; 9679 struct ieee80211_frame *protwh; 9680 struct ieee80211_frame_cts *cts; 9681 struct ieee80211_frame_rts *rts; 9682 const struct ieee80211_txparam *tp; 9683 struct ieee80211vap *vap = ni->ni_vap; 9684 struct ifnet *ifp = sc->sc_ifp; 9685 struct ieee80211com *ic = ifp->if_l2com; 9686 struct mbuf *mprot; 9687 unsigned int len; 9688 uint32_t macctl = 0; 9689 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9690 uint16_t phyctl = 0; 9691 uint8_t rate, rate_fb; 9692 9693 wh = mtod(m, struct ieee80211_frame *); 9694 memset(txhdr, 0, sizeof(*txhdr)); 9695 9696 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9697 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9698 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9699 9700 /* 9701 * Find TX rate 9702 */ 9703 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9704 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9705 rate = rate_fb = tp->mgmtrate; 9706 else if (ismcast) 9707 rate = rate_fb = tp->mcastrate; 9708 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9709 rate = rate_fb = tp->ucastrate; 9710 else { 9711 rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn); 9712 rate = ni->ni_txrate; 9713 9714 if (rix > 0) 9715 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9716 IEEE80211_RATE_VAL; 9717 else 9718 rate_fb = rate; 9719 } 9720 9721 sc->sc_tx_rate = rate; 9722 9723 rate = bwn_ieeerate2hwrate(sc, rate); 9724 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9725 9726 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9727 bwn_plcp_getcck(rate); 9728 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9729 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9730 9731 if ((rate_fb == rate) || 9732 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9733 (*(u_int16_t *)wh->i_dur == htole16(0))) 9734 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9735 else 9736 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9737 m->m_pkthdr.len, rate, isshort); 9738 9739 /* XXX TX encryption */ 9740 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9741 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9742 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9743 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9744 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9745 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9746 9747 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9748 BWN_TX_EFT_FB_CCK; 9749 txhdr->chan = phy->chan; 9750 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9751 BWN_TX_PHY_ENC_CCK; 9752 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9753 rate == BWN_CCK_RATE_11MB)) 9754 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9755 9756 /* XXX TX antenna selection */ 9757 9758 switch (bwn_antenna_sanitize(mac, 0)) { 9759 case 0: 9760 phyctl |= BWN_TX_PHY_ANT01AUTO; 9761 break; 9762 case 1: 9763 phyctl |= BWN_TX_PHY_ANT0; 9764 break; 9765 case 2: 9766 phyctl |= BWN_TX_PHY_ANT1; 9767 break; 9768 case 3: 9769 phyctl |= BWN_TX_PHY_ANT2; 9770 break; 9771 case 4: 9772 phyctl |= BWN_TX_PHY_ANT3; 9773 break; 9774 default: 9775 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9776 } 9777 9778 if (!ismcast) 9779 macctl |= BWN_TX_MAC_ACK; 9780 9781 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9782 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9783 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9784 macctl |= BWN_TX_MAC_LONGFRAME; 9785 9786 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9787 /* XXX RTS rate is always 1MB??? */ 9788 rts_rate = BWN_CCK_RATE_1MB; 9789 rts_rate_fb = bwn_get_fbrate(rts_rate); 9790 9791 protdur = ieee80211_compute_duration(ic->ic_rt, 9792 m->m_pkthdr.len, rate, isshort) + 9793 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9794 9795 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9796 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9797 (txhdr->body.old.rts_frame) : 9798 (txhdr->body.new.rts_frame)); 9799 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9800 protdur); 9801 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9802 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9803 mprot->m_pkthdr.len); 9804 m_freem(mprot); 9805 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9806 len = sizeof(struct ieee80211_frame_cts); 9807 } else { 9808 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9809 (txhdr->body.old.rts_frame) : 9810 (txhdr->body.new.rts_frame)); 9811 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9812 isshort); 9813 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9814 wh->i_addr2, protdur); 9815 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9816 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9817 mprot->m_pkthdr.len); 9818 m_freem(mprot); 9819 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9820 len = sizeof(struct ieee80211_frame_rts); 9821 } 9822 len += IEEE80211_CRC_LEN; 9823 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9824 &txhdr->body.old.rts_plcp : 9825 &txhdr->body.new.rts_plcp), len, rts_rate); 9826 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9827 rts_rate_fb); 9828 9829 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9830 (&txhdr->body.old.rts_frame) : 9831 (&txhdr->body.new.rts_frame)); 9832 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9833 9834 if (BWN_ISOFDMRATE(rts_rate)) { 9835 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9836 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9837 } else { 9838 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9839 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9840 } 9841 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9842 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9843 } 9844 9845 if (BWN_ISOLDFMT(mac)) 9846 txhdr->body.old.cookie = htole16(cookie); 9847 else 9848 txhdr->body.new.cookie = htole16(cookie); 9849 9850 txhdr->macctl = htole32(macctl); 9851 txhdr->phyctl = htole16(phyctl); 9852 9853 /* 9854 * TX radio tap 9855 */ 9856 if (ieee80211_radiotap_active_vap(vap)) { 9857 sc->sc_tx_th.wt_flags = 0; 9858 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9859 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9860 if (isshort && 9861 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9862 rate == BWN_CCK_RATE_11MB)) 9863 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9864 sc->sc_tx_th.wt_rate = rate; 9865 9866 ieee80211_radiotap_tx(vap, m); 9867 } 9868 9869 return (0); 9870} 9871 9872static void 9873bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9874 const uint8_t rate) 9875{ 9876 uint32_t d, plen; 9877 uint8_t *raw = plcp->o.raw; 9878 9879 if (BWN_ISOFDMRATE(rate)) { 9880 d = bwn_plcp_getofdm(rate); 9881 KASSERT(!(octets & 0xf000), 9882 ("%s:%d: fail", __func__, __LINE__)); 9883 d |= (octets << 5); 9884 plcp->o.data = htole32(d); 9885 } else { 9886 plen = octets * 16 / rate; 9887 if ((octets * 16 % rate) > 0) { 9888 plen++; 9889 if ((rate == BWN_CCK_RATE_11MB) 9890 && ((octets * 8 % 11) < 4)) { 9891 raw[1] = 0x84; 9892 } else 9893 raw[1] = 0x04; 9894 } else 9895 raw[1] = 0x04; 9896 plcp->o.data |= htole32(plen << 16); 9897 raw[0] = bwn_plcp_getcck(rate); 9898 } 9899} 9900 9901static uint8_t 9902bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9903{ 9904 uint8_t mask; 9905 9906 if (n == 0) 9907 return (0); 9908 if (mac->mac_phy.gmode) 9909 mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg; 9910 else 9911 mask = mac->mac_sd->sd_bus->siba_sprom.ant_a; 9912 if (!(mask & (1 << (n - 1)))) 9913 return (0); 9914 return (n); 9915} 9916 9917static uint8_t 9918bwn_get_fbrate(uint8_t bitrate) 9919{ 9920 switch (bitrate) { 9921 case BWN_CCK_RATE_1MB: 9922 return (BWN_CCK_RATE_1MB); 9923 case BWN_CCK_RATE_2MB: 9924 return (BWN_CCK_RATE_1MB); 9925 case BWN_CCK_RATE_5MB: 9926 return (BWN_CCK_RATE_2MB); 9927 case BWN_CCK_RATE_11MB: 9928 return (BWN_CCK_RATE_5MB); 9929 case BWN_OFDM_RATE_6MB: 9930 return (BWN_CCK_RATE_5MB); 9931 case BWN_OFDM_RATE_9MB: 9932 return (BWN_OFDM_RATE_6MB); 9933 case BWN_OFDM_RATE_12MB: 9934 return (BWN_OFDM_RATE_9MB); 9935 case BWN_OFDM_RATE_18MB: 9936 return (BWN_OFDM_RATE_12MB); 9937 case BWN_OFDM_RATE_24MB: 9938 return (BWN_OFDM_RATE_18MB); 9939 case BWN_OFDM_RATE_36MB: 9940 return (BWN_OFDM_RATE_24MB); 9941 case BWN_OFDM_RATE_48MB: 9942 return (BWN_OFDM_RATE_36MB); 9943 case BWN_OFDM_RATE_54MB: 9944 return (BWN_OFDM_RATE_48MB); 9945 } 9946 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9947 return (0); 9948} 9949 9950static uint32_t 9951bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9952 uint32_t ctl, const void *_data, int len) 9953{ 9954 uint32_t value = 0; 9955 const uint8_t *data = _data; 9956 9957 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9958 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9959 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9960 9961 siba_write_multi_4(mac->mac_sd, data, (len & ~3), 9962 tq->tq_base + BWN_PIO8_TXDATA); 9963 if (len & 3) { 9964 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9965 BWN_PIO8_TXCTL_24_31); 9966 data = &(data[len - 1]); 9967 switch (len & 3) { 9968 case 3: 9969 ctl |= BWN_PIO8_TXCTL_16_23; 9970 value |= (uint32_t)(*data) << 16; 9971 data--; 9972 case 2: 9973 ctl |= BWN_PIO8_TXCTL_8_15; 9974 value |= (uint32_t)(*data) << 8; 9975 data--; 9976 case 1: 9977 value |= (uint32_t)(*data); 9978 } 9979 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9980 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9981 } 9982 9983 return (ctl); 9984} 9985 9986static void 9987bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9988 uint16_t offset, uint32_t value) 9989{ 9990 9991 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9992} 9993 9994static uint16_t 9995bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9996 uint16_t ctl, const void *_data, int len) 9997{ 9998 const uint8_t *data = _data; 9999 10000 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10001 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10002 10003 siba_write_multi_2(mac->mac_sd, data, (len & ~1), 10004 tq->tq_base + BWN_PIO_TXDATA); 10005 if (len & 1) { 10006 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10007 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10008 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 10009 } 10010 10011 return (ctl); 10012} 10013 10014static uint16_t 10015bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 10016 uint16_t ctl, struct mbuf *m0) 10017{ 10018 int i, j = 0; 10019 uint16_t data = 0; 10020 const uint8_t *buf; 10021 struct mbuf *m = m0; 10022 10023 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10024 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10025 10026 for (; m != NULL; m = m->m_next) { 10027 buf = mtod(m, const uint8_t *); 10028 for (i = 0; i < m->m_len; i++) { 10029 if (!((j++) % 2)) 10030 data |= buf[i]; 10031 else { 10032 data |= (buf[i] << 8); 10033 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10034 data = 0; 10035 } 10036 } 10037 } 10038 if (m0->m_pkthdr.len % 2) { 10039 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10040 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10041 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10042 } 10043 10044 return (ctl); 10045} 10046 10047static void 10048bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 10049{ 10050 10051 if (mac->mac_phy.type != BWN_PHYTYPE_G) 10052 return; 10053 BWN_WRITE_2(mac, 0x684, 510 + time); 10054 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 10055} 10056 10057static struct bwn_dma_ring * 10058bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 10059{ 10060 10061 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 10062 return (mac->mac_method.dma.wme[WME_AC_BE]); 10063 10064 switch (prio) { 10065 case 3: 10066 return (mac->mac_method.dma.wme[WME_AC_VO]); 10067 case 2: 10068 return (mac->mac_method.dma.wme[WME_AC_VI]); 10069 case 0: 10070 return (mac->mac_method.dma.wme[WME_AC_BE]); 10071 case 1: 10072 return (mac->mac_method.dma.wme[WME_AC_BK]); 10073 } 10074 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10075 return (NULL); 10076} 10077 10078static int 10079bwn_dma_getslot(struct bwn_dma_ring *dr) 10080{ 10081 int slot; 10082 10083 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10084 10085 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10086 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10087 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10088 10089 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10090 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10091 dr->dr_curslot = slot; 10092 dr->dr_usedslot++; 10093 10094 return (slot); 10095} 10096 10097static int 10098bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10099{ 10100 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10101 unsigned int a, b, c, d; 10102 unsigned int avg; 10103 uint32_t tmp; 10104 10105 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10106 a = tmp & 0xff; 10107 b = (tmp >> 8) & 0xff; 10108 c = (tmp >> 16) & 0xff; 10109 d = (tmp >> 24) & 0xff; 10110 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10111 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10112 return (ENOENT); 10113 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10114 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10115 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10116 10117 if (ofdm) { 10118 a = (a + 32) & 0x3f; 10119 b = (b + 32) & 0x3f; 10120 c = (c + 32) & 0x3f; 10121 d = (d + 32) & 0x3f; 10122 } 10123 10124 avg = (a + b + c + d + 2) / 4; 10125 if (ofdm) { 10126 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10127 & BWN_HF_4DB_CCK_POWERBOOST) 10128 avg = (avg >= 13) ? (avg - 13) : 0; 10129 } 10130 return (avg); 10131} 10132 10133static void 10134bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10135{ 10136 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10137 int rfatt = *rfattp; 10138 int bbatt = *bbattp; 10139 10140 while (1) { 10141 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10142 break; 10143 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10144 break; 10145 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10146 break; 10147 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10148 break; 10149 if (bbatt > lo->bbatt.max) { 10150 bbatt -= 4; 10151 rfatt += 1; 10152 continue; 10153 } 10154 if (bbatt < lo->bbatt.min) { 10155 bbatt += 4; 10156 rfatt -= 1; 10157 continue; 10158 } 10159 if (rfatt > lo->rfatt.max) { 10160 rfatt -= 1; 10161 bbatt += 4; 10162 continue; 10163 } 10164 if (rfatt < lo->rfatt.min) { 10165 rfatt += 1; 10166 bbatt -= 4; 10167 continue; 10168 } 10169 break; 10170 } 10171 10172 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10173 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10174} 10175 10176static void 10177bwn_phy_lock(struct bwn_mac *mac) 10178{ 10179 struct bwn_softc *sc = mac->mac_sc; 10180 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10181 10182 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10183 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10184 10185 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10186 bwn_psctl(mac, BWN_PS_AWAKE); 10187} 10188 10189static void 10190bwn_phy_unlock(struct bwn_mac *mac) 10191{ 10192 struct bwn_softc *sc = mac->mac_sc; 10193 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10194 10195 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10196 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10197 10198 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10199 bwn_psctl(mac, 0); 10200} 10201 10202static void 10203bwn_rf_lock(struct bwn_mac *mac) 10204{ 10205 10206 BWN_WRITE_4(mac, BWN_MACCTL, 10207 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10208 BWN_READ_4(mac, BWN_MACCTL); 10209 DELAY(10); 10210} 10211 10212static void 10213bwn_rf_unlock(struct bwn_mac *mac) 10214{ 10215 10216 BWN_READ_2(mac, BWN_PHYVER); 10217 BWN_WRITE_4(mac, BWN_MACCTL, 10218 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10219} 10220 10221static struct bwn_pio_txqueue * 10222bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10223 struct bwn_pio_txpkt **pack) 10224{ 10225 struct bwn_pio *pio = &mac->mac_method.pio; 10226 struct bwn_pio_txqueue *tq = NULL; 10227 unsigned int index; 10228 10229 switch (cookie & 0xf000) { 10230 case 0x1000: 10231 tq = &pio->wme[WME_AC_BK]; 10232 break; 10233 case 0x2000: 10234 tq = &pio->wme[WME_AC_BE]; 10235 break; 10236 case 0x3000: 10237 tq = &pio->wme[WME_AC_VI]; 10238 break; 10239 case 0x4000: 10240 tq = &pio->wme[WME_AC_VO]; 10241 break; 10242 case 0x5000: 10243 tq = &pio->mcast; 10244 break; 10245 } 10246 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10247 if (tq == NULL) 10248 return (NULL); 10249 index = (cookie & 0x0fff); 10250 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10251 if (index >= N(tq->tq_pkts)) 10252 return (NULL); 10253 *pack = &tq->tq_pkts[index]; 10254 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10255 return (tq); 10256} 10257 10258static void 10259bwn_txpwr(void *arg, int npending) 10260{ 10261 struct bwn_mac *mac = arg; 10262 struct bwn_softc *sc = mac->mac_sc; 10263 10264 BWN_LOCK(sc); 10265 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10266 mac->mac_phy.set_txpwr != NULL) 10267 mac->mac_phy.set_txpwr(mac); 10268 BWN_UNLOCK(sc); 10269} 10270 10271static void 10272bwn_task_15s(struct bwn_mac *mac) 10273{ 10274 uint16_t reg; 10275 10276 if (mac->mac_fw.opensource) { 10277 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10278 if (reg) { 10279 bwn_restart(mac, "fw watchdog"); 10280 return; 10281 } 10282 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10283 } 10284 if (mac->mac_phy.task_15s) 10285 mac->mac_phy.task_15s(mac); 10286 10287 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10288} 10289 10290static void 10291bwn_task_30s(struct bwn_mac *mac) 10292{ 10293 10294 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10295 return; 10296 mac->mac_noise.noi_running = 1; 10297 mac->mac_noise.noi_nsamples = 0; 10298 10299 bwn_noise_gensample(mac); 10300} 10301 10302static void 10303bwn_task_60s(struct bwn_mac *mac) 10304{ 10305 10306 if (mac->mac_phy.task_60s) 10307 mac->mac_phy.task_60s(mac); 10308 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10309} 10310 10311static void 10312bwn_tasks(void *arg) 10313{ 10314 struct bwn_mac *mac = arg; 10315 struct bwn_softc *sc = mac->mac_sc; 10316 10317 BWN_ASSERT_LOCKED(sc); 10318 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10319 return; 10320 10321 if (mac->mac_task_state % 4 == 0) 10322 bwn_task_60s(mac); 10323 if (mac->mac_task_state % 2 == 0) 10324 bwn_task_30s(mac); 10325 bwn_task_15s(mac); 10326 10327 mac->mac_task_state++; 10328 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10329} 10330 10331static int 10332bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10333{ 10334 struct bwn_softc *sc = mac->mac_sc; 10335 10336 KASSERT(a == 0, ("not support APHY\n")); 10337 10338 switch (plcp->o.raw[0] & 0xf) { 10339 case 0xb: 10340 return (BWN_OFDM_RATE_6MB); 10341 case 0xf: 10342 return (BWN_OFDM_RATE_9MB); 10343 case 0xa: 10344 return (BWN_OFDM_RATE_12MB); 10345 case 0xe: 10346 return (BWN_OFDM_RATE_18MB); 10347 case 0x9: 10348 return (BWN_OFDM_RATE_24MB); 10349 case 0xd: 10350 return (BWN_OFDM_RATE_36MB); 10351 case 0x8: 10352 return (BWN_OFDM_RATE_48MB); 10353 case 0xc: 10354 return (BWN_OFDM_RATE_54MB); 10355 } 10356 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10357 plcp->o.raw[0] & 0xf); 10358 return (-1); 10359} 10360 10361static int 10362bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10363{ 10364 struct bwn_softc *sc = mac->mac_sc; 10365 10366 switch (plcp->o.raw[0]) { 10367 case 0x0a: 10368 return (BWN_CCK_RATE_1MB); 10369 case 0x14: 10370 return (BWN_CCK_RATE_2MB); 10371 case 0x37: 10372 return (BWN_CCK_RATE_5MB); 10373 case 0x6e: 10374 return (BWN_CCK_RATE_11MB); 10375 } 10376 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10377 return (-1); 10378} 10379 10380static void 10381bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10382 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10383 int rssi, int noise) 10384{ 10385 struct bwn_softc *sc = mac->mac_sc; 10386 const struct ieee80211_frame_min *wh; 10387 uint64_t tsf; 10388 uint16_t low_mactime_now; 10389 10390 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10391 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10392 10393 wh = mtod(m, const struct ieee80211_frame_min *); 10394 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10395 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10396 10397 bwn_tsf_read(mac, &tsf); 10398 low_mactime_now = tsf; 10399 tsf = tsf & ~0xffffULL; 10400 tsf += le16toh(rxhdr->mac_time); 10401 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10402 tsf -= 0x10000; 10403 10404 sc->sc_rx_th.wr_tsf = tsf; 10405 sc->sc_rx_th.wr_rate = rate; 10406 sc->sc_rx_th.wr_antsignal = rssi; 10407 sc->sc_rx_th.wr_antnoise = noise; 10408} 10409 10410static void 10411bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10412{ 10413 uint32_t low, high; 10414 10415 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10416 ("%s:%d: fail", __func__, __LINE__)); 10417 10418 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10419 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10420 *tsf = high; 10421 *tsf <<= 32; 10422 *tsf |= low; 10423} 10424 10425static int 10426bwn_dma_attach(struct bwn_mac *mac) 10427{ 10428 struct bwn_dma *dma = &mac->mac_method.dma; 10429 struct bwn_softc *sc = mac->mac_sc; 10430 struct siba_dev_softc *sd = mac->mac_sd; 10431 struct siba_softc *siba = sd->sd_bus; 10432 bus_addr_t lowaddr = 0; 10433 int error; 10434 10435 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10436 return (0); 10437 10438 KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__)); 10439 10440 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10441 10442 dma->dmatype = bwn_dma_gettype(mac); 10443 if (dma->dmatype == BWN_DMA_30BIT) 10444 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10445 else if (dma->dmatype == BWN_DMA_32BIT) 10446 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10447 else 10448 lowaddr = BUS_SPACE_MAXADDR; 10449 10450 /* 10451 * Create top level DMA tag 10452 */ 10453 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10454 BWN_ALIGN, 0, /* alignment, bounds */ 10455 lowaddr, /* lowaddr */ 10456 BUS_SPACE_MAXADDR, /* highaddr */ 10457 NULL, NULL, /* filter, filterarg */ 10458 MAXBSIZE, /* maxsize */ 10459 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10460 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10461 0, /* flags */ 10462 NULL, NULL, /* lockfunc, lockarg */ 10463 &dma->parent_dtag); 10464 if (error) { 10465 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10466 return (error); 10467 } 10468 10469 /* 10470 * Create TX/RX mbuf DMA tag 10471 */ 10472 error = bus_dma_tag_create(dma->parent_dtag, 10473 1, 10474 0, 10475 BUS_SPACE_MAXADDR, 10476 BUS_SPACE_MAXADDR, 10477 NULL, NULL, 10478 MCLBYTES, 10479 1, 10480 BUS_SPACE_MAXSIZE_32BIT, 10481 0, 10482 NULL, NULL, 10483 &dma->rxbuf_dtag); 10484 if (error) { 10485 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10486 goto fail0; 10487 } 10488 error = bus_dma_tag_create(dma->parent_dtag, 10489 1, 10490 0, 10491 BUS_SPACE_MAXADDR, 10492 BUS_SPACE_MAXADDR, 10493 NULL, NULL, 10494 MCLBYTES, 10495 1, 10496 BUS_SPACE_MAXSIZE_32BIT, 10497 0, 10498 NULL, NULL, 10499 &dma->txbuf_dtag); 10500 if (error) { 10501 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10502 goto fail1; 10503 } 10504 10505 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10506 if (!dma->wme[WME_AC_BK]) 10507 goto fail2; 10508 10509 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10510 if (!dma->wme[WME_AC_BE]) 10511 goto fail3; 10512 10513 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10514 if (!dma->wme[WME_AC_VI]) 10515 goto fail4; 10516 10517 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10518 if (!dma->wme[WME_AC_VO]) 10519 goto fail5; 10520 10521 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10522 if (!dma->mcast) 10523 goto fail6; 10524 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10525 if (!dma->rx) 10526 goto fail7; 10527 10528 return (error); 10529 10530fail7: bwn_dma_ringfree(&dma->mcast); 10531fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10532fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10533fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10534fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10535fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10536fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10537fail0: bus_dma_tag_destroy(dma->parent_dtag); 10538 return (error); 10539} 10540 10541static struct bwn_dma_ring * 10542bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10543 uint16_t cookie, int *slot) 10544{ 10545 struct bwn_dma *dma = &mac->mac_method.dma; 10546 struct bwn_dma_ring *dr; 10547 struct bwn_softc *sc = mac->mac_sc; 10548 10549 BWN_ASSERT_LOCKED(mac->mac_sc); 10550 10551 switch (cookie & 0xf000) { 10552 case 0x1000: 10553 dr = dma->wme[WME_AC_BK]; 10554 break; 10555 case 0x2000: 10556 dr = dma->wme[WME_AC_BE]; 10557 break; 10558 case 0x3000: 10559 dr = dma->wme[WME_AC_VI]; 10560 break; 10561 case 0x4000: 10562 dr = dma->wme[WME_AC_VO]; 10563 break; 10564 case 0x5000: 10565 dr = dma->mcast; 10566 break; 10567 default: 10568 dr = NULL; 10569 KASSERT(0 == 1, 10570 ("invalid cookie value %d", cookie & 0xf000)); 10571 } 10572 *slot = (cookie & 0x0fff); 10573 if (*slot < 0 || *slot >= dr->dr_numslots) { 10574 /* 10575 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10576 * that it occurs events which have same H/W sequence numbers. 10577 * When it's occurred just prints a WARNING msgs and ignores. 10578 */ 10579 KASSERT(status->seq == dma->lastseq, 10580 ("%s:%d: fail", __func__, __LINE__)); 10581 device_printf(sc->sc_dev, 10582 "out of slot ranges (0 < %d < %d)\n", *slot, 10583 dr->dr_numslots); 10584 return (NULL); 10585 } 10586 dma->lastseq = status->seq; 10587 return (dr); 10588} 10589 10590static void 10591bwn_dma_stop(struct bwn_mac *mac) 10592{ 10593 struct bwn_dma *dma; 10594 10595 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10596 return; 10597 dma = &mac->mac_method.dma; 10598 10599 bwn_dma_ringstop(&dma->rx); 10600 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10601 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10602 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10603 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10604 bwn_dma_ringstop(&dma->mcast); 10605} 10606 10607static void 10608bwn_dma_ringstop(struct bwn_dma_ring **dr) 10609{ 10610 10611 if (dr == NULL) 10612 return; 10613 10614 bwn_dma_cleanup(*dr); 10615} 10616 10617static void 10618bwn_pio_stop(struct bwn_mac *mac) 10619{ 10620 struct bwn_pio *pio; 10621 10622 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10623 return; 10624 pio = &mac->mac_method.pio; 10625 10626 bwn_destroy_queue_tx(&pio->mcast); 10627 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10628 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10629 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10630 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10631} 10632 10633static void 10634bwn_led_attach(struct bwn_mac *mac) 10635{ 10636 struct bwn_softc *sc = mac->mac_sc; 10637 struct siba_softc *siba = mac->mac_sd->sd_bus; 10638 const uint8_t *led_act = NULL; 10639 uint16_t val[BWN_LED_MAX]; 10640 int i; 10641 10642 sc->sc_led_idle = (2350 * hz) / 1000; 10643 sc->sc_led_blink = 1; 10644 10645 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10646 if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) { 10647 led_act = bwn_vendor_led_act[i].led_act; 10648 break; 10649 } 10650 } 10651 if (led_act == NULL) 10652 led_act = bwn_default_led_act; 10653 10654 val[0] = siba->siba_sprom.gpio0; 10655 val[1] = siba->siba_sprom.gpio1; 10656 val[2] = siba->siba_sprom.gpio2; 10657 val[3] = siba->siba_sprom.gpio3; 10658 10659 for (i = 0; i < BWN_LED_MAX; ++i) { 10660 struct bwn_led *led = &sc->sc_leds[i]; 10661 10662 if (val[i] == 0xff) { 10663 led->led_act = led_act[i]; 10664 } else { 10665 if (val[i] & BWN_LED_ACT_LOW) 10666 led->led_flags |= BWN_LED_F_ACTLOW; 10667 led->led_act = val[i] & BWN_LED_ACT_MASK; 10668 } 10669 led->led_mask = (1 << i); 10670 10671 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10672 led->led_act == BWN_LED_ACT_BLINK_POLL || 10673 led->led_act == BWN_LED_ACT_BLINK) { 10674 led->led_flags |= BWN_LED_F_BLINK; 10675 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10676 led->led_flags |= BWN_LED_F_POLLABLE; 10677 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10678 led->led_flags |= BWN_LED_F_SLOW; 10679 10680 if (sc->sc_blink_led == NULL) { 10681 sc->sc_blink_led = led; 10682 if (led->led_flags & BWN_LED_F_SLOW) 10683 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10684 } 10685 } 10686 10687 DPRINTF(sc, BWN_DEBUG_LED, 10688 "%dth led, act %d, lowact %d\n", i, 10689 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10690 } 10691 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10692} 10693 10694static __inline uint16_t 10695bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10696{ 10697 10698 if (led->led_flags & BWN_LED_F_ACTLOW) 10699 on = !on; 10700 if (on) 10701 val |= led->led_mask; 10702 else 10703 val &= ~led->led_mask; 10704 return val; 10705} 10706 10707static void 10708bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10709{ 10710 struct bwn_softc *sc = mac->mac_sc; 10711 struct ifnet *ifp = sc->sc_ifp; 10712 struct ieee80211com *ic = ifp->if_l2com; 10713 uint16_t val; 10714 int i; 10715 10716 if (nstate == IEEE80211_S_INIT) { 10717 callout_stop(&sc->sc_led_blink_ch); 10718 sc->sc_led_blinking = 0; 10719 } 10720 10721 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10722 return; 10723 10724 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10725 for (i = 0; i < BWN_LED_MAX; ++i) { 10726 struct bwn_led *led = &sc->sc_leds[i]; 10727 int on; 10728 10729 if (led->led_act == BWN_LED_ACT_UNKN || 10730 led->led_act == BWN_LED_ACT_NULL) 10731 continue; 10732 10733 if ((led->led_flags & BWN_LED_F_BLINK) && 10734 nstate != IEEE80211_S_INIT) 10735 continue; 10736 10737 switch (led->led_act) { 10738 case BWN_LED_ACT_ON: /* Always on */ 10739 on = 1; 10740 break; 10741 case BWN_LED_ACT_OFF: /* Always off */ 10742 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10743 on = 0; 10744 break; 10745 default: 10746 on = 1; 10747 switch (nstate) { 10748 case IEEE80211_S_INIT: 10749 on = 0; 10750 break; 10751 case IEEE80211_S_RUN: 10752 if (led->led_act == BWN_LED_ACT_11G && 10753 ic->ic_curmode != IEEE80211_MODE_11G) 10754 on = 0; 10755 break; 10756 default: 10757 if (led->led_act == BWN_LED_ACT_ASSOC) 10758 on = 0; 10759 break; 10760 } 10761 break; 10762 } 10763 10764 val = bwn_led_onoff(led, val, on); 10765 } 10766 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10767} 10768 10769static void 10770bwn_led_event(struct bwn_mac *mac, int event) 10771{ 10772 struct bwn_softc *sc = mac->mac_sc; 10773 struct bwn_led *led = sc->sc_blink_led; 10774 int rate; 10775 10776 if (event == BWN_LED_EVENT_POLL) { 10777 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10778 return; 10779 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10780 return; 10781 } 10782 10783 sc->sc_led_ticks = ticks; 10784 if (sc->sc_led_blinking) 10785 return; 10786 10787 switch (event) { 10788 case BWN_LED_EVENT_RX: 10789 rate = sc->sc_rx_rate; 10790 break; 10791 case BWN_LED_EVENT_TX: 10792 rate = sc->sc_tx_rate; 10793 break; 10794 case BWN_LED_EVENT_POLL: 10795 rate = 0; 10796 break; 10797 default: 10798 panic("unknown LED event %d\n", event); 10799 break; 10800 } 10801 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10802 bwn_led_duration[rate].off_dur); 10803} 10804 10805static void 10806bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10807{ 10808 struct bwn_softc *sc = mac->mac_sc; 10809 struct bwn_led *led = sc->sc_blink_led; 10810 uint16_t val; 10811 10812 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10813 val = bwn_led_onoff(led, val, 1); 10814 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10815 10816 if (led->led_flags & BWN_LED_F_SLOW) { 10817 BWN_LED_SLOWDOWN(on_dur); 10818 BWN_LED_SLOWDOWN(off_dur); 10819 } 10820 10821 sc->sc_led_blinking = 1; 10822 sc->sc_led_blink_offdur = off_dur; 10823 10824 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10825} 10826 10827static void 10828bwn_led_blink_next(void *arg) 10829{ 10830 struct bwn_mac *mac = arg; 10831 struct bwn_softc *sc = mac->mac_sc; 10832 uint16_t val; 10833 10834 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10835 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10836 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10837 10838 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10839 bwn_led_blink_end, mac); 10840} 10841 10842static void 10843bwn_led_blink_end(void *arg) 10844{ 10845 struct bwn_mac *mac = arg; 10846 struct bwn_softc *sc = mac->mac_sc; 10847 10848 sc->sc_led_blinking = 0; 10849} 10850 10851static int 10852bwn_suspend(device_t dev) 10853{ 10854 struct bwn_softc *sc = device_get_softc(dev); 10855 10856 bwn_stop(sc, 1); 10857 return (0); 10858} 10859 10860static int 10861bwn_resume(device_t dev) 10862{ 10863 struct bwn_softc *sc = device_get_softc(dev); 10864 struct ifnet *ifp = sc->sc_ifp; 10865 10866 if (ifp->if_flags & IFF_UP) 10867 bwn_init(sc); 10868 return (0); 10869} 10870 10871static void 10872bwn_rfswitch(void *arg) 10873{ 10874 struct bwn_softc *sc = arg; 10875 struct bwn_mac *mac = sc->sc_curmac; 10876 int cur = 0, prev = 0; 10877 10878 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10879 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10880 10881 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10882 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10883 & BWN_RF_HWENABLED_HI_MASK)) 10884 cur = 1; 10885 } else { 10886 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10887 & BWN_RF_HWENABLED_LO_MASK) 10888 cur = 1; 10889 } 10890 10891 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10892 prev = 1; 10893 10894 if (cur != prev) { 10895 if (cur) 10896 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10897 else 10898 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10899 10900 device_printf(sc->sc_dev, 10901 "status of RF switch is changed to %s\n", 10902 cur ? "ON" : "OFF"); 10903 if (cur != mac->mac_phy.rf_on) { 10904 if (cur) 10905 bwn_rf_turnon(mac); 10906 else 10907 bwn_rf_turnoff(mac); 10908 } 10909 } 10910 10911 callout_schedule(&sc->sc_rfswitch_ch, hz); 10912} 10913 10914static void 10915bwn_phy_lp_init_pre(struct bwn_mac *mac) 10916{ 10917 struct bwn_phy *phy = &mac->mac_phy; 10918 struct bwn_phy_lp *plp = &phy->phy_lp; 10919 10920 plp->plp_antenna = BWN_ANT_DEFAULT; 10921} 10922 10923static int 10924bwn_phy_lp_init(struct bwn_mac *mac) 10925{ 10926 static const struct bwn_stxtable tables[] = { 10927 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10928 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10929 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10930 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10931 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10932 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10933 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10934 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10935 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10936 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10937 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10938 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10939 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10940 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10941 { 2, 11, 0x40, 0, 0x0f } 10942 }; 10943 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10944 struct bwn_softc *sc = mac->mac_sc; 10945 const struct bwn_stxtable *st; 10946 struct ifnet *ifp = sc->sc_ifp; 10947 struct ieee80211com *ic = ifp->if_l2com; 10948 int i, error; 10949 uint16_t tmp; 10950 10951 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10952 bwn_phy_lp_bbinit(mac); 10953 10954 /* initialize RF */ 10955 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10956 DELAY(1); 10957 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10958 DELAY(1); 10959 10960 if (mac->mac_phy.rf_ver == 0x2062) 10961 bwn_phy_lp_b2062_init(mac); 10962 else { 10963 bwn_phy_lp_b2063_init(mac); 10964 10965 /* synchronize stx table. */ 10966 for (i = 0; i < N(tables); i++) { 10967 st = &tables[i]; 10968 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10969 tmp >>= st->st_rfshift; 10970 tmp <<= st->st_physhift; 10971 BWN_PHY_SETMASK(mac, 10972 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10973 ~(st->st_mask << st->st_physhift), tmp); 10974 } 10975 10976 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10977 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10978 } 10979 10980 /* calibrate RC */ 10981 if (mac->mac_phy.rev >= 2) 10982 bwn_phy_lp_rxcal_r2(mac); 10983 else if (!plp->plp_rccap) { 10984 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10985 bwn_phy_lp_rccal_r12(mac); 10986 } else 10987 bwn_phy_lp_set_rccap(mac); 10988 10989 error = bwn_phy_lp_switch_channel(mac, 7); 10990 if (error) 10991 device_printf(sc->sc_dev, 10992 "failed to change channel 7 (%d)\n", error); 10993 bwn_phy_lp_txpctl_init(mac); 10994 bwn_phy_lp_calib(mac); 10995 return (0); 10996} 10997 10998static uint16_t 10999bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 11000{ 11001 11002 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11003 return (BWN_READ_2(mac, BWN_PHYDATA)); 11004} 11005 11006static void 11007bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11008{ 11009 11010 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11011 BWN_WRITE_2(mac, BWN_PHYDATA, value); 11012} 11013 11014static void 11015bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 11016 uint16_t set) 11017{ 11018 11019 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11020 BWN_WRITE_2(mac, BWN_PHYDATA, 11021 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 11022} 11023 11024static uint16_t 11025bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 11026{ 11027 11028 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11029 if (mac->mac_phy.rev < 2 && reg != 0x4001) 11030 reg |= 0x100; 11031 if (mac->mac_phy.rev >= 2) 11032 reg |= 0x200; 11033 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11034 return BWN_READ_2(mac, BWN_RFDATALO); 11035} 11036 11037static void 11038bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11039{ 11040 11041 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11042 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11043 BWN_WRITE_2(mac, BWN_RFDATALO, value); 11044} 11045 11046static void 11047bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 11048{ 11049 11050 if (on) { 11051 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 11052 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 11053 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 11054 return; 11055 } 11056 11057 if (mac->mac_phy.rev >= 2) { 11058 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 11059 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11060 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 11061 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 11062 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 11063 return; 11064 } 11065 11066 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 11067 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11068 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 11069 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 11070} 11071 11072static int 11073bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11074{ 11075 struct bwn_phy *phy = &mac->mac_phy; 11076 struct bwn_phy_lp *plp = &phy->phy_lp; 11077 int error; 11078 11079 if (phy->rf_ver == 0x2063) { 11080 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11081 if (error) 11082 return (error); 11083 } else { 11084 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11085 if (error) 11086 return (error); 11087 bwn_phy_lp_set_anafilter(mac, chan); 11088 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11089 } 11090 11091 plp->plp_chan = chan; 11092 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11093 return (0); 11094} 11095 11096static uint32_t 11097bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11098{ 11099 struct bwn_softc *sc = mac->mac_sc; 11100 struct ifnet *ifp = sc->sc_ifp; 11101 struct ieee80211com *ic = ifp->if_l2com; 11102 11103 device_printf(sc->sc_dev, "correct?\n"); 11104 11105 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11106} 11107 11108static void 11109bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11110{ 11111 struct bwn_phy *phy = &mac->mac_phy; 11112 struct bwn_phy_lp *plp = &phy->phy_lp; 11113 11114 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11115 return; 11116 11117 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11118 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11119 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11120 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11121 plp->plp_antenna = antenna; 11122} 11123 11124static void 11125bwn_phy_lp_task_60s(struct bwn_mac *mac) 11126{ 11127 11128 bwn_phy_lp_calib(mac); 11129} 11130 11131static void 11132bwn_phy_lp_readsprom(struct bwn_mac *mac) 11133{ 11134 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11135 struct bwn_softc *sc = mac->mac_sc; 11136 struct ifnet *ifp = sc->sc_ifp; 11137 struct ieee80211com *ic = ifp->if_l2com; 11138 struct siba_dev_softc *sd = mac->mac_sd; 11139 struct siba_softc *siba = sd->sd_bus; 11140 struct siba_sprom *sprom = &siba->siba_sprom; 11141 11142 device_printf(sc->sc_dev, "XXX using %dghz\n", 11143 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5); 11144 11145 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11146 plp->plp_txisoband_m = sprom->tri2g; 11147 plp->plp_bxarch = sprom->bxa2g; 11148 plp->plp_rxpwroffset = sprom->rxpo2g; 11149 plp->plp_rssivf = sprom->rssismf2g; 11150 plp->plp_rssivc = sprom->rssismc2g; 11151 plp->plp_rssigs = sprom->rssisav2g; 11152 return; 11153 } 11154 11155 plp->plp_txisoband_l = sprom->tri5gl; 11156 plp->plp_txisoband_m = sprom->tri5g; 11157 plp->plp_txisoband_h = sprom->tri5gh; 11158 plp->plp_bxarch = sprom->bxa5g; 11159 plp->plp_rxpwroffset = sprom->rxpo5g; 11160 plp->plp_rssivf = sprom->rssismf5g; 11161 plp->plp_rssivc = sprom->rssismc5g; 11162 plp->plp_rssigs = sprom->rssisav5g; 11163} 11164 11165static void 11166bwn_phy_lp_bbinit(struct bwn_mac *mac) 11167{ 11168 11169 bwn_phy_lp_tblinit(mac); 11170 if (mac->mac_phy.rev >= 2) 11171 bwn_phy_lp_bbinit_r2(mac); 11172 else 11173 bwn_phy_lp_bbinit_r01(mac); 11174} 11175 11176static void 11177bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11178{ 11179 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11180 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11181 struct bwn_softc *sc = mac->mac_sc; 11182 struct ifnet *ifp = sc->sc_ifp; 11183 struct ieee80211com *ic = ifp->if_l2com; 11184 11185 bwn_phy_lp_set_txgain(mac, 11186 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11187 bwn_phy_lp_set_bbmult(mac, 150); 11188} 11189 11190static void 11191bwn_phy_lp_calib(struct bwn_mac *mac) 11192{ 11193 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11194 struct siba_dev_softc *sd = mac->mac_sd; 11195 struct siba_softc *siba = sd->sd_bus; 11196 struct bwn_softc *sc = mac->mac_sc; 11197 struct ifnet *ifp = sc->sc_ifp; 11198 struct ieee80211com *ic = ifp->if_l2com; 11199 const struct bwn_rxcompco *rc = NULL; 11200 struct bwn_txgain ogain; 11201 int i, omode, oafeovr, orf, obbmult; 11202 uint8_t mode, fc = 0; 11203 11204 if (plp->plp_chanfullcal != plp->plp_chan) { 11205 plp->plp_chanfullcal = plp->plp_chan; 11206 fc = 1; 11207 } 11208 11209 bwn_mac_suspend(mac); 11210 11211 /* BlueTooth Coexistance Override */ 11212 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11213 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11214 11215 if (mac->mac_phy.rev >= 2) 11216 bwn_phy_lp_digflt_save(mac); 11217 bwn_phy_lp_get_txpctlmode(mac); 11218 mode = plp->plp_txpctlmode; 11219 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11220 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11221 bwn_phy_lp_bugfix(mac); 11222 if (mac->mac_phy.rev >= 2 && fc == 1) { 11223 bwn_phy_lp_get_txpctlmode(mac); 11224 omode = plp->plp_txpctlmode; 11225 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11226 if (oafeovr) 11227 ogain = bwn_phy_lp_get_txgain(mac); 11228 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11229 obbmult = bwn_phy_lp_get_bbmult(mac); 11230 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11231 if (oafeovr) 11232 bwn_phy_lp_set_txgain(mac, &ogain); 11233 bwn_phy_lp_set_bbmult(mac, obbmult); 11234 bwn_phy_lp_set_txpctlmode(mac, omode); 11235 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11236 } 11237 bwn_phy_lp_set_txpctlmode(mac, mode); 11238 if (mac->mac_phy.rev >= 2) 11239 bwn_phy_lp_digflt_restore(mac); 11240 11241 /* do RX IQ Calculation; assumes that noise is true. */ 11242 if (siba->siba_chipid == 0x5354) { 11243 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11244 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11245 rc = &bwn_rxcompco_5354[i]; 11246 } 11247 } else if (mac->mac_phy.rev >= 2) 11248 rc = &bwn_rxcompco_r2; 11249 else { 11250 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11251 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11252 rc = &bwn_rxcompco_r12[i]; 11253 } 11254 } 11255 if (rc == NULL) 11256 goto fail; 11257 11258 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11259 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11260 11261 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11262 11263 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11264 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11266 } else { 11267 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11268 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11269 } 11270 11271 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11272 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11273 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11274 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11275 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11276 bwn_phy_lp_set_deaf(mac, 0); 11277 /* XXX no checking return value? */ 11278 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11279 bwn_phy_lp_clear_deaf(mac, 0); 11280 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11281 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11282 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11283 11284 /* disable RX GAIN override. */ 11285 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11286 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11287 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11288 if (mac->mac_phy.rev >= 2) { 11289 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11290 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11292 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11293 } 11294 } else { 11295 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11296 } 11297 11298 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11299 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11300fail: 11301 bwn_mac_enable(mac); 11302} 11303 11304static void 11305bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11306{ 11307 11308 if (on) { 11309 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11310 return; 11311 } 11312 11313 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11314 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11315} 11316 11317static int 11318bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11319{ 11320 struct siba_dev_softc *sd = mac->mac_sd; 11321 struct siba_softc *siba = sd->sd_bus; 11322 static const struct bwn_b206x_chan *bc = NULL; 11323 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11324 tmp[6]; 11325 uint16_t old, scale, tmp16; 11326 int i, div; 11327 11328 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11329 if (bwn_b2063_chantable[i].bc_chan == chan) { 11330 bc = &bwn_b2063_chantable[i]; 11331 break; 11332 } 11333 } 11334 if (bc == NULL) 11335 return (EINVAL); 11336 11337 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11338 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11339 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11340 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11341 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11342 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11343 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11344 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11345 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11346 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11347 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11348 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11349 11350 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11351 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11352 11353 freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11354 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11355 freqref = freqxtal * 3; 11356 div = (freqxtal <= 26000000 ? 1 : 2); 11357 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11358 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11359 999999) / 1000000) + 1; 11360 11361 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11362 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11363 0xfff8, timeout >> 2); 11364 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11365 0xff9f,timeout << 5); 11366 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11367 11368 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11369 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11370 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11371 11372 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11373 (timeoutref + 1)) - 1; 11374 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11375 0xf0, count >> 8); 11376 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11377 11378 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11379 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11380 while (tmp[1] >= freqref) { 11381 tmp[0]++; 11382 tmp[1] -= freqref; 11383 } 11384 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11385 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11386 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11387 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11388 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11389 11390 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11391 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11392 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11393 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11394 11395 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11396 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11397 11398 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11399 scale = 1; 11400 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11401 } else { 11402 scale = 0; 11403 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11404 } 11405 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11406 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11407 11408 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11409 (scale + 1); 11410 if (tmp[5] > 150) 11411 tmp[5] = 0; 11412 11413 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11414 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11415 11416 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11417 if (freqxtal > 26000000) 11418 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11419 else 11420 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11421 11422 if (val[0] == 45) 11423 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11424 else 11425 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11426 11427 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11428 DELAY(1); 11429 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11430 11431 /* VCO Calibration */ 11432 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11433 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11434 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11435 DELAY(1); 11436 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11437 DELAY(1); 11438 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11439 DELAY(1); 11440 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11441 DELAY(300); 11442 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11443 11444 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11445 return (0); 11446} 11447 11448static int 11449bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11450{ 11451 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11452 struct siba_dev_softc *sd = mac->mac_sd; 11453 struct siba_softc *siba = sd->sd_bus; 11454 const struct bwn_b206x_chan *bc = NULL; 11455 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11456 uint32_t tmp[9]; 11457 int i; 11458 11459 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11460 if (bwn_b2062_chantable[i].bc_chan == chan) { 11461 bc = &bwn_b2062_chantable[i]; 11462 break; 11463 } 11464 } 11465 11466 if (bc == NULL) 11467 return (EINVAL); 11468 11469 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11470 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11471 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11472 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11473 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11474 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11475 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11476 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11477 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11478 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11479 11480 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11481 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11482 bwn_phy_lp_b2062_reset_pllbias(mac); 11483 tmp[0] = freqxtal / 1000; 11484 tmp[1] = plp->plp_div * 1000; 11485 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11486 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11487 tmp[2] *= 2; 11488 tmp[3] = 48 * tmp[0]; 11489 tmp[5] = tmp[2] / tmp[3]; 11490 tmp[6] = tmp[2] % tmp[3]; 11491 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11492 tmp[4] = tmp[6] * 0x100; 11493 tmp[5] = tmp[4] / tmp[3]; 11494 tmp[6] = tmp[4] % tmp[3]; 11495 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11496 tmp[4] = tmp[6] * 0x100; 11497 tmp[5] = tmp[4] / tmp[3]; 11498 tmp[6] = tmp[4] % tmp[3]; 11499 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11500 tmp[4] = tmp[6] * 0x100; 11501 tmp[5] = tmp[4] / tmp[3]; 11502 tmp[6] = tmp[4] % tmp[3]; 11503 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11504 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11505 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11506 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11507 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11508 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11509 11510 bwn_phy_lp_b2062_vco_calib(mac); 11511 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11512 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11513 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11514 bwn_phy_lp_b2062_reset_pllbias(mac); 11515 bwn_phy_lp_b2062_vco_calib(mac); 11516 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11517 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11518 return (EIO); 11519 } 11520 } 11521 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11522 return (0); 11523} 11524 11525static void 11526bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11527{ 11528 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11529 uint16_t tmp = (channel == 14); 11530 11531 if (mac->mac_phy.rev < 2) { 11532 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11533 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11534 bwn_phy_lp_set_rccap(mac); 11535 return; 11536 } 11537 11538 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11539} 11540 11541static void 11542bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11543{ 11544 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11545 struct bwn_softc *sc = mac->mac_sc; 11546 struct ifnet *ifp = sc->sc_ifp; 11547 struct ieee80211com *ic = ifp->if_l2com; 11548 uint16_t iso, tmp[3]; 11549 11550 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11551 11552 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11553 iso = plp->plp_txisoband_m; 11554 else if (freq <= 5320) 11555 iso = plp->plp_txisoband_l; 11556 else if (freq <= 5700) 11557 iso = plp->plp_txisoband_m; 11558 else 11559 iso = plp->plp_txisoband_h; 11560 11561 tmp[0] = ((iso - 26) / 12) << 12; 11562 tmp[1] = tmp[0] + 0x1000; 11563 tmp[2] = tmp[0] + 0x2000; 11564 11565 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11566 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11567} 11568 11569static void 11570bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11571{ 11572 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11573 int i; 11574 static const uint16_t addr[] = { 11575 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11576 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11577 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11578 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11579 BWN_PHY_OFDM(0xcf), 11580 }; 11581 static const uint16_t val[] = { 11582 0xde5e, 0xe832, 0xe331, 0x4d26, 11583 0x0026, 0x1420, 0x0020, 0xfe08, 11584 0x0008, 11585 }; 11586 11587 for (i = 0; i < N(addr); i++) { 11588 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11589 BWN_PHY_WRITE(mac, addr[i], val[i]); 11590 } 11591} 11592 11593static void 11594bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11595{ 11596 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11597 struct bwn_softc *sc = mac->mac_sc; 11598 uint16_t ctl; 11599 11600 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11601 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11602 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11603 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11604 break; 11605 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11606 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11607 break; 11608 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11609 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11610 break; 11611 default: 11612 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11613 device_printf(sc->sc_dev, "unknown command mode\n"); 11614 break; 11615 } 11616} 11617 11618static void 11619bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11620{ 11621 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11622 uint16_t ctl; 11623 uint8_t old; 11624 11625 bwn_phy_lp_get_txpctlmode(mac); 11626 old = plp->plp_txpctlmode; 11627 if (old == mode) 11628 return; 11629 plp->plp_txpctlmode = mode; 11630 11631 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11632 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11633 plp->plp_tssiidx); 11634 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11635 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11636 11637 /* disable TX GAIN override */ 11638 if (mac->mac_phy.rev < 2) 11639 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11640 else { 11641 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11642 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11643 } 11644 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11645 11646 plp->plp_txpwridx = -1; 11647 } 11648 if (mac->mac_phy.rev >= 2) { 11649 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11650 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11651 else 11652 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11653 } 11654 11655 /* writes TX Power Control mode */ 11656 switch (plp->plp_txpctlmode) { 11657 case BWN_PHYLP_TXPCTL_OFF: 11658 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11659 break; 11660 case BWN_PHYLP_TXPCTL_ON_HW: 11661 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11662 break; 11663 case BWN_PHYLP_TXPCTL_ON_SW: 11664 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11665 break; 11666 default: 11667 ctl = 0; 11668 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11669 } 11670 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11671 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11672} 11673 11674static void 11675bwn_phy_lp_bugfix(struct bwn_mac *mac) 11676{ 11677 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11678 struct bwn_softc *sc = mac->mac_sc; 11679 const unsigned int size = 256; 11680 struct bwn_txgain tg; 11681 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11682 uint16_t tssinpt, tssiidx, value[2]; 11683 uint8_t mode; 11684 int8_t txpwridx; 11685 11686 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11687 M_NOWAIT | M_ZERO); 11688 if (tabs == NULL) { 11689 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11690 return; 11691 } 11692 11693 bwn_phy_lp_get_txpctlmode(mac); 11694 mode = plp->plp_txpctlmode; 11695 txpwridx = plp->plp_txpwridx; 11696 tssinpt = plp->plp_tssinpt; 11697 tssiidx = plp->plp_tssiidx; 11698 11699 bwn_tab_read_multi(mac, 11700 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11701 BWN_TAB_4(7, 0x140), size, tabs); 11702 11703 bwn_phy_lp_tblinit(mac); 11704 bwn_phy_lp_bbinit(mac); 11705 bwn_phy_lp_txpctl_init(mac); 11706 bwn_phy_lp_rf_onoff(mac, 1); 11707 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11708 11709 bwn_tab_write_multi(mac, 11710 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11711 BWN_TAB_4(7, 0x140), size, tabs); 11712 11713 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11714 plp->plp_tssinpt = tssinpt; 11715 plp->plp_tssiidx = tssiidx; 11716 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11717 if (txpwridx != -1) { 11718 /* set TX power by index */ 11719 plp->plp_txpwridx = txpwridx; 11720 bwn_phy_lp_get_txpctlmode(mac); 11721 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11722 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11723 if (mac->mac_phy.rev >= 2) { 11724 rxcomp = bwn_tab_read(mac, 11725 BWN_TAB_4(7, txpwridx + 320)); 11726 txgain = bwn_tab_read(mac, 11727 BWN_TAB_4(7, txpwridx + 192)); 11728 tg.tg_pad = (txgain >> 16) & 0xff; 11729 tg.tg_gm = txgain & 0xff; 11730 tg.tg_pga = (txgain >> 8) & 0xff; 11731 tg.tg_dac = (rxcomp >> 28) & 0xff; 11732 bwn_phy_lp_set_txgain(mac, &tg); 11733 } else { 11734 rxcomp = bwn_tab_read(mac, 11735 BWN_TAB_4(10, txpwridx + 320)); 11736 txgain = bwn_tab_read(mac, 11737 BWN_TAB_4(10, txpwridx + 192)); 11738 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11739 0xf800, (txgain >> 4) & 0x7fff); 11740 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11741 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11742 } 11743 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11744 11745 /* set TX IQCC */ 11746 value[0] = (rxcomp >> 10) & 0x3ff; 11747 value[1] = rxcomp & 0x3ff; 11748 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11749 11750 coeff = bwn_tab_read(mac, 11751 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11752 BWN_TAB_4(10, txpwridx + 448)); 11753 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11754 if (mac->mac_phy.rev >= 2) { 11755 rfpwr = bwn_tab_read(mac, 11756 BWN_TAB_4(7, txpwridx + 576)); 11757 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11758 rfpwr & 0xffff); 11759 } 11760 bwn_phy_lp_set_txgain_override(mac); 11761 } 11762 if (plp->plp_rccap) 11763 bwn_phy_lp_set_rccap(mac); 11764 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11765 bwn_phy_lp_set_txpctlmode(mac, mode); 11766 free(tabs, M_DEVBUF); 11767} 11768 11769static void 11770bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11771{ 11772 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11773 int i; 11774 static const uint16_t addr[] = { 11775 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11776 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11777 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11778 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11779 BWN_PHY_OFDM(0xcf), 11780 }; 11781 11782 for (i = 0; i < N(addr); i++) 11783 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11784} 11785 11786static void 11787bwn_phy_lp_tblinit(struct bwn_mac *mac) 11788{ 11789 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11790 11791 if (mac->mac_phy.rev < 2) { 11792 bwn_phy_lp_tblinit_r01(mac); 11793 bwn_phy_lp_tblinit_txgain(mac); 11794 bwn_phy_lp_set_gaintbl(mac, freq); 11795 return; 11796 } 11797 11798 bwn_phy_lp_tblinit_r2(mac); 11799 bwn_phy_lp_tblinit_txgain(mac); 11800} 11801 11802struct bwn_wpair { 11803 uint16_t reg; 11804 uint16_t value; 11805}; 11806 11807struct bwn_smpair { 11808 uint16_t offset; 11809 uint16_t mask; 11810 uint16_t set; 11811}; 11812 11813static void 11814bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11815{ 11816 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11817 struct siba_dev_softc *sd = mac->mac_sd; 11818 struct siba_softc *siba = sd->sd_bus; 11819 struct bwn_softc *sc = mac->mac_sc; 11820 struct ifnet *ifp = sc->sc_ifp; 11821 struct ieee80211com *ic = ifp->if_l2com; 11822 static const struct bwn_wpair v1[] = { 11823 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11824 { BWN_PHY_AFE_CTL, 0x8800 }, 11825 { BWN_PHY_AFE_CTL_OVR, 0 }, 11826 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11827 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11828 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11829 { BWN_PHY_OFDM(0xf9), 0 }, 11830 { BWN_PHY_TR_LOOKUP_1, 0 } 11831 }; 11832 static const struct bwn_smpair v2[] = { 11833 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11834 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11835 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11836 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11837 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11838 }; 11839 static const struct bwn_smpair v3[] = { 11840 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11841 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11842 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11843 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11844 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11845 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11846 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11847 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11848 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11849 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11850 11851 }; 11852 int i; 11853 11854 for (i = 0; i < N(v1); i++) 11855 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11856 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11857 for (i = 0; i < N(v2); i++) 11858 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11859 11860 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11861 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11862 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11863 if (siba->siba_board_rev >= 0x18) { 11864 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11865 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11866 } else { 11867 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11868 } 11869 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11870 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11871 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11872 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11873 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11874 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11875 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11876 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11877 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11878 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11879 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11880 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11881 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11882 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11883 } else { 11884 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11885 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11886 } 11887 for (i = 0; i < N(v3); i++) 11888 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11889 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11890 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11891 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11892 } 11893 11894 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11895 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11896 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11897 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11898 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11899 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11900 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11901 } else 11902 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11903 11904 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11905 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11906 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11907 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11908 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11909 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11910 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11911 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11912 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11913 11914 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11915 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11918 } 11919 11920 bwn_phy_lp_digflt_save(mac); 11921} 11922 11923static void 11924bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11925{ 11926 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11927 struct siba_dev_softc *sd = mac->mac_sd; 11928 struct siba_softc *siba = sd->sd_bus; 11929 struct bwn_softc *sc = mac->mac_sc; 11930 struct ifnet *ifp = sc->sc_ifp; 11931 struct ieee80211com *ic = ifp->if_l2com; 11932 static const struct bwn_smpair v1[] = { 11933 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11934 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11935 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11936 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11937 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11938 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11939 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11940 }; 11941 static const struct bwn_smpair v2[] = { 11942 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11943 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11944 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11945 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11946 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11947 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11948 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11949 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11950 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11951 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11952 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11953 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11954 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11955 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11956 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11957 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11958 }; 11959 static const struct bwn_smpair v3[] = { 11960 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11961 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11962 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11963 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11964 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11965 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11966 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11967 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11968 }; 11969 static const struct bwn_smpair v4[] = { 11970 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11971 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11972 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11973 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11974 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11975 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11976 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11977 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11978 }; 11979 static const struct bwn_smpair v5[] = { 11980 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11981 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11982 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11983 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11984 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11985 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11986 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11987 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11988 }; 11989 int i; 11990 uint16_t tmp, tmp2; 11991 11992 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11993 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11994 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11995 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11996 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11997 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11998 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11999 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 12000 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 12001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 12002 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 12003 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 12004 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 12005 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 12006 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 12007 for (i = 0; i < N(v1); i++) 12008 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 12009 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 12010 0xff00, plp->plp_rxpwroffset); 12011 if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) && 12012 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 12013 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) { 12014 siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28); 12015 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1); 12016 if (mac->mac_phy.rev == 0) 12017 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 12018 0xffcf, 0x0010); 12019 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 12020 } else { 12021 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0); 12022 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 12023 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 12024 } 12025 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 12026 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 12027 if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV) 12028 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 12029 else 12030 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 12031 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 12032 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 12033 0xfff9, (plp->plp_bxarch << 1)); 12034 if (mac->mac_phy.rev == 1 && 12035 (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) { 12036 for (i = 0; i < N(v2); i++) 12037 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 12038 v2[i].set); 12039 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 12040 (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) && 12041 (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) { 12042 for (i = 0; i < N(v3); i++) 12043 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 12044 v3[i].set); 12045 } else if (mac->mac_phy.rev == 1 || 12046 (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) { 12047 for (i = 0; i < N(v4); i++) 12048 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 12049 v4[i].set); 12050 } else { 12051 for (i = 0; i < N(v5); i++) 12052 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 12053 v5[i].set); 12054 } 12055 if (mac->mac_phy.rev == 1 && 12056 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) { 12057 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 12058 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 12059 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 12060 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 12061 } 12062 if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) && 12063 (siba->siba_chipid == 0x5354) && 12064 (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) { 12065 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 12066 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 12067 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 12068 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 12069 } 12070 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12071 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 12072 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 12073 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 12074 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 12075 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 12076 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 12077 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 12078 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 12079 } else { 12080 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 12081 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 12082 } 12083 if (mac->mac_phy.rev == 1) { 12084 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12085 tmp2 = (tmp & 0x03e0) >> 5; 12086 tmp2 |= tmp2 << 5; 12087 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12088 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12089 tmp2 = (tmp & 0x1f00) >> 8; 12090 tmp2 |= tmp2 << 5; 12091 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12092 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12093 tmp2 = tmp & 0x00ff; 12094 tmp2 |= tmp << 8; 12095 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12096 } 12097} 12098 12099struct bwn_b2062_freq { 12100 uint16_t freq; 12101 uint8_t value[6]; 12102}; 12103 12104static void 12105bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12106{ 12107#define CALC_CTL7(freq, div) \ 12108 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12109#define CALC_CTL18(freq, div) \ 12110 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12111#define CALC_CTL19(freq, div) \ 12112 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12113 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12114 struct siba_dev_softc *sd = mac->mac_sd; 12115 struct siba_softc *siba = sd->sd_bus; 12116 struct bwn_softc *sc = mac->mac_sc; 12117 struct ifnet *ifp = sc->sc_ifp; 12118 struct ieee80211com *ic = ifp->if_l2com; 12119 static const struct bwn_b2062_freq freqdata_tab[] = { 12120 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12121 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12122 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12123 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12124 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12125 { 19200, { 1, 1, 1, 1, 14, 9 } } 12126 }; 12127 static const struct bwn_wpair v1[] = { 12128 { BWN_B2062_N_TXCTL3, 0 }, 12129 { BWN_B2062_N_TXCTL4, 0 }, 12130 { BWN_B2062_N_TXCTL5, 0 }, 12131 { BWN_B2062_N_TXCTL6, 0 }, 12132 { BWN_B2062_N_PDNCTL0, 0x40 }, 12133 { BWN_B2062_N_PDNCTL0, 0 }, 12134 { BWN_B2062_N_CALIB_TS, 0x10 }, 12135 { BWN_B2062_N_CALIB_TS, 0 } 12136 }; 12137 const struct bwn_b2062_freq *f = NULL; 12138 uint32_t xtalfreq, ref; 12139 unsigned int i; 12140 12141 bwn_phy_lp_b2062_tblinit(mac); 12142 12143 for (i = 0; i < N(v1); i++) 12144 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12145 if (mac->mac_phy.rev > 0) 12146 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12147 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12148 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12149 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12150 else 12151 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12152 12153 KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU, 12154 ("%s:%d: fail", __func__, __LINE__)); 12155 xtalfreq = siba->siba_cc.scc_pmu.freq * 1000; 12156 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12157 12158 if (xtalfreq <= 30000000) { 12159 plp->plp_div = 1; 12160 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12161 } else { 12162 plp->plp_div = 2; 12163 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12164 } 12165 12166 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12167 CALC_CTL7(xtalfreq, plp->plp_div)); 12168 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12169 CALC_CTL18(xtalfreq, plp->plp_div)); 12170 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12171 CALC_CTL19(xtalfreq, plp->plp_div)); 12172 12173 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12174 ref &= 0xffff; 12175 for (i = 0; i < N(freqdata_tab); i++) { 12176 if (ref < freqdata_tab[i].freq) { 12177 f = &freqdata_tab[i]; 12178 break; 12179 } 12180 } 12181 if (f == NULL) 12182 f = &freqdata_tab[N(freqdata_tab) - 1]; 12183 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12184 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12185 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12186 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12187 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12188 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12189#undef CALC_CTL7 12190#undef CALC_CTL18 12191#undef CALC_CTL19 12192} 12193 12194static void 12195bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12196{ 12197 12198 bwn_phy_lp_b2063_tblinit(mac); 12199 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12200 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12201 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12202 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12203 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12204 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12205 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12206 if (mac->mac_phy.rev == 2) { 12207 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12208 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12209 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12210 } else { 12211 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12212 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12213 } 12214} 12215 12216static void 12217bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12218{ 12219 struct siba_dev_softc *sd = mac->mac_sd; 12220 struct siba_softc *siba = sd->sd_bus; 12221 static const struct bwn_wpair v1[] = { 12222 { BWN_B2063_RX_BB_SP8, 0x0 }, 12223 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12224 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12225 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12226 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12227 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12228 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12229 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12230 }; 12231 static const struct bwn_wpair v2[] = { 12232 { BWN_B2063_TX_BB_SP3, 0x0 }, 12233 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12234 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12235 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12236 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12237 }; 12238 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 12239 int i; 12240 uint8_t tmp; 12241 12242 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12243 12244 for (i = 0; i < 2; i++) 12245 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12246 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12247 for (i = 2; i < N(v1); i++) 12248 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12249 for (i = 0; i < 10000; i++) { 12250 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12251 break; 12252 DELAY(1000); 12253 } 12254 12255 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12256 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12257 12258 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12259 12260 for (i = 0; i < N(v2); i++) 12261 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12262 if (freqxtal == 24000000) { 12263 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12264 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12265 } else { 12266 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12267 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12268 } 12269 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12270 for (i = 0; i < 10000; i++) { 12271 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12272 break; 12273 DELAY(1000); 12274 } 12275 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12276 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12277 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12278} 12279 12280static void 12281bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12282{ 12283 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12284 struct bwn_softc *sc = mac->mac_sc; 12285 struct bwn_phy_lp_iq_est ie; 12286 struct bwn_txgain tx_gains; 12287 static const uint32_t pwrtbl[21] = { 12288 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12289 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12290 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12291 0x0004c, 0x0002c, 0x0001a, 12292 }; 12293 uint32_t npwr, ipwr, sqpwr, tmp; 12294 int loopback, i, j, sum, error; 12295 uint16_t save[7]; 12296 uint8_t txo, bbmult, txpctlmode; 12297 12298 error = bwn_phy_lp_switch_channel(mac, 7); 12299 if (error) 12300 device_printf(sc->sc_dev, 12301 "failed to change channel to 7 (%d)\n", error); 12302 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12303 bbmult = bwn_phy_lp_get_bbmult(mac); 12304 if (txo) 12305 tx_gains = bwn_phy_lp_get_txgain(mac); 12306 12307 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12308 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12309 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12310 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12311 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12312 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12313 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12314 12315 bwn_phy_lp_get_txpctlmode(mac); 12316 txpctlmode = plp->plp_txpctlmode; 12317 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12318 12319 /* disable CRS */ 12320 bwn_phy_lp_set_deaf(mac, 1); 12321 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12322 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12323 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12324 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12325 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12326 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12327 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12328 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12329 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12330 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12331 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12332 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12333 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12334 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12335 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12336 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12337 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12338 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12339 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12340 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12341 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12342 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12343 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12344 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12345 12346 loopback = bwn_phy_lp_loopback(mac); 12347 if (loopback == -1) 12348 goto done; 12349 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12350 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12351 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12352 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12353 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12354 12355 tmp = 0; 12356 memset(&ie, 0, sizeof(ie)); 12357 for (i = 128; i <= 159; i++) { 12358 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12359 sum = 0; 12360 for (j = 5; j <= 25; j++) { 12361 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12362 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12363 goto done; 12364 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12365 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12366 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12367 12); 12368 sum += ((ipwr - npwr) * (ipwr - npwr)); 12369 if ((i == 128) || (sum < tmp)) { 12370 plp->plp_rccap = i; 12371 tmp = sum; 12372 } 12373 } 12374 } 12375 bwn_phy_lp_ddfs_turnoff(mac); 12376done: 12377 /* restore CRS */ 12378 bwn_phy_lp_clear_deaf(mac, 1); 12379 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12380 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12381 12382 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12383 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12384 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12385 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12386 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12387 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12388 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12389 12390 bwn_phy_lp_set_bbmult(mac, bbmult); 12391 if (txo) 12392 bwn_phy_lp_set_txgain(mac, &tx_gains); 12393 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12394 if (plp->plp_rccap) 12395 bwn_phy_lp_set_rccap(mac); 12396} 12397 12398static void 12399bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12400{ 12401 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12402 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12403 12404 if (mac->mac_phy.rev == 1) 12405 rc_cap = MIN(rc_cap + 5, 15); 12406 12407 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12408 MAX(plp->plp_rccap - 4, 0x80)); 12409 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12410 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12411 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12412} 12413 12414static uint32_t 12415bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12416{ 12417 uint32_t i, q, r; 12418 12419 if (div == 0) 12420 return (0); 12421 12422 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12423 q <<= 1; 12424 if (r << 1 >= div) { 12425 q++; 12426 r = (r << 1) - div; 12427 } 12428 } 12429 if (r << 1 >= div) 12430 q++; 12431 return (q); 12432} 12433 12434static void 12435bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12436{ 12437 struct siba_dev_softc *sd = mac->mac_sd; 12438 struct siba_softc *siba = sd->sd_bus; 12439 12440 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12441 DELAY(20); 12442 if (siba->siba_chipid == 0x5354) { 12443 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12444 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12445 } else { 12446 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12447 } 12448 DELAY(5); 12449} 12450 12451static void 12452bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12453{ 12454 12455 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12456 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12457 DELAY(200); 12458} 12459 12460static void 12461bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12462{ 12463#define FLAG_A 0x01 12464#define FLAG_G 0x02 12465 struct bwn_softc *sc = mac->mac_sc; 12466 struct ifnet *ifp = sc->sc_ifp; 12467 struct ieee80211com *ic = ifp->if_l2com; 12468 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12469 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12470 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12471 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12472 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12473 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12474 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12475 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12476 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12477 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12478 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12479 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12480 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12481 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12482 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12483 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12484 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12485 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12486 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12487 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12488 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12489 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12490 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12491 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12492 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12493 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12494 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12495 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12496 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12497 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12498 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12499 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12500 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12501 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12502 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12503 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12504 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12505 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12506 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12507 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12508 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12509 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12510 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12511 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12512 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12513 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12514 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12515 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12516 }; 12517 const struct bwn_b206x_rfinit_entry *br; 12518 unsigned int i; 12519 12520 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12521 br = &bwn_b2062_init_tab[i]; 12522 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12523 if (br->br_flags & FLAG_G) 12524 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12525 } else { 12526 if (br->br_flags & FLAG_A) 12527 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12528 } 12529 } 12530#undef FLAG_A 12531#undef FLAG_B 12532} 12533 12534static void 12535bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12536{ 12537#define FLAG_A 0x01 12538#define FLAG_G 0x02 12539 struct bwn_softc *sc = mac->mac_sc; 12540 struct ifnet *ifp = sc->sc_ifp; 12541 struct ieee80211com *ic = ifp->if_l2com; 12542 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12543 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12544 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12545 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12546 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12547 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12548 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12549 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12550 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12551 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12552 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12553 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12554 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12555 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12556 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12557 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12558 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12559 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12560 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12561 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12562 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12563 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12564 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12565 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12566 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12567 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12568 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12569 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12570 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12571 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12572 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12573 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12574 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12575 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12576 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12577 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12578 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12579 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12580 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12581 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12582 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12583 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12584 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12585 }; 12586 const struct bwn_b206x_rfinit_entry *br; 12587 unsigned int i; 12588 12589 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12590 br = &bwn_b2063_init_tab[i]; 12591 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12592 if (br->br_flags & FLAG_G) 12593 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12594 } else { 12595 if (br->br_flags & FLAG_A) 12596 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12597 } 12598 } 12599#undef FLAG_A 12600#undef FLAG_B 12601} 12602 12603static void 12604bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12605 int count, void *_data) 12606{ 12607 unsigned int i; 12608 uint32_t offset, type; 12609 uint8_t *data = _data; 12610 12611 type = BWN_TAB_GETTYPE(typenoffset); 12612 offset = BWN_TAB_GETOFFSET(typenoffset); 12613 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12614 12615 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12616 12617 for (i = 0; i < count; i++) { 12618 switch (type) { 12619 case BWN_TAB_8BIT: 12620 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12621 data++; 12622 break; 12623 case BWN_TAB_16BIT: 12624 *((uint16_t *)data) = BWN_PHY_READ(mac, 12625 BWN_PHY_TABLEDATALO); 12626 data += 2; 12627 break; 12628 case BWN_TAB_32BIT: 12629 *((uint32_t *)data) = BWN_PHY_READ(mac, 12630 BWN_PHY_TABLEDATAHI); 12631 *((uint32_t *)data) <<= 16; 12632 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12633 BWN_PHY_TABLEDATALO); 12634 data += 4; 12635 break; 12636 default: 12637 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12638 } 12639 } 12640} 12641 12642static void 12643bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12644 int count, const void *_data) 12645{ 12646 uint32_t offset, type, value; 12647 const uint8_t *data = _data; 12648 unsigned int i; 12649 12650 type = BWN_TAB_GETTYPE(typenoffset); 12651 offset = BWN_TAB_GETOFFSET(typenoffset); 12652 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12653 12654 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12655 12656 for (i = 0; i < count; i++) { 12657 switch (type) { 12658 case BWN_TAB_8BIT: 12659 value = *data; 12660 data++; 12661 KASSERT(!(value & ~0xff), 12662 ("%s:%d: fail", __func__, __LINE__)); 12663 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12664 break; 12665 case BWN_TAB_16BIT: 12666 value = *((const uint16_t *)data); 12667 data += 2; 12668 KASSERT(!(value & ~0xffff), 12669 ("%s:%d: fail", __func__, __LINE__)); 12670 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12671 break; 12672 case BWN_TAB_32BIT: 12673 value = *((const uint32_t *)data); 12674 data += 4; 12675 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12676 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12677 break; 12678 default: 12679 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12680 } 12681 } 12682} 12683 12684static struct bwn_txgain 12685bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12686{ 12687 struct bwn_txgain tg; 12688 uint16_t tmp; 12689 12690 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12691 if (mac->mac_phy.rev < 2) { 12692 tmp = BWN_PHY_READ(mac, 12693 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12694 tg.tg_gm = tmp & 0x0007; 12695 tg.tg_pga = (tmp & 0x0078) >> 3; 12696 tg.tg_pad = (tmp & 0x780) >> 7; 12697 return (tg); 12698 } 12699 12700 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12701 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12702 tg.tg_gm = tmp & 0xff; 12703 tg.tg_pga = (tmp >> 8) & 0xff; 12704 return (tg); 12705} 12706 12707static uint8_t 12708bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12709{ 12710 12711 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12712} 12713 12714static void 12715bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12716{ 12717 uint16_t pa; 12718 12719 if (mac->mac_phy.rev < 2) { 12720 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12721 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12722 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12723 bwn_phy_lp_set_txgain_override(mac); 12724 return; 12725 } 12726 12727 pa = bwn_phy_lp_get_pa_gain(mac); 12728 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12729 (tg->tg_pga << 8) | tg->tg_gm); 12730 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12731 tg->tg_pad | (pa << 6)); 12732 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12733 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12734 tg->tg_pad | (pa << 8)); 12735 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12736 bwn_phy_lp_set_txgain_override(mac); 12737} 12738 12739static void 12740bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12741{ 12742 12743 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12744} 12745 12746static void 12747bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12748{ 12749 uint16_t trsw = (tx << 1) | rx; 12750 12751 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12752 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12753} 12754 12755static void 12756bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12757{ 12758 struct bwn_softc *sc = mac->mac_sc; 12759 struct ifnet *ifp = sc->sc_ifp; 12760 struct ieee80211com *ic = ifp->if_l2com; 12761 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12762 12763 if (mac->mac_phy.rev < 2) { 12764 trsw = gain & 0x1; 12765 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12766 ext_lna = (gain & 2) >> 1; 12767 12768 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12769 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12770 0xfbff, ext_lna << 10); 12771 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12772 0xf7ff, ext_lna << 11); 12773 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12774 } else { 12775 low_gain = gain & 0xffff; 12776 high_gain = (gain >> 16) & 0xf; 12777 ext_lna = (gain >> 21) & 0x1; 12778 trsw = ~(gain >> 20) & 0x1; 12779 12780 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12781 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12782 0xfdff, ext_lna << 9); 12783 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12784 0xfbff, ext_lna << 10); 12785 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12786 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12787 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12788 tmp = (gain >> 2) & 0x3; 12789 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12790 0xe7ff, tmp<<11); 12791 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12792 tmp << 3); 12793 } 12794 } 12795 12796 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12797 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12798 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12799 if (mac->mac_phy.rev >= 2) { 12800 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12801 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12802 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12803 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12804 } 12805 return; 12806 } 12807 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12808} 12809 12810static void 12811bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12812{ 12813 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12814 12815 if (user) 12816 plp->plp_crsusr_off = 1; 12817 else 12818 plp->plp_crssys_off = 1; 12819 12820 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12821} 12822 12823static void 12824bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12825{ 12826 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12827 struct bwn_softc *sc = mac->mac_sc; 12828 struct ifnet *ifp = sc->sc_ifp; 12829 struct ieee80211com *ic = ifp->if_l2com; 12830 12831 if (user) 12832 plp->plp_crsusr_off = 0; 12833 else 12834 plp->plp_crssys_off = 0; 12835 12836 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12837 return; 12838 12839 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12840 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12841 else 12842 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12843} 12844 12845static unsigned int 12846bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12847{ 12848 struct bwn_softc *sc = mac->mac_sc; 12849 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12850 static uint8_t sqrt_table[256] = { 12851 10, 14, 17, 20, 22, 24, 26, 28, 12852 30, 31, 33, 34, 36, 37, 38, 40, 12853 41, 42, 43, 44, 45, 46, 47, 48, 12854 50, 50, 51, 52, 53, 54, 55, 56, 12855 57, 58, 59, 60, 60, 61, 62, 63, 12856 64, 64, 65, 66, 67, 67, 68, 69, 12857 70, 70, 71, 72, 72, 73, 74, 74, 12858 75, 76, 76, 77, 78, 78, 79, 80, 12859 80, 81, 81, 82, 83, 83, 84, 84, 12860 85, 86, 86, 87, 87, 88, 88, 89, 12861 90, 90, 91, 91, 92, 92, 93, 93, 12862 94, 94, 95, 95, 96, 96, 97, 97, 12863 98, 98, 99, 100, 100, 100, 101, 101, 12864 102, 102, 103, 103, 104, 104, 105, 105, 12865 106, 106, 107, 107, 108, 108, 109, 109, 12866 110, 110, 110, 111, 111, 112, 112, 113, 12867 113, 114, 114, 114, 115, 115, 116, 116, 12868 117, 117, 117, 118, 118, 119, 119, 120, 12869 120, 120, 121, 121, 122, 122, 122, 123, 12870 123, 124, 124, 124, 125, 125, 126, 126, 12871 126, 127, 127, 128, 128, 128, 129, 129, 12872 130, 130, 130, 131, 131, 131, 132, 132, 12873 133, 133, 133, 134, 134, 134, 135, 135, 12874 136, 136, 136, 137, 137, 137, 138, 138, 12875 138, 139, 139, 140, 140, 140, 141, 141, 12876 141, 142, 142, 142, 143, 143, 143, 144, 12877 144, 144, 145, 145, 145, 146, 146, 146, 12878 147, 147, 147, 148, 148, 148, 149, 149, 12879 150, 150, 150, 150, 151, 151, 151, 152, 12880 152, 152, 153, 153, 153, 154, 154, 154, 12881 155, 155, 155, 156, 156, 156, 157, 157, 12882 157, 158, 158, 158, 159, 159, 159, 160 12883 }; 12884 12885 if (x == 0) 12886 return (0); 12887 if (x >= 256) { 12888 device_printf(sc->sc_dev, 12889 "out of bounds of the square-root table (%d)\n", x); 12890 return (16); 12891 } 12892 return (sqrt_table[x - 1] / 10); 12893} 12894 12895static int 12896bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12897{ 12898#define CALC_COEFF(_v, _x, _y, _z) do { \ 12899 int _t; \ 12900 _t = _x - 20; \ 12901 if (_t >= 0) { \ 12902 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12903 } else { \ 12904 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12905 } \ 12906} while (0) 12907#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12908 int _t; \ 12909 _t = _x - 11; \ 12910 if (_t >= 0) \ 12911 tmp[3] = (_y << (31 - _x)) / (_z >> _t); \ 12912 else \ 12913 tmp[3] = (_y << (31 - _x)) / (_z << -_t); \ 12914} while (0) 12915 struct bwn_phy_lp_iq_est ie; 12916 uint16_t v0, v1; 12917 int tmp[2], ret; 12918 12919 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12920 v0 = v1 >> 8; 12921 v1 |= 0xff; 12922 12923 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12924 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12925 12926 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12927 if (ret == 0) 12928 goto done; 12929 12930 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12931 ret = 0; 12932 goto done; 12933 } 12934 12935 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12936 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12937 12938 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12939 v0 = tmp[0] >> 3; 12940 v1 = tmp[1] >> 4; 12941done: 12942 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12943 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12944 return ret; 12945#undef CALC_COEFF 12946#undef CALC_COEFF2 12947} 12948 12949static void 12950bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12951{ 12952 static const uint16_t noisescale[] = { 12953 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12954 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12955 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12956 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12957 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12958 }; 12959 static const uint16_t crsgainnft[] = { 12960 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12961 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12962 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12963 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12964 0x013d, 12965 }; 12966 static const uint16_t filterctl[] = { 12967 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12968 0xff53, 0x0127, 12969 }; 12970 static const uint32_t psctl[] = { 12971 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12972 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12973 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12974 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12975 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12976 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12977 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12978 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12979 }; 12980 static const uint16_t ofdmcckgain_r0[] = { 12981 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12982 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12983 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12984 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12985 0x755d, 12986 }; 12987 static const uint16_t ofdmcckgain_r1[] = { 12988 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12989 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12990 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12991 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12992 0x755d, 12993 }; 12994 static const uint16_t gaindelta[] = { 12995 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12996 0x0000, 12997 }; 12998 static const uint32_t txpwrctl[] = { 12999 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 13000 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 13001 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 13002 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 13003 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 13004 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 13005 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 13006 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 13007 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 13008 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 13009 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 13010 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 13011 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 13012 0x00000000, 0x00000000, 0x00000000, 0x00000000, 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, 0x000075a0, 0x000075a0, 0x000075a1, 13038 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 13039 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 13040 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 13041 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 13042 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 13043 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 13044 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 13045 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 13046 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 13047 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 13048 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 13049 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 13050 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 13051 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 13052 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 13053 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 13054 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 13055 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 13056 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 13057 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 13058 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 13059 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 13060 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 13061 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 13062 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 13063 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13064 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13065 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13066 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13067 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13068 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13069 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13070 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13071 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13072 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13073 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13074 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13075 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13076 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13077 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13078 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13079 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13080 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13081 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13082 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13083 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13084 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13085 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13086 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13087 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13088 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13089 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13090 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13091 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13092 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13093 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13094 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13095 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13096 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13097 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13098 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13099 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13100 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13101 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13102 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13103 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13104 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13105 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13106 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13107 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13108 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13109 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13110 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13111 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13112 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13113 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13114 0x00000702, 13115 }; 13116 13117 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13118 13119 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13120 bwn_tab_sigsq_tbl); 13121 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13122 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13123 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13124 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13125 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13126 bwn_tab_pllfrac_tbl); 13127 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13128 bwn_tabl_iqlocal_tbl); 13129 if (mac->mac_phy.rev == 0) { 13130 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13131 ofdmcckgain_r0); 13132 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13133 ofdmcckgain_r0); 13134 } else { 13135 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13136 ofdmcckgain_r1); 13137 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13138 ofdmcckgain_r1); 13139 } 13140 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13141 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13142} 13143 13144static void 13145bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13146{ 13147 struct siba_dev_softc *sd = mac->mac_sd; 13148 struct siba_softc *siba = sd->sd_bus; 13149 int i; 13150 static const uint16_t noisescale[] = { 13151 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13152 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13153 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13154 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13155 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13156 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13157 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13158 }; 13159 static const uint32_t filterctl[] = { 13160 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13161 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13162 }; 13163 static const uint32_t psctl[] = { 13164 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13165 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13166 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13167 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13168 }; 13169 static const uint32_t gainidx[] = { 13170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13172 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13173 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13174 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13175 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13176 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13177 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13178 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13179 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13180 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13181 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13182 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13183 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13184 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13185 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13186 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13187 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13188 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13189 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13190 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13191 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13192 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13193 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13194 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13195 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13196 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13197 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13198 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13199 0x0000001a, 0x64ca55ad, 0x0000001a 13200 }; 13201 static const uint16_t auxgainidx[] = { 13202 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13203 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13204 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13205 0x0004, 0x0016 13206 }; 13207 static const uint16_t swctl[] = { 13208 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13209 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13210 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13211 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13212 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13213 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13214 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13215 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13216 }; 13217 static const uint8_t hf[] = { 13218 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13219 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13220 }; 13221 static const uint32_t gainval[] = { 13222 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13223 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13224 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13225 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13226 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13227 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13228 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13230 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13231 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13232 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13233 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13235 0x000000f1, 0x00000000, 0x00000000 13236 }; 13237 static const uint16_t gain[] = { 13238 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13239 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13240 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13241 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13242 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13243 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13244 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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 }; 13251 static const uint32_t papdeps[] = { 13252 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13253 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13254 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13255 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13256 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13257 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13258 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13259 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13260 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13261 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13262 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13263 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13264 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13265 }; 13266 static const uint32_t papdmult[] = { 13267 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13268 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13269 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13270 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13271 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13272 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13273 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13274 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13275 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13276 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13277 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13278 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13279 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13280 }; 13281 static const uint32_t gainidx_a0[] = { 13282 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13283 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13284 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13285 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13286 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13287 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13288 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13289 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13290 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13291 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13292 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13293 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13294 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13295 }; 13296 static const uint16_t auxgainidx_a0[] = { 13297 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13298 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13299 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13300 0x0002, 0x0014 13301 }; 13302 static const uint32_t gainval_a0[] = { 13303 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13304 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13305 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13306 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13307 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13308 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13309 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13310 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13311 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13312 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13313 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13314 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13315 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13316 0x000000f7, 0x00000000, 0x00000000 13317 }; 13318 static const uint16_t gain_a0[] = { 13319 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13320 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13321 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13322 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13323 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13324 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13325 0x0000, 0x0000, 0x0000, 0x0000, 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 }; 13332 13333 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13334 13335 for (i = 0; i < 704; i++) 13336 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13337 13338 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13339 bwn_tab_sigsq_tbl); 13340 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13341 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13342 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13343 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13344 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13345 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13346 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13347 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13348 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13349 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13350 bwn_tab_pllfrac_tbl); 13351 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13352 bwn_tabl_iqlocal_tbl); 13353 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13354 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13355 13356 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 13357 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13358 gainidx_a0); 13359 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13360 auxgainidx_a0); 13361 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13362 gainval_a0); 13363 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13364 } 13365} 13366 13367static void 13368bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13369{ 13370 struct siba_dev_softc *sd = mac->mac_sd; 13371 struct siba_softc *siba = sd->sd_bus; 13372 struct bwn_softc *sc = mac->mac_sc; 13373 struct ifnet *ifp = sc->sc_ifp; 13374 struct ieee80211com *ic = ifp->if_l2com; 13375 static struct bwn_txgain_entry txgain_r2[] = { 13376 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13377 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13378 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13379 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13380 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13381 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13382 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13383 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13384 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13385 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13386 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13387 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13388 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13389 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13390 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13391 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13392 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13393 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13394 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13395 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13396 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13397 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13398 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13399 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13400 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13401 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13402 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13403 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13404 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13405 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13406 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13407 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13408 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13409 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13410 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13411 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13412 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13413 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13414 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13415 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13416 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13417 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13418 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13419 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13420 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13421 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13422 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13423 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13424 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13425 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13426 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13427 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13428 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13429 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13430 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13431 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13432 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13433 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13434 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13435 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13436 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13437 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13438 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13439 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13440 }; 13441 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13442 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13443 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13444 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13445 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13446 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13447 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13448 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13449 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13450 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13451 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13452 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13453 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13454 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13455 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13456 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13457 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13458 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13459 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13460 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13461 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13462 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13463 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13464 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13465 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13466 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13467 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13468 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13469 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13470 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13471 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13472 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13473 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13474 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13475 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13476 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13477 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13478 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13479 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13480 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13481 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13482 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13483 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13484 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13485 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13486 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13487 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13488 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13489 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13490 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13491 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13492 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13493 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13494 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13495 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13496 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13497 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13498 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13499 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13500 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13501 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13502 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13503 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13504 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13505 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13506 }; 13507 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13508 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13509 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13510 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13511 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13512 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13513 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13514 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13515 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13516 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13517 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13518 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13519 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13520 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13521 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13522 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13523 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13524 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13525 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13526 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13527 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13528 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13529 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13530 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13531 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13532 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13533 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13534 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13535 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13536 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13537 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13538 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13539 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13540 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13541 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13542 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13543 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13544 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13545 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13546 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13547 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13548 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13549 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13550 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13551 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13552 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13553 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13554 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13555 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13556 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13557 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13558 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13559 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13560 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13561 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13562 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13563 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13564 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13565 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13566 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13567 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13568 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13569 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13570 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13571 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13572 }; 13573 static struct bwn_txgain_entry txgain_r0[] = { 13574 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13575 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13576 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13577 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13578 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13579 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13580 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13581 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13582 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13583 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13584 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13585 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13586 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13587 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13588 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13589 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13590 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13591 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13592 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13593 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13594 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13595 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13596 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13597 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13598 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13599 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13600 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13601 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13602 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13603 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13604 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13605 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13606 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13607 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13608 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13609 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13610 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13611 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13612 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13613 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13614 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13615 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13616 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13617 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13618 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13619 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13620 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13621 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13622 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13623 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13624 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13625 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13626 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13627 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13628 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13629 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13630 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13631 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13632 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13633 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13634 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13635 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13636 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13637 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13638 }; 13639 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13640 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13641 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13642 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13643 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13644 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13645 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13646 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13647 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13648 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13649 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13650 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13651 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13652 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13653 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13654 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13655 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13656 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13657 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13658 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13659 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13660 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13661 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13662 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13663 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13664 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13665 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13666 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13667 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13668 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13669 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13670 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13671 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13672 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13673 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13674 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13675 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13676 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13677 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13678 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13679 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13680 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13681 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13682 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13683 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13684 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13685 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13686 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13687 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13688 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13689 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13690 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13691 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13692 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13693 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13694 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13695 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13696 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13697 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13698 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13699 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13700 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13701 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13702 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13703 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13704 }; 13705 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13706 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13707 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13708 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13709 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13710 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13711 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13712 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13713 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13714 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13715 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13716 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13717 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13718 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13719 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13720 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13721 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13722 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13723 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13724 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13725 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13726 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13727 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13728 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13729 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13730 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13731 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13732 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13733 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13734 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13735 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13736 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13737 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13738 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13739 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13740 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13741 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13742 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13743 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13744 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13745 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13746 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13747 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13748 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13749 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13750 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13751 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13752 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13753 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13754 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13755 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13756 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13757 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13758 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13759 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13760 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13761 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13762 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13763 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13764 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13765 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13766 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13767 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13768 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13769 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13770 }; 13771 static struct bwn_txgain_entry txgain_r1[] = { 13772 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13773 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13774 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13775 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13776 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13777 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13778 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13779 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13780 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13781 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13782 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13783 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13784 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13785 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13786 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13787 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13788 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13789 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13790 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13791 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13792 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13793 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13794 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13795 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13796 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13797 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13798 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13799 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13800 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13801 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13802 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13803 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13804 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13805 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13806 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13807 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13808 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13809 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13810 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13811 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13812 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13813 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13814 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13815 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13816 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13817 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13818 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13819 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13820 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13821 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13822 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13823 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13824 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13825 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13826 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13827 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13828 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13829 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13830 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13831 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13832 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13833 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13834 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13835 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13836 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13837 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13838 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13839 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13840 { 7, 11, 6, 0, 71 } 13841 }; 13842 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13843 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13844 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13845 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13846 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13847 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13848 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13849 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13850 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13851 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13852 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13853 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13854 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13855 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13856 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13857 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13858 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13859 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13860 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13861 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13862 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13863 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13864 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13865 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13866 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13867 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13868 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13869 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13870 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13871 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13872 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13873 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13874 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13875 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13876 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13877 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13878 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13879 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13880 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13881 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13882 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13883 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13884 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13885 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13886 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13887 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13888 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13889 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13890 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13891 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13892 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13893 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13894 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13895 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13896 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13897 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13898 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13899 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13900 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13901 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13902 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13903 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13904 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13905 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13906 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13907 }; 13908 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13909 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13910 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13911 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13912 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13913 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13914 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13915 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13916 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13917 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13918 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13919 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13920 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13921 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13922 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13923 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13924 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13925 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13926 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13927 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13928 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13929 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13930 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13931 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13932 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13933 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13934 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13935 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13936 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13937 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13938 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13939 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13940 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13941 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13942 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13943 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13944 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13945 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13946 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13947 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13948 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13949 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13950 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13951 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13952 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13953 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13954 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13955 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13956 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13957 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13958 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13959 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13960 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13961 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13962 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13963 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13964 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13965 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13966 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13967 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13968 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13969 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13970 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13971 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13972 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13973 }; 13974 13975 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13976 if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA) 13977 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13978 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13979 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13980 txgain_2ghz_r2); 13981 else 13982 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13983 txgain_5ghz_r2); 13984 return; 13985 } 13986 13987 if (mac->mac_phy.rev == 0) { 13988 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 13989 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 13990 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13991 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13992 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13993 txgain_2ghz_r0); 13994 else 13995 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13996 txgain_5ghz_r0); 13997 return; 13998 } 13999 14000 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 14001 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 14002 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 14003 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 14004 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 14005 else 14006 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 14007} 14008 14009static void 14010bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 14011{ 14012 uint32_t offset, type; 14013 14014 type = BWN_TAB_GETTYPE(typeoffset); 14015 offset = BWN_TAB_GETOFFSET(typeoffset); 14016 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14017 14018 switch (type) { 14019 case BWN_TAB_8BIT: 14020 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 14021 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14022 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14023 break; 14024 case BWN_TAB_16BIT: 14025 KASSERT(!(value & ~0xffff), 14026 ("%s:%d: fail", __func__, __LINE__)); 14027 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14028 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14029 break; 14030 case BWN_TAB_32BIT: 14031 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14032 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 14033 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14034 break; 14035 default: 14036 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14037 } 14038} 14039 14040static int 14041bwn_phy_lp_loopback(struct bwn_mac *mac) 14042{ 14043 struct bwn_phy_lp_iq_est ie; 14044 int i, index = -1; 14045 uint32_t tmp; 14046 14047 memset(&ie, 0, sizeof(ie)); 14048 14049 bwn_phy_lp_set_trsw_over(mac, 1, 1); 14050 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 14051 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 14052 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 14053 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 14054 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 14055 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 14056 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 14057 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 14058 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 14059 for (i = 0; i < 32; i++) { 14060 bwn_phy_lp_set_rxgain_idx(mac, i); 14061 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 14062 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 14063 continue; 14064 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 14065 if ((tmp > 4000) && (tmp < 10000)) { 14066 index = i; 14067 break; 14068 } 14069 } 14070 bwn_phy_lp_ddfs_turnoff(mac); 14071 return (index); 14072} 14073 14074static void 14075bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 14076{ 14077 14078 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 14079} 14080 14081static void 14082bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 14083 int incr1, int incr2, int scale_idx) 14084{ 14085 14086 bwn_phy_lp_ddfs_turnoff(mac); 14087 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 14088 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 14089 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14090 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14091 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14092 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14093 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14094 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14095 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14096 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14097} 14098 14099static uint8_t 14100bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14101 struct bwn_phy_lp_iq_est *ie) 14102{ 14103 int i; 14104 14105 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14106 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14107 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14108 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14109 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14110 14111 for (i = 0; i < 500; i++) { 14112 if (!(BWN_PHY_READ(mac, 14113 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14114 break; 14115 DELAY(1000); 14116 } 14117 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14118 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14119 return 0; 14120 } 14121 14122 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14123 ie->ie_iqprod <<= 16; 14124 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14125 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14126 ie->ie_ipwr <<= 16; 14127 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14128 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14129 ie->ie_qpwr <<= 16; 14130 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14131 14132 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14133 return 1; 14134} 14135 14136static uint32_t 14137bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14138{ 14139 uint32_t offset, type, value; 14140 14141 type = BWN_TAB_GETTYPE(typeoffset); 14142 offset = BWN_TAB_GETOFFSET(typeoffset); 14143 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14144 14145 switch (type) { 14146 case BWN_TAB_8BIT: 14147 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14148 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14149 break; 14150 case BWN_TAB_16BIT: 14151 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14152 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14153 break; 14154 case BWN_TAB_32BIT: 14155 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14156 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14157 value <<= 16; 14158 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14159 break; 14160 default: 14161 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14162 value = 0; 14163 } 14164 14165 return (value); 14166} 14167 14168static void 14169bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14170{ 14171 14172 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14173 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14174} 14175 14176static void 14177bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14178{ 14179 uint16_t ctl; 14180 14181 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14182 ctl |= dac << 7; 14183 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14184} 14185 14186static void 14187bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14188{ 14189 14190 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14191 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14192} 14193 14194static void 14195bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14196{ 14197 14198 if (mac->mac_phy.rev < 2) 14199 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14200 else { 14201 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14202 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14203 } 14204 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14205} 14206 14207static uint16_t 14208bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14209{ 14210 14211 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14212} 14213 14214static uint8_t 14215bwn_nbits(int32_t val) 14216{ 14217 uint32_t tmp; 14218 uint8_t nbits = 0; 14219 14220 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14221 nbits++; 14222 return (nbits); 14223} 14224 14225static void 14226bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14227 struct bwn_txgain_entry *table) 14228{ 14229 int i; 14230 14231 for (i = offset; i < count; i++) 14232 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14233} 14234 14235static void 14236bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14237 struct bwn_txgain_entry data) 14238{ 14239 14240 if (mac->mac_phy.rev >= 2) 14241 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14242 else 14243 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14244} 14245 14246static void 14247bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14248 struct bwn_txgain_entry te) 14249{ 14250 struct bwn_softc *sc = mac->mac_sc; 14251 struct ifnet *ifp = sc->sc_ifp; 14252 struct ieee80211com *ic = ifp->if_l2com; 14253 uint32_t tmp; 14254 14255 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14256 14257 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14258 if (mac->mac_phy.rev >= 3) { 14259 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14260 (0x10 << 24) : (0x70 << 24)); 14261 } else { 14262 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14263 (0x14 << 24) : (0x7f << 24)); 14264 } 14265 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14266 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14267 te.te_bbmult << 20 | te.te_dac << 28); 14268} 14269 14270static void 14271bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14272 struct bwn_txgain_entry te) 14273{ 14274 14275 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14276 14277 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14278 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14279 te.te_dac); 14280 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14281} 14282 14283static void 14284bwn_sysctl_node(struct bwn_softc *sc) 14285{ 14286 device_t dev = sc->sc_dev; 14287 struct bwn_mac *mac; 14288 struct bwn_stats *stats; 14289 14290 /* XXX assume that count of MAC is only 1. */ 14291 14292 if ((mac = sc->sc_curmac) == NULL) 14293 return; 14294 stats = &mac->mac_stats; 14295 14296 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14297 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14298 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14299 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14300 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14301 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14302 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14303 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14304 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14305 14306#ifdef BWN_DEBUG 14307 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14308 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14309 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14310#endif 14311} 14312 14313static void 14314bwn_identify(driver_t *driver, device_t parent) 14315{ 14316 14317 BUS_ADD_CHILD(parent, 0, "bwn", -1); 14318} 14319 14320static device_method_t bwn_methods[] = { 14321 /* Device interface */ 14322 DEVMETHOD(device_identify, bwn_identify), 14323 DEVMETHOD(device_probe, bwn_probe), 14324 DEVMETHOD(device_attach, bwn_attach), 14325 DEVMETHOD(device_detach, bwn_detach), 14326 DEVMETHOD(device_suspend, bwn_suspend), 14327 DEVMETHOD(device_resume, bwn_resume), 14328 { 0,0 } 14329}; 14330static driver_t bwn_driver = { 14331 "bwn", 14332 bwn_methods, 14333 sizeof(struct bwn_softc) 14334}; 14335static devclass_t bwn_devclass; 14336DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14337MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14338MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14339MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14340MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14341