if_bwn.c revision 204257
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 204257 2010-02-23 19:55:54Z 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_SHPREAMBLE /* short preamble supported */ 1080 | IEEE80211_C_SHSLOT /* short slot time supported */ 1081 | IEEE80211_C_WME /* WME/WMM supported */ 1082 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1083 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1084 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1085 ; 1086 1087 /* call MI attach routine. */ 1088 ieee80211_ifattach(ic, 1089 bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a : 1090 sprom->mac_80211bg); 1091 1092 ic->ic_headroom = sizeof(struct bwn_txhdr); 1093 1094 /* override default methods */ 1095 ic->ic_raw_xmit = bwn_raw_xmit; 1096 ic->ic_newassoc = bwn_newassoc; 1097 ic->ic_updateslot = bwn_updateslot; 1098 ic->ic_update_promisc = bwn_update_promisc; 1099 ic->ic_wme.wme_update = bwn_wme_update; 1100 1101 ic->ic_node_alloc = bwn_node_alloc; 1102 sc->sc_node_cleanup = ic->ic_node_cleanup; 1103 ic->ic_node_cleanup = bwn_node_cleanup; 1104 1105 ic->ic_scan_start = bwn_scan_start; 1106 ic->ic_scan_end = bwn_scan_end; 1107 ic->ic_set_channel = bwn_set_channel; 1108 1109 ic->ic_vap_create = bwn_vap_create; 1110 ic->ic_vap_delete = bwn_vap_delete; 1111 1112 ieee80211_radiotap_attach(ic, 1113 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1114 BWN_TX_RADIOTAP_PRESENT, 1115 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1116 BWN_RX_RADIOTAP_PRESENT); 1117 1118 bwn_sysctl_node(sc); 1119 1120 if (bootverbose) 1121 ieee80211_announce(ic); 1122 return (0); 1123} 1124 1125static void 1126bwn_phy_detach(struct bwn_mac *mac) 1127{ 1128 1129 if (mac->mac_phy.detach != NULL) 1130 mac->mac_phy.detach(mac); 1131} 1132 1133static int 1134bwn_detach(device_t dev) 1135{ 1136 struct bwn_softc *sc = device_get_softc(dev); 1137 struct bwn_mac *mac = sc->sc_curmac; 1138 struct ifnet *ifp = sc->sc_ifp; 1139 struct ieee80211com *ic = ifp->if_l2com; 1140 int i; 1141 1142 sc->sc_flags |= BWN_FLAG_INVALID; 1143 1144 if (device_is_attached(sc->sc_dev)) { 1145 bwn_stop(sc, 1); 1146 bwn_dma_free(mac); 1147 callout_drain(&sc->sc_led_blink_ch); 1148 callout_drain(&sc->sc_rfswitch_ch); 1149 callout_drain(&sc->sc_task_ch); 1150 callout_drain(&sc->sc_watchdog_ch); 1151 bwn_phy_detach(mac); 1152 if (ifp != NULL) { 1153 ieee80211_draintask(ic, &mac->mac_hwreset); 1154 ieee80211_draintask(ic, &mac->mac_txpower); 1155 ieee80211_ifdetach(ic); 1156 if_free(ifp); 1157 } 1158 } 1159 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1160 taskqueue_free(sc->sc_tq); 1161 1162 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1163 if (mac->mac_intrhand[i] != NULL) { 1164 bus_teardown_intr(dev, mac->mac_res_irq[i], 1165 mac->mac_intrhand[i]); 1166 mac->mac_intrhand[i] = NULL; 1167 } 1168 } 1169 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1170 if (mac->mac_msi != 0) 1171 pci_release_msi(dev); 1172 1173 BWN_LOCK_DESTROY(sc); 1174 return (0); 1175} 1176 1177static int 1178bwn_attach_pre(struct bwn_softc *sc) 1179{ 1180 struct ifnet *ifp; 1181 int error = 0; 1182 1183 BWN_LOCK_INIT(sc); 1184 TAILQ_INIT(&sc->sc_maclist); 1185 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1186 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1187 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1188 1189 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1190 taskqueue_thread_enqueue, &sc->sc_tq); 1191 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1192 "%s taskq", device_get_nameunit(sc->sc_dev)); 1193 1194 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1195 if (ifp == NULL) { 1196 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1197 error = ENOSPC; 1198 goto fail; 1199 } 1200 1201 /* set these up early for if_printf use */ 1202 if_initname(ifp, device_get_name(sc->sc_dev), 1203 device_get_unit(sc->sc_dev)); 1204 1205 ifp->if_softc = sc; 1206 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1207 ifp->if_init = bwn_init; 1208 ifp->if_ioctl = bwn_ioctl; 1209 ifp->if_start = bwn_start; 1210 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 1211 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 1212 IFQ_SET_READY(&ifp->if_snd); 1213 1214 return (0); 1215 1216fail: BWN_LOCK_DESTROY(sc); 1217 return (error); 1218} 1219 1220static void 1221bwn_sprom_bugfixes(struct siba_softc *siba) 1222{ 1223#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1224 ((siba->siba_pci_vid == PCI_VENDOR_##_vendor) && \ 1225 (siba->siba_pci_did == _device) && \ 1226 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) && \ 1227 (siba->siba_pci_subdid == _subdevice)) 1228 1229 if (siba->siba_board_vendor == PCI_VENDOR_APPLE && 1230 siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40) 1231 siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL; 1232 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL && 1233 siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74) 1234 siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST; 1235 if (siba->siba_type == SIBA_TYPE_PCI) { 1236 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1237 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1238 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1239 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1240 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1241 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1242 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1243 siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST; 1244 } 1245#undef BWN_ISDEV 1246} 1247 1248static int 1249bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1250{ 1251#define IS_RUNNING(ifp) \ 1252 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1253 struct bwn_softc *sc = ifp->if_softc; 1254 struct ieee80211com *ic = ifp->if_l2com; 1255 struct ifreq *ifr = (struct ifreq *)data; 1256 int error = 0, startall; 1257 1258 switch (cmd) { 1259 case SIOCSIFFLAGS: 1260 startall = 0; 1261 if (IS_RUNNING(ifp)) { 1262 bwn_update_promisc(ifp); 1263 } else if (ifp->if_flags & IFF_UP) { 1264 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1265 bwn_init(sc); 1266 startall = 1; 1267 } 1268 } else 1269 bwn_stop(sc, 1); 1270 if (startall) 1271 ieee80211_start_all(ic); 1272 break; 1273 case SIOCGIFMEDIA: 1274 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1275 break; 1276 case SIOCGIFADDR: 1277 error = ether_ioctl(ifp, cmd, data); 1278 break; 1279 default: 1280 error = EINVAL; 1281 break; 1282 } 1283 return (error); 1284} 1285 1286static void 1287bwn_start(struct ifnet *ifp) 1288{ 1289 struct bwn_softc *sc = ifp->if_softc; 1290 1291 BWN_LOCK(sc); 1292 bwn_start_locked(ifp); 1293 BWN_UNLOCK(sc); 1294} 1295 1296static void 1297bwn_start_locked(struct ifnet *ifp) 1298{ 1299 struct bwn_softc *sc = ifp->if_softc; 1300 struct bwn_mac *mac = sc->sc_curmac; 1301 struct ieee80211_frame *wh; 1302 struct ieee80211_node *ni; 1303 struct ieee80211_key *k; 1304 struct mbuf *m; 1305 1306 BWN_ASSERT_LOCKED(sc); 1307 1308 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1309 mac->mac_status < BWN_MAC_STATUS_STARTED) 1310 return; 1311 1312 for (;;) { 1313 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1314 if (m == NULL) 1315 break; 1316 1317 if (bwn_tx_isfull(sc, m)) 1318 break; 1319 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1320 if (ni == NULL) { 1321 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1322 m_freem(m); 1323 ifp->if_oerrors++; 1324 continue; 1325 } 1326 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1327 wh = mtod(m, struct ieee80211_frame *); 1328 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1329 k = ieee80211_crypto_encap(ni, m); 1330 if (k == NULL) { 1331 ieee80211_free_node(ni); 1332 m_freem(m); 1333 ifp->if_oerrors++; 1334 continue; 1335 } 1336 } 1337 wh = NULL; /* Catch any invalid use */ 1338 1339 if (bwn_tx_start(sc, ni, m) != 0) { 1340 if (ni != NULL) 1341 ieee80211_free_node(ni); 1342 ifp->if_oerrors++; 1343 continue; 1344 } 1345 1346 sc->sc_watchdog_timer = 5; 1347 } 1348} 1349 1350static int 1351bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1352{ 1353 struct bwn_dma_ring *dr; 1354 struct bwn_mac *mac = sc->sc_curmac; 1355 struct bwn_pio_txqueue *tq; 1356 struct ifnet *ifp = sc->sc_ifp; 1357 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1358 1359 BWN_ASSERT_LOCKED(sc); 1360 1361 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1362 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1363 if (dr->dr_stop == 1 || 1364 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1365 dr->dr_stop = 1; 1366 goto full; 1367 } 1368 } else { 1369 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1370 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1371 pktlen > (tq->tq_size - tq->tq_used)) { 1372 tq->tq_stop = 1; 1373 goto full; 1374 } 1375 } 1376 return (0); 1377full: 1378 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1379 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1380 return (1); 1381} 1382 1383static int 1384bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1385{ 1386 struct bwn_mac *mac = sc->sc_curmac; 1387 int error; 1388 1389 BWN_ASSERT_LOCKED(sc); 1390 1391 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1392 m_freem(m); 1393 return (ENXIO); 1394 } 1395 1396 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1397 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1398 if (error) { 1399 m_freem(m); 1400 return (error); 1401 } 1402 return (0); 1403} 1404 1405static int 1406bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1407{ 1408 struct bwn_pio_txpkt *tp; 1409 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1410 struct bwn_softc *sc = mac->mac_sc; 1411 struct bwn_txhdr txhdr; 1412 struct mbuf *m_new; 1413 uint32_t ctl32; 1414 int error; 1415 uint16_t ctl16; 1416 1417 BWN_ASSERT_LOCKED(sc); 1418 1419 /* XXX TODO send packets after DTIM */ 1420 1421 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1422 tp = TAILQ_FIRST(&tq->tq_pktlist); 1423 tp->tp_ni = ni; 1424 tp->tp_m = m; 1425 1426 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1427 if (error) { 1428 device_printf(sc->sc_dev, "tx fail\n"); 1429 return (error); 1430 } 1431 1432 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1433 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1434 tq->tq_free--; 1435 1436 if (mac->mac_sd->sd_id.sd_rev >= 8) { 1437 /* 1438 * XXX please removes m_defrag(9) 1439 */ 1440 m_new = m_defrag(m, M_DONTWAIT); 1441 if (m_new == NULL) { 1442 device_printf(sc->sc_dev, 1443 "%s: can't defrag TX buffer\n", 1444 __func__); 1445 return (ENOBUFS); 1446 } 1447 if (m_new->m_next != NULL) 1448 device_printf(sc->sc_dev, 1449 "TODO: fragmented packets for PIO\n"); 1450 tp->tp_m = m_new; 1451 1452 /* send HEADER */ 1453 ctl32 = bwn_pio_write_multi_4(mac, tq, 1454 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1455 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1456 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1457 /* send BODY */ 1458 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1459 mtod(m_new, const void *), m_new->m_pkthdr.len); 1460 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1461 ctl32 | BWN_PIO8_TXCTL_EOF); 1462 } else { 1463 ctl16 = bwn_pio_write_multi_2(mac, tq, 1464 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1465 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1466 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1467 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1468 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1469 ctl16 | BWN_PIO_TXCTL_EOF); 1470 } 1471 1472 return (0); 1473} 1474 1475static struct bwn_pio_txqueue * 1476bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1477{ 1478 1479 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1480 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1481 1482 switch (prio) { 1483 case 0: 1484 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1485 case 1: 1486 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1487 case 2: 1488 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1489 case 3: 1490 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1491 } 1492 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1493 return (NULL); 1494} 1495 1496static int 1497bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1498{ 1499#define BWN_GET_TXHDRCACHE(slot) \ 1500 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1501 struct bwn_dma *dma = &mac->mac_method.dma; 1502 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1503 struct bwn_dmadesc_generic *desc; 1504 struct bwn_dmadesc_meta *mt; 1505 struct bwn_softc *sc = mac->mac_sc; 1506 struct ifnet *ifp = sc->sc_ifp; 1507 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1508 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1509 1510 BWN_ASSERT_LOCKED(sc); 1511 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1512 1513 /* XXX send after DTIM */ 1514 1515 slot = bwn_dma_getslot(dr); 1516 dr->getdesc(dr, slot, &desc, &mt); 1517 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1518 ("%s:%d: fail", __func__, __LINE__)); 1519 1520 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1521 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1522 BWN_DMA_COOKIE(dr, slot)); 1523 if (error) 1524 goto fail; 1525 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1526 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1527 &mt->mt_paddr, BUS_DMA_NOWAIT); 1528 if (error) { 1529 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1530 __func__, error); 1531 goto fail; 1532 } 1533 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1534 BUS_DMASYNC_PREWRITE); 1535 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1536 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1537 BUS_DMASYNC_PREWRITE); 1538 1539 slot = bwn_dma_getslot(dr); 1540 dr->getdesc(dr, slot, &desc, &mt); 1541 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1542 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1543 mt->mt_m = m; 1544 mt->mt_ni = ni; 1545 1546 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1547 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1548 if (error && error != EFBIG) { 1549 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1550 __func__, error); 1551 goto fail; 1552 } 1553 if (error) { /* error == EFBIG */ 1554 struct mbuf *m_new; 1555 1556 m_new = m_defrag(m, M_DONTWAIT); 1557 if (m_new == NULL) { 1558 if_printf(ifp, "%s: can't defrag TX buffer\n", 1559 __func__); 1560 error = ENOBUFS; 1561 goto fail; 1562 } else { 1563 m = m_new; 1564 } 1565 1566 mt->mt_m = m; 1567 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1568 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1569 if (error) { 1570 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1571 __func__, error); 1572 goto fail; 1573 } 1574 } 1575 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1576 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1577 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1578 BUS_DMASYNC_PREWRITE); 1579 1580 /* XXX send after DTIM */ 1581 1582 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1583 return (0); 1584fail: 1585 dr->dr_curslot = backup[0]; 1586 dr->dr_usedslot = backup[1]; 1587 return (error); 1588#undef BWN_GET_TXHDRCACHE 1589} 1590 1591static void 1592bwn_watchdog(void *arg) 1593{ 1594 struct bwn_softc *sc = arg; 1595 struct ifnet *ifp = sc->sc_ifp; 1596 1597 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1598 if_printf(ifp, "device timeout\n"); 1599 ifp->if_oerrors++; 1600 } 1601 callout_schedule(&sc->sc_watchdog_ch, hz); 1602} 1603 1604static int 1605bwn_attach_core(struct bwn_mac *mac) 1606{ 1607 struct bwn_softc *sc = mac->mac_sc; 1608 struct siba_dev_softc *sd = mac->mac_sd; 1609 struct siba_softc *siba = sd->sd_bus; 1610 int error, have_bg = 0, have_a = 0; 1611 uint32_t high; 1612 1613 KASSERT(sd->sd_id.sd_rev >= 5, 1614 ("unsupported revision %d", sd->sd_id.sd_rev)); 1615 1616 siba_powerup(siba, 0); 1617 1618 high = siba_read_4(sd, SIBA_TGSHIGH); 1619 bwn_reset_core(mac, 1620 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1621 error = bwn_phy_getinfo(mac, high); 1622 if (error) 1623 goto fail; 1624 1625 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1626 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1627 if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 && 1628 siba->siba_pci_did != 0x4324) { 1629 have_a = have_bg = 0; 1630 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1631 have_a = 1; 1632 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1633 mac->mac_phy.type == BWN_PHYTYPE_N || 1634 mac->mac_phy.type == BWN_PHYTYPE_LP) 1635 have_bg = 1; 1636 else 1637 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1638 mac->mac_phy.type)); 1639 } 1640 /* XXX turns off PHY A because it's not supported */ 1641 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1642 mac->mac_phy.type != BWN_PHYTYPE_N) { 1643 have_a = 0; 1644 have_bg = 1; 1645 } 1646 1647 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1648 mac->mac_phy.attach = bwn_phy_g_attach; 1649 mac->mac_phy.detach = bwn_phy_g_detach; 1650 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1651 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1652 mac->mac_phy.init = bwn_phy_g_init; 1653 mac->mac_phy.exit = bwn_phy_g_exit; 1654 mac->mac_phy.phy_read = bwn_phy_g_read; 1655 mac->mac_phy.phy_write = bwn_phy_g_write; 1656 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1657 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1658 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1659 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1660 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1661 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1662 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1663 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1664 mac->mac_phy.set_im = bwn_phy_g_im; 1665 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1666 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1667 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1668 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1669 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1670 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1671 mac->mac_phy.init = bwn_phy_lp_init; 1672 mac->mac_phy.phy_read = bwn_phy_lp_read; 1673 mac->mac_phy.phy_write = bwn_phy_lp_write; 1674 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1675 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1676 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1677 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1678 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1679 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1680 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1681 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1682 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1683 } else { 1684 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1685 mac->mac_phy.type); 1686 error = ENXIO; 1687 goto fail; 1688 } 1689 1690 mac->mac_phy.gmode = have_bg; 1691 if (mac->mac_phy.attach != NULL) { 1692 error = mac->mac_phy.attach(mac); 1693 if (error) { 1694 device_printf(sc->sc_dev, "failed\n"); 1695 goto fail; 1696 } 1697 } 1698 1699 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1700 1701 error = bwn_chiptest(mac); 1702 if (error) 1703 goto fail; 1704 error = bwn_setup_channels(mac, have_bg, have_a); 1705 if (error) { 1706 device_printf(sc->sc_dev, "failed to setup channels\n"); 1707 goto fail; 1708 } 1709 1710 if (sc->sc_curmac == NULL) 1711 sc->sc_curmac = mac; 1712 1713 error = bwn_dma_attach(mac); 1714 if (error != 0) { 1715 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1716 goto fail; 1717 } 1718 1719 mac->mac_phy.switch_analog(mac, 0); 1720 1721 siba_dev_down(sd, 0); 1722fail: 1723 siba_powerdown(siba); 1724 return (error); 1725} 1726 1727static void 1728bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1729{ 1730 struct siba_dev_softc *sd = mac->mac_sd; 1731 uint32_t low, ctl; 1732 1733 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1734 1735 siba_dev_up(sd, flags); 1736 DELAY(2000); 1737 1738 low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1739 ~BWN_TGSLOW_PHYRESET; 1740 siba_write_4(sd, SIBA_TGSLOW, low); 1741 siba_read_4(sd, SIBA_TGSLOW); 1742 DELAY(1000); 1743 siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1744 siba_read_4(sd, SIBA_TGSLOW); 1745 DELAY(1000); 1746 1747 if (mac->mac_phy.switch_analog != NULL) 1748 mac->mac_phy.switch_analog(mac, 1); 1749 1750 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1751 if (flags & BWN_TGSLOW_SUPPORT_G) 1752 ctl |= BWN_MACCTL_GMODE; 1753 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1754} 1755 1756static int 1757bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1758{ 1759 struct bwn_phy *phy = &mac->mac_phy; 1760 struct bwn_softc *sc = mac->mac_sc; 1761 struct siba_dev_softc *sd = mac->mac_sd; 1762 struct siba_softc *siba = sd->sd_bus; 1763 uint32_t tmp; 1764 1765 /* PHY */ 1766 tmp = BWN_READ_2(mac, BWN_PHYVER); 1767 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1768 phy->rf_on = 1; 1769 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1770 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1771 phy->rev = (tmp & BWN_PHYVER_VERSION); 1772 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1773 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1774 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1775 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1776 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1777 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1778 goto unsupphy; 1779 1780 /* RADIO */ 1781 if (siba->siba_chipid == 0x4317) { 1782 if (siba->siba_chiprev == 0) 1783 tmp = 0x3205017f; 1784 else if (siba->siba_chiprev == 1) 1785 tmp = 0x4205017f; 1786 else 1787 tmp = 0x5205017f; 1788 } else { 1789 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1790 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1791 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1792 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1793 } 1794 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1795 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1796 phy->rf_manuf = (tmp & 0x00000fff); 1797 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1798 goto unsupradio; 1799 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1800 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1801 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1802 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1803 (phy->type == BWN_PHYTYPE_N && 1804 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1805 (phy->type == BWN_PHYTYPE_LP && 1806 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1807 goto unsupradio; 1808 1809 return (0); 1810unsupphy: 1811 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1812 "analog %#x)\n", 1813 phy->type, phy->rev, phy->analog); 1814 return (ENXIO); 1815unsupradio: 1816 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1817 "rev %#x)\n", 1818 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1819 return (ENXIO); 1820} 1821 1822static int 1823bwn_chiptest(struct bwn_mac *mac) 1824{ 1825#define TESTVAL0 0x55aaaa55 1826#define TESTVAL1 0xaa5555aa 1827 struct bwn_softc *sc = mac->mac_sc; 1828 struct siba_dev_softc *sd = mac->mac_sd; 1829 uint32_t v, backup; 1830 1831 BWN_LOCK(sc); 1832 1833 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1834 1835 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1836 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1837 goto error; 1838 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1839 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1840 goto error; 1841 1842 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1843 1844 if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) { 1845 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1846 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1847 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1848 goto error; 1849 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1850 goto error; 1851 } 1852 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1853 1854 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1855 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1856 goto error; 1857 1858 BWN_UNLOCK(sc); 1859 return (0); 1860error: 1861 BWN_UNLOCK(sc); 1862 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1863 return (ENODEV); 1864} 1865 1866#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1867#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1868 1869static int 1870bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1871{ 1872 struct bwn_softc *sc = mac->mac_sc; 1873 struct ifnet *ifp = sc->sc_ifp; 1874 struct ieee80211com *ic = ifp->if_l2com; 1875 1876 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1877 ic->ic_nchans = 0; 1878 1879 if (have_bg) 1880 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1881 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1882 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1883 if (have_a) 1884 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1885 &ic->ic_nchans, &bwn_chantable_n, 1886 IEEE80211_CHAN_HTA); 1887 } else { 1888 if (have_a) 1889 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1890 &ic->ic_nchans, &bwn_chantable_a, 1891 IEEE80211_CHAN_A); 1892 } 1893 1894 mac->mac_phy.supports_2ghz = have_bg; 1895 mac->mac_phy.supports_5ghz = have_a; 1896 1897 return (ic->ic_nchans == 0 ? ENXIO : 0); 1898} 1899 1900static uint32_t 1901bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1902{ 1903 uint32_t ret; 1904 1905 BWN_ASSERT_LOCKED(mac->mac_sc); 1906 1907 if (way == BWN_SHARED) { 1908 KASSERT((offset & 0x0001) == 0, 1909 ("%s:%d warn", __func__, __LINE__)); 1910 if (offset & 0x0003) { 1911 bwn_shm_ctlword(mac, way, offset >> 2); 1912 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1913 ret <<= 16; 1914 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1915 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1916 goto out; 1917 } 1918 offset >>= 2; 1919 } 1920 bwn_shm_ctlword(mac, way, offset); 1921 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1922out: 1923 return (ret); 1924} 1925 1926static uint16_t 1927bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1928{ 1929 uint16_t ret; 1930 1931 BWN_ASSERT_LOCKED(mac->mac_sc); 1932 1933 if (way == BWN_SHARED) { 1934 KASSERT((offset & 0x0001) == 0, 1935 ("%s:%d warn", __func__, __LINE__)); 1936 if (offset & 0x0003) { 1937 bwn_shm_ctlword(mac, way, offset >> 2); 1938 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1939 goto out; 1940 } 1941 offset >>= 2; 1942 } 1943 bwn_shm_ctlword(mac, way, offset); 1944 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1945out: 1946 1947 return (ret); 1948} 1949 1950static void 1951bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1952 uint16_t offset) 1953{ 1954 uint32_t control; 1955 1956 control = way; 1957 control <<= 16; 1958 control |= offset; 1959 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1960} 1961 1962static void 1963bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1964 uint32_t value) 1965{ 1966 BWN_ASSERT_LOCKED(mac->mac_sc); 1967 1968 if (way == BWN_SHARED) { 1969 KASSERT((offset & 0x0001) == 0, 1970 ("%s:%d warn", __func__, __LINE__)); 1971 if (offset & 0x0003) { 1972 bwn_shm_ctlword(mac, way, offset >> 2); 1973 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1974 (value >> 16) & 0xffff); 1975 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1976 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1977 return; 1978 } 1979 offset >>= 2; 1980 } 1981 bwn_shm_ctlword(mac, way, offset); 1982 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1983} 1984 1985static void 1986bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1987 uint16_t value) 1988{ 1989 BWN_ASSERT_LOCKED(mac->mac_sc); 1990 1991 if (way == BWN_SHARED) { 1992 KASSERT((offset & 0x0001) == 0, 1993 ("%s:%d warn", __func__, __LINE__)); 1994 if (offset & 0x0003) { 1995 bwn_shm_ctlword(mac, way, offset >> 2); 1996 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1997 return; 1998 } 1999 offset >>= 2; 2000 } 2001 bwn_shm_ctlword(mac, way, offset); 2002 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 2003} 2004 2005static void 2006bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 2007 int txpow) 2008{ 2009 2010 c->ic_freq = freq; 2011 c->ic_flags = flags; 2012 c->ic_ieee = ieee; 2013 c->ic_minpower = 0; 2014 c->ic_maxpower = 2 * txpow; 2015 c->ic_maxregpower = txpow; 2016} 2017 2018static void 2019bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2020 const struct bwn_channelinfo *ci, int flags) 2021{ 2022 struct ieee80211_channel *c; 2023 int i; 2024 2025 c = &chans[*nchans]; 2026 2027 for (i = 0; i < ci->nchannels; i++) { 2028 const struct bwn_channel *hc; 2029 2030 hc = &ci->channels[i]; 2031 if (*nchans >= maxchans) 2032 break; 2033 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2034 c++, (*nchans)++; 2035 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2036 /* g channel have a separate b-only entry */ 2037 if (*nchans >= maxchans) 2038 break; 2039 c[0] = c[-1]; 2040 c[-1].ic_flags = IEEE80211_CHAN_B; 2041 c++, (*nchans)++; 2042 } 2043 if (flags == IEEE80211_CHAN_HTG) { 2044 /* HT g channel have a separate g-only entry */ 2045 if (*nchans >= maxchans) 2046 break; 2047 c[-1].ic_flags = IEEE80211_CHAN_G; 2048 c[0] = c[-1]; 2049 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2050 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2051 c++, (*nchans)++; 2052 } 2053 if (flags == IEEE80211_CHAN_HTA) { 2054 /* HT a channel have a separate a-only entry */ 2055 if (*nchans >= maxchans) 2056 break; 2057 c[-1].ic_flags = IEEE80211_CHAN_A; 2058 c[0] = c[-1]; 2059 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2060 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2061 c++, (*nchans)++; 2062 } 2063 } 2064} 2065 2066static int 2067bwn_phy_g_attach(struct bwn_mac *mac) 2068{ 2069 struct bwn_softc *sc = mac->mac_sc; 2070 struct bwn_phy *phy = &mac->mac_phy; 2071 struct bwn_phy_g *pg = &phy->phy_g; 2072 struct siba_dev_softc *sd = mac->mac_sd; 2073 struct siba_sprom *sprom = &sd->sd_bus->siba_sprom; 2074 unsigned int i; 2075 int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1), 2076 pab2 = (int16_t)(sprom->pa0b2); 2077 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2078 int8_t bg = (int8_t)sprom->tssi_bg; 2079 2080 if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050)) 2081 device_printf(sc->sc_dev, "not supported anymore\n"); 2082 2083 pg->pg_flags = 0; 2084 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2085 pab2 == -1) { 2086 pg->pg_idletssi = 52; 2087 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2088 return (0); 2089 } 2090 2091 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2092 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2093 if (pg->pg_tssi2dbm == NULL) { 2094 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2095 return (ENOMEM); 2096 } 2097 for (i = 0; i < 64; i++) { 2098 int32_t m1, m2, f, q, delta; 2099 int8_t j = 0; 2100 2101 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2102 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2103 f = 256; 2104 2105 do { 2106 if (j > 15) { 2107 device_printf(sc->sc_dev, 2108 "failed to generate tssi2dBm\n"); 2109 free(pg->pg_tssi2dbm, M_DEVBUF); 2110 return (ENOMEM); 2111 } 2112 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2113 f, 2048); 2114 delta = abs(q - f); 2115 f = q; 2116 j++; 2117 } while (delta >= 2); 2118 2119 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2120 128); 2121 } 2122 2123 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2124 return (0); 2125} 2126 2127static void 2128bwn_phy_g_detach(struct bwn_mac *mac) 2129{ 2130 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2131 2132 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2133 free(pg->pg_tssi2dbm, M_DEVBUF); 2134 pg->pg_tssi2dbm = NULL; 2135 } 2136 pg->pg_flags = 0; 2137} 2138 2139static void 2140bwn_phy_g_init_pre(struct bwn_mac *mac) 2141{ 2142 struct bwn_phy *phy = &mac->mac_phy; 2143 struct bwn_phy_g *pg = &phy->phy_g; 2144 void *tssi2dbm; 2145 int idletssi; 2146 unsigned int i; 2147 2148 tssi2dbm = pg->pg_tssi2dbm; 2149 idletssi = pg->pg_idletssi; 2150 2151 memset(pg, 0, sizeof(*pg)); 2152 2153 pg->pg_tssi2dbm = tssi2dbm; 2154 pg->pg_idletssi = idletssi; 2155 2156 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2157 2158 for (i = 0; i < N(pg->pg_nrssi); i++) 2159 pg->pg_nrssi[i] = -1000; 2160 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2161 pg->pg_nrssi_lt[i] = i; 2162 pg->pg_lofcal = 0xffff; 2163 pg->pg_initval = 0xffff; 2164 pg->pg_immode = BWN_IMMODE_NONE; 2165 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2166 pg->pg_avgtssi = 0xff; 2167 2168 pg->pg_loctl.tx_bias = 0xff; 2169 TAILQ_INIT(&pg->pg_loctl.calib_list); 2170} 2171 2172static int 2173bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2174{ 2175 struct bwn_phy *phy = &mac->mac_phy; 2176 struct bwn_phy_g *pg = &phy->phy_g; 2177 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2178 struct siba_softc *bus = mac->mac_sd->sd_bus; 2179 static const struct bwn_rfatt rfatt0[] = { 2180 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2181 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2182 { 3, 1 }, { 4, 1 } 2183 }; 2184 static const struct bwn_rfatt rfatt1[] = { 2185 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2186 { 14, 1 } 2187 }; 2188 static const struct bwn_rfatt rfatt2[] = { 2189 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2190 { 9, 1 } 2191 }; 2192 static const struct bwn_bbatt bbatt_0[] = { 2193 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2194 }; 2195 2196 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2197 2198 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2199 pg->pg_bbatt.att = 0; 2200 else 2201 pg->pg_bbatt.att = 2; 2202 2203 /* prepare Radio Attenuation */ 2204 pg->pg_rfatt.padmix = 0; 2205 2206 if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 2207 bus->siba_board_type == SIBA_BOARD_BCM4309G) { 2208 if (bus->siba_board_rev < 0x43) { 2209 pg->pg_rfatt.att = 2; 2210 goto done; 2211 } else if (bus->siba_board_rev < 0x51) { 2212 pg->pg_rfatt.att = 3; 2213 goto done; 2214 } 2215 } 2216 2217 if (phy->type == BWN_PHYTYPE_A) { 2218 pg->pg_rfatt.att = 0x60; 2219 goto done; 2220 } 2221 2222 switch (phy->rf_ver) { 2223 case 0x2050: 2224 switch (phy->rf_rev) { 2225 case 0: 2226 pg->pg_rfatt.att = 5; 2227 goto done; 2228 case 1: 2229 if (phy->type == BWN_PHYTYPE_G) { 2230 if (bus->siba_board_vendor == 2231 SIBA_BOARDVENDOR_BCM && 2232 bus->siba_board_type == 2233 SIBA_BOARD_BCM4309G && 2234 bus->siba_board_rev >= 30) 2235 pg->pg_rfatt.att = 3; 2236 else if (bus->siba_board_vendor == 2237 SIBA_BOARDVENDOR_BCM && 2238 bus->siba_board_type == SIBA_BOARD_BU4306) 2239 pg->pg_rfatt.att = 3; 2240 else 2241 pg->pg_rfatt.att = 1; 2242 } else { 2243 if (bus->siba_board_vendor == 2244 SIBA_BOARDVENDOR_BCM && 2245 bus->siba_board_type == 2246 SIBA_BOARD_BCM4309G && 2247 bus->siba_board_rev >= 30) 2248 pg->pg_rfatt.att = 7; 2249 else 2250 pg->pg_rfatt.att = 6; 2251 } 2252 goto done; 2253 case 2: 2254 if (phy->type == BWN_PHYTYPE_G) { 2255 if (bus->siba_board_vendor == 2256 SIBA_BOARDVENDOR_BCM && 2257 bus->siba_board_type == 2258 SIBA_BOARD_BCM4309G && 2259 bus->siba_board_rev >= 30) 2260 pg->pg_rfatt.att = 3; 2261 else if (bus->siba_board_vendor == 2262 SIBA_BOARDVENDOR_BCM && 2263 bus->siba_board_type == SIBA_BOARD_BU4306) 2264 pg->pg_rfatt.att = 5; 2265 else if (bus->siba_chipid == 0x4320) 2266 pg->pg_rfatt.att = 4; 2267 else 2268 pg->pg_rfatt.att = 3; 2269 } else 2270 pg->pg_rfatt.att = 6; 2271 goto done; 2272 case 3: 2273 pg->pg_rfatt.att = 5; 2274 goto done; 2275 case 4: 2276 case 5: 2277 pg->pg_rfatt.att = 1; 2278 goto done; 2279 case 6: 2280 case 7: 2281 pg->pg_rfatt.att = 5; 2282 goto done; 2283 case 8: 2284 pg->pg_rfatt.att = 0xa; 2285 pg->pg_rfatt.padmix = 1; 2286 goto done; 2287 case 9: 2288 default: 2289 pg->pg_rfatt.att = 5; 2290 goto done; 2291 } 2292 break; 2293 case 0x2053: 2294 switch (phy->rf_rev) { 2295 case 1: 2296 pg->pg_rfatt.att = 6; 2297 goto done; 2298 } 2299 break; 2300 } 2301 pg->pg_rfatt.att = 5; 2302done: 2303 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2304 2305 if (!bwn_has_hwpctl(mac)) { 2306 lo->rfatt.array = rfatt0; 2307 lo->rfatt.len = N(rfatt0); 2308 lo->rfatt.min = 0; 2309 lo->rfatt.max = 9; 2310 goto genbbatt; 2311 } 2312 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2313 lo->rfatt.array = rfatt1; 2314 lo->rfatt.len = N(rfatt1); 2315 lo->rfatt.min = 0; 2316 lo->rfatt.max = 14; 2317 goto genbbatt; 2318 } 2319 lo->rfatt.array = rfatt2; 2320 lo->rfatt.len = N(rfatt2); 2321 lo->rfatt.min = 0; 2322 lo->rfatt.max = 9; 2323genbbatt: 2324 lo->bbatt.array = bbatt_0; 2325 lo->bbatt.len = N(bbatt_0); 2326 lo->bbatt.min = 0; 2327 lo->bbatt.max = 8; 2328 2329 BWN_READ_4(mac, BWN_MACCTL); 2330 if (phy->rev == 1) { 2331 phy->gmode = 0; 2332 bwn_reset_core(mac, 0); 2333 bwn_phy_g_init_sub(mac); 2334 phy->gmode = 1; 2335 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2336 } 2337 return (0); 2338} 2339 2340static uint16_t 2341bwn_phy_g_txctl(struct bwn_mac *mac) 2342{ 2343 struct bwn_phy *phy = &mac->mac_phy; 2344 2345 if (phy->rf_ver != 0x2050) 2346 return (0); 2347 if (phy->rf_rev == 1) 2348 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2349 if (phy->rf_rev < 6) 2350 return (BWN_TXCTL_PA2DB); 2351 if (phy->rf_rev == 8) 2352 return (BWN_TXCTL_TXMIX); 2353 return (0); 2354} 2355 2356static int 2357bwn_phy_g_init(struct bwn_mac *mac) 2358{ 2359 2360 bwn_phy_g_init_sub(mac); 2361 return (0); 2362} 2363 2364static void 2365bwn_phy_g_exit(struct bwn_mac *mac) 2366{ 2367 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2368 struct bwn_lo_calib *cal, *tmp; 2369 2370 if (lo == NULL) 2371 return; 2372 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2373 TAILQ_REMOVE(&lo->calib_list, cal, list); 2374 free(cal, M_DEVBUF); 2375 } 2376} 2377 2378static uint16_t 2379bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2380{ 2381 2382 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2383 return (BWN_READ_2(mac, BWN_PHYDATA)); 2384} 2385 2386static void 2387bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2388{ 2389 2390 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2391 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2392} 2393 2394static uint16_t 2395bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2396{ 2397 2398 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2399 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2400 return (BWN_READ_2(mac, BWN_RFDATALO)); 2401} 2402 2403static void 2404bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2405{ 2406 2407 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2408 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2409 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2410} 2411 2412static int 2413bwn_phy_g_hwpctl(struct bwn_mac *mac) 2414{ 2415 2416 return (mac->mac_phy.rev >= 6); 2417} 2418 2419static void 2420bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2421{ 2422 struct bwn_phy *phy = &mac->mac_phy; 2423 struct bwn_phy_g *pg = &phy->phy_g; 2424 unsigned int channel; 2425 uint16_t rfover, rfoverval; 2426 2427 if (on) { 2428 if (phy->rf_on) 2429 return; 2430 2431 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2432 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2433 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2434 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2435 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2436 pg->pg_radioctx_over); 2437 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2438 pg->pg_radioctx_overval); 2439 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2440 } 2441 channel = phy->chan; 2442 bwn_phy_g_switch_chan(mac, 6, 1); 2443 bwn_phy_g_switch_chan(mac, channel, 0); 2444 return; 2445 } 2446 2447 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2448 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2449 pg->pg_radioctx_over = rfover; 2450 pg->pg_radioctx_overval = rfoverval; 2451 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2452 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2453 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2454} 2455 2456static int 2457bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2458{ 2459 2460 if ((newchan < 1) || (newchan > 14)) 2461 return (EINVAL); 2462 bwn_phy_g_switch_chan(mac, newchan, 0); 2463 2464 return (0); 2465} 2466 2467static uint32_t 2468bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2469{ 2470 2471 return (1); 2472} 2473 2474static void 2475bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2476{ 2477 struct bwn_phy *phy = &mac->mac_phy; 2478 uint64_t hf; 2479 int autodiv = 0; 2480 uint16_t tmp; 2481 2482 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2483 autodiv = 1; 2484 2485 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2486 bwn_hf_write(mac, hf); 2487 2488 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2489 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2490 ((autodiv ? BWN_ANTAUTO1 : antenna) 2491 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2492 2493 if (autodiv) { 2494 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2495 if (antenna == BWN_ANTAUTO1) 2496 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2497 else 2498 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2499 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2500 } 2501 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2502 if (autodiv) 2503 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2504 else 2505 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2506 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2507 if (phy->rev >= 2) { 2508 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2509 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2510 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2511 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2512 0x15); 2513 if (phy->rev == 2) 2514 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2515 else 2516 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2517 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2518 8); 2519 } 2520 if (phy->rev >= 6) 2521 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2522 2523 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2524 bwn_hf_write(mac, hf); 2525} 2526 2527static int 2528bwn_phy_g_im(struct bwn_mac *mac, int mode) 2529{ 2530 struct bwn_phy *phy = &mac->mac_phy; 2531 struct bwn_phy_g *pg = &phy->phy_g; 2532 2533 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2534 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2535 2536 if (phy->rev == 0 || !phy->gmode) 2537 return (ENODEV); 2538 2539 pg->pg_aci_wlan_automatic = 0; 2540 return (0); 2541} 2542 2543static int 2544bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2545{ 2546 struct bwn_phy *phy = &mac->mac_phy; 2547 struct bwn_phy_g *pg = &phy->phy_g; 2548 struct bwn_softc *sc = mac->mac_sc; 2549 struct siba_softc *siba = mac->mac_sd->sd_bus; 2550 unsigned int tssi; 2551 int cck, ofdm; 2552 int power; 2553 int rfatt, bbatt; 2554 unsigned int max; 2555 2556 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2557 2558 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2559 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2560 if (cck < 0 && ofdm < 0) { 2561 if (ignore_tssi == 0) 2562 return (BWN_TXPWR_RES_DONE); 2563 cck = 0; 2564 ofdm = 0; 2565 } 2566 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2567 if (pg->pg_avgtssi != 0xff) 2568 tssi = (tssi + pg->pg_avgtssi) / 2; 2569 pg->pg_avgtssi = tssi; 2570 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2571 2572 max = siba->siba_sprom.maxpwr_bg; 2573 if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL) 2574 max -= 3; 2575 if (max >= 120) { 2576 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2577 siba->siba_sprom.maxpwr_bg = max = 80; 2578 } 2579 2580 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2581 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2582 tssi, 0x00), 0x3f)]); 2583 if (power == 0) 2584 return (BWN_TXPWR_RES_DONE); 2585 2586 rfatt = -((power + 7) / 8); 2587 bbatt = (-(power / 2)) - (4 * rfatt); 2588 if ((rfatt == 0) && (bbatt == 0)) 2589 return (BWN_TXPWR_RES_DONE); 2590 pg->pg_bbatt_delta = bbatt; 2591 pg->pg_rfatt_delta = rfatt; 2592 return (BWN_TXPWR_RES_NEED_ADJUST); 2593} 2594 2595static void 2596bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2597{ 2598 struct bwn_phy *phy = &mac->mac_phy; 2599 struct bwn_phy_g *pg = &phy->phy_g; 2600 struct bwn_softc *sc = mac->mac_sc; 2601 int rfatt, bbatt; 2602 uint8_t txctl; 2603 2604 bwn_mac_suspend(mac); 2605 2606 BWN_ASSERT_LOCKED(sc); 2607 2608 bbatt = pg->pg_bbatt.att; 2609 bbatt += pg->pg_bbatt_delta; 2610 rfatt = pg->pg_rfatt.att; 2611 rfatt += pg->pg_rfatt_delta; 2612 2613 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2614 txctl = pg->pg_txctl; 2615 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2616 if (rfatt <= 1) { 2617 if (txctl == 0) { 2618 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2619 rfatt += 2; 2620 bbatt += 2; 2621 } else if (mac->mac_sd->sd_bus->siba_sprom. 2622 bf_lo & 2623 BWN_BFL_PACTRL) { 2624 bbatt += 4 * (rfatt - 2); 2625 rfatt = 2; 2626 } 2627 } else if (rfatt > 4 && txctl) { 2628 txctl = 0; 2629 if (bbatt < 3) { 2630 rfatt -= 3; 2631 bbatt += 2; 2632 } else { 2633 rfatt -= 2; 2634 bbatt -= 2; 2635 } 2636 } 2637 } 2638 pg->pg_txctl = txctl; 2639 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2640 pg->pg_rfatt.att = rfatt; 2641 pg->pg_bbatt.att = bbatt; 2642 2643 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2644 2645 bwn_phy_lock(mac); 2646 bwn_rf_lock(mac); 2647 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2648 pg->pg_txctl); 2649 bwn_rf_unlock(mac); 2650 bwn_phy_unlock(mac); 2651 2652 bwn_mac_enable(mac); 2653} 2654 2655static void 2656bwn_phy_g_task_15s(struct bwn_mac *mac) 2657{ 2658 struct bwn_phy *phy = &mac->mac_phy; 2659 struct bwn_phy_g *pg = &phy->phy_g; 2660 struct bwn_softc *sc = mac->mac_sc; 2661 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2662 unsigned long expire, now; 2663 struct bwn_lo_calib *cal, *tmp; 2664 uint8_t expired = 0; 2665 2666 bwn_mac_suspend(mac); 2667 2668 if (lo == NULL) 2669 goto fail; 2670 2671 BWN_GETTIME(now); 2672 if (bwn_has_hwpctl(mac)) { 2673 expire = now - BWN_LO_PWRVEC_EXPIRE; 2674 if (time_before(lo->pwr_vec_read_time, expire)) { 2675 bwn_lo_get_powervector(mac); 2676 bwn_phy_g_dc_lookup_init(mac, 0); 2677 } 2678 goto fail; 2679 } 2680 2681 expire = now - BWN_LO_CALIB_EXPIRE; 2682 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2683 if (!time_before(cal->calib_time, expire)) 2684 continue; 2685 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2686 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2687 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2688 expired = 1; 2689 } 2690 2691 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2692 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2693 cal->ctl.i, cal->ctl.q); 2694 2695 TAILQ_REMOVE(&lo->calib_list, cal, list); 2696 free(cal, M_DEVBUF); 2697 } 2698 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2699 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2700 &pg->pg_rfatt); 2701 if (cal == NULL) { 2702 device_printf(sc->sc_dev, 2703 "failed to recalibrate LO\n"); 2704 goto fail; 2705 } 2706 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2707 bwn_lo_write(mac, &cal->ctl); 2708 } 2709 2710fail: 2711 bwn_mac_enable(mac); 2712} 2713 2714static void 2715bwn_phy_g_task_60s(struct bwn_mac *mac) 2716{ 2717 struct bwn_phy *phy = &mac->mac_phy; 2718 uint8_t old = phy->chan; 2719 2720 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) 2721 return; 2722 2723 bwn_mac_suspend(mac); 2724 bwn_nrssi_slope_11g(mac); 2725 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2726 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2727 bwn_switch_channel(mac, old); 2728 } 2729 bwn_mac_enable(mac); 2730} 2731 2732static void 2733bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2734{ 2735 2736 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2737} 2738 2739static int 2740bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2741 const struct ieee80211_bpf_params *params) 2742{ 2743 struct ieee80211com *ic = ni->ni_ic; 2744 struct ifnet *ifp = ic->ic_ifp; 2745 struct bwn_softc *sc = ifp->if_softc; 2746 struct bwn_mac *mac = sc->sc_curmac; 2747 2748 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2749 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2750 ieee80211_free_node(ni); 2751 m_freem(m); 2752 return (ENETDOWN); 2753 } 2754 2755 BWN_LOCK(sc); 2756 if (bwn_tx_isfull(sc, m)) { 2757 ieee80211_free_node(ni); 2758 m_freem(m); 2759 ifp->if_oerrors++; 2760 BWN_UNLOCK(sc); 2761 return (ENOBUFS); 2762 } 2763 2764 if (bwn_tx_start(sc, ni, m) != 0) { 2765 if (ni != NULL) 2766 ieee80211_free_node(ni); 2767 ifp->if_oerrors++; 2768 } 2769 sc->sc_watchdog_timer = 5; 2770 BWN_UNLOCK(sc); 2771 return (0); 2772} 2773 2774/* 2775 * Setup driver-specific state for a newly associated node. 2776 * Note that we're called also on a re-associate, the isnew 2777 * param tells us if this is the first time or not. 2778 */ 2779static void 2780bwn_newassoc(struct ieee80211_node *ni, int isnew) 2781{ 2782 struct ieee80211vap *vap = ni->ni_vap; 2783 2784 ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr, 2785 &BWN_NODE(ni)->bn_amn, ni); 2786} 2787 2788/* 2789 * Callback from the 802.11 layer to update the slot time 2790 * based on the current setting. We use it to notify the 2791 * firmware of ERP changes and the f/w takes care of things 2792 * like slot time and preamble. 2793 */ 2794static void 2795bwn_updateslot(struct ifnet *ifp) 2796{ 2797 struct bwn_softc *sc = ifp->if_softc; 2798 struct ieee80211com *ic = ifp->if_l2com; 2799 struct bwn_mac *mac; 2800 2801 BWN_LOCK(sc); 2802 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2803 mac = (struct bwn_mac *)sc->sc_curmac; 2804 bwn_set_slot_time(mac, 2805 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2806 } 2807 BWN_UNLOCK(sc); 2808} 2809 2810/* 2811 * Callback from the 802.11 layer after a promiscuous mode change. 2812 * Note this interface does not check the operating mode as this 2813 * is an internal callback and we are expected to honor the current 2814 * state (e.g. this is used for setting the interface in promiscuous 2815 * mode when operating in hostap mode to do ACS). 2816 */ 2817static void 2818bwn_update_promisc(struct ifnet *ifp) 2819{ 2820 struct bwn_softc *sc = ifp->if_softc; 2821 struct bwn_mac *mac = sc->sc_curmac; 2822 2823 BWN_LOCK(sc); 2824 mac = sc->sc_curmac; 2825 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2826 if (ifp->if_flags & IFF_PROMISC) 2827 sc->sc_filters |= BWN_MACCTL_PROMISC; 2828 else 2829 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2830 bwn_set_opmode(mac); 2831 } 2832 BWN_UNLOCK(sc); 2833} 2834 2835/* 2836 * Callback from the 802.11 layer to update WME parameters. 2837 */ 2838static int 2839bwn_wme_update(struct ieee80211com *ic) 2840{ 2841 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2842 struct bwn_mac *mac = sc->sc_curmac; 2843 struct wmeParams *wmep; 2844 int i; 2845 2846 BWN_LOCK(sc); 2847 mac = sc->sc_curmac; 2848 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2849 bwn_mac_suspend(mac); 2850 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2851 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2852 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2853 } 2854 bwn_mac_enable(mac); 2855 } 2856 BWN_UNLOCK(sc); 2857 return (0); 2858} 2859 2860static struct ieee80211_node * 2861bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2862{ 2863 struct ieee80211com *ic = vap->iv_ic; 2864 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2865 const size_t space = sizeof(struct bwn_node); 2866 struct bwn_node *bn; 2867 2868 bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO); 2869 if (bn == NULL) { 2870 /* XXX stat+msg */ 2871 return (NULL); 2872 } 2873 DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn); 2874 return (&bn->bn_node); 2875} 2876 2877static void 2878bwn_node_cleanup(struct ieee80211_node *ni) 2879{ 2880 struct ieee80211com *ic = ni->ni_ic; 2881 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2882 2883 sc->sc_node_cleanup(ni); 2884} 2885 2886static void 2887bwn_scan_start(struct ieee80211com *ic) 2888{ 2889 struct ifnet *ifp = ic->ic_ifp; 2890 struct bwn_softc *sc = ifp->if_softc; 2891 struct bwn_mac *mac; 2892 2893 BWN_LOCK(sc); 2894 mac = sc->sc_curmac; 2895 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2896 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2897 bwn_set_opmode(mac); 2898 /* disable CFP update during scan */ 2899 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2900 } 2901 BWN_UNLOCK(sc); 2902} 2903 2904static void 2905bwn_scan_end(struct ieee80211com *ic) 2906{ 2907 struct ifnet *ifp = ic->ic_ifp; 2908 struct bwn_softc *sc = ifp->if_softc; 2909 struct bwn_mac *mac; 2910 2911 BWN_LOCK(sc); 2912 mac = sc->sc_curmac; 2913 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2914 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2915 bwn_set_opmode(mac); 2916 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2917 } 2918 BWN_UNLOCK(sc); 2919} 2920 2921static void 2922bwn_set_channel(struct ieee80211com *ic) 2923{ 2924 struct ifnet *ifp = ic->ic_ifp; 2925 struct bwn_softc *sc = ifp->if_softc; 2926 struct bwn_mac *mac = sc->sc_curmac; 2927 struct bwn_phy *phy = &mac->mac_phy; 2928 int chan, error; 2929 2930 BWN_LOCK(sc); 2931 2932 error = bwn_switch_band(sc, ic->ic_curchan); 2933 if (error) 2934 goto fail;; 2935 bwn_mac_suspend(mac); 2936 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2937 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2938 if (chan != phy->chan) 2939 bwn_switch_channel(mac, chan); 2940 2941 /* TX power level */ 2942 if (ic->ic_curchan->ic_maxpower != 0 && 2943 ic->ic_curchan->ic_maxpower != phy->txpower) { 2944 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2945 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2946 BWN_TXPWR_IGNORE_TSSI); 2947 } 2948 2949 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2950 if (phy->set_antenna) 2951 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2952 2953 if (sc->sc_rf_enabled != phy->rf_on) { 2954 if (sc->sc_rf_enabled) { 2955 bwn_rf_turnon(mac); 2956 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2957 device_printf(sc->sc_dev, 2958 "please turns on the RF switch\n"); 2959 } else 2960 bwn_rf_turnoff(mac); 2961 } 2962 2963 bwn_mac_enable(mac); 2964 2965fail: 2966 /* 2967 * Setup radio tap channel freq and flags 2968 */ 2969 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2970 htole16(ic->ic_curchan->ic_freq); 2971 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2972 htole16(ic->ic_curchan->ic_flags & 0xffff); 2973 2974 BWN_UNLOCK(sc); 2975} 2976 2977static struct ieee80211vap * 2978bwn_vap_create(struct ieee80211com *ic, 2979 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2980 const uint8_t bssid[IEEE80211_ADDR_LEN], 2981 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2982{ 2983 struct ifnet *ifp = ic->ic_ifp; 2984 struct bwn_softc *sc = ifp->if_softc; 2985 struct ieee80211vap *vap; 2986 struct bwn_vap *bvp; 2987 uint8_t mac[IEEE80211_ADDR_LEN]; 2988 2989 IEEE80211_ADDR_COPY(mac, mac0); 2990 switch (opmode) { 2991 case IEEE80211_M_HOSTAP: 2992 case IEEE80211_M_MBSS: 2993 case IEEE80211_M_STA: 2994 case IEEE80211_M_WDS: 2995 case IEEE80211_M_MONITOR: 2996 case IEEE80211_M_IBSS: 2997 case IEEE80211_M_AHDEMO: 2998 break; 2999 default: 3000 return (NULL); 3001 } 3002 3003 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 3004 3005 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 3006 M_80211_VAP, M_NOWAIT | M_ZERO); 3007 if (bvp == NULL) { 3008 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 3009 return (NULL); 3010 } 3011 vap = &bvp->bv_vap; 3012 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 3013 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 3014 /* override with driver methods */ 3015 bvp->bv_newstate = vap->iv_newstate; 3016 vap->iv_newstate = bwn_newstate; 3017 3018 /* override max aid so sta's cannot assoc when we're out of sta id's */ 3019 vap->iv_max_aid = BWN_STAID_MAX; 3020 3021 ieee80211_amrr_init(&bvp->bv_amrr, vap, 3022 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 3023 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 3024 500 /*ms*/); 3025 3026 /* complete setup */ 3027 ieee80211_vap_attach(vap, ieee80211_media_change, 3028 ieee80211_media_status); 3029 return (vap); 3030} 3031 3032static void 3033bwn_vap_delete(struct ieee80211vap *vap) 3034{ 3035 struct bwn_vap *bvp = BWN_VAP(vap); 3036 3037 ieee80211_amrr_cleanup(&bvp->bv_amrr); 3038 ieee80211_vap_detach(vap); 3039 free(bvp, M_80211_VAP); 3040} 3041 3042static void 3043bwn_init(void *arg) 3044{ 3045 struct bwn_softc *sc = arg; 3046 struct ifnet *ifp = sc->sc_ifp; 3047 struct ieee80211com *ic = ifp->if_l2com; 3048 int error = 0; 3049 3050 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3051 __func__, ifp->if_flags); 3052 3053 BWN_LOCK(sc); 3054 error = bwn_init_locked(sc); 3055 BWN_UNLOCK(sc); 3056 3057 if (error == 0) 3058 ieee80211_start_all(ic); /* start all vap's */ 3059} 3060 3061static int 3062bwn_init_locked(struct bwn_softc *sc) 3063{ 3064 struct bwn_mac *mac; 3065 struct ifnet *ifp = sc->sc_ifp; 3066 int error; 3067 3068 BWN_ASSERT_LOCKED(sc); 3069 3070 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3071 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3072 sc->sc_filters = 0; 3073 bwn_wme_clear(sc); 3074 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3075 sc->sc_rf_enabled = 1; 3076 3077 mac = sc->sc_curmac; 3078 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3079 error = bwn_core_init(mac); 3080 if (error != 0) 3081 return (error); 3082 } 3083 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3084 bwn_core_start(mac); 3085 3086 bwn_set_opmode(mac); 3087 bwn_set_pretbtt(mac); 3088 bwn_spu_setdelay(mac, 0); 3089 bwn_set_macaddr(mac); 3090 3091 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3092 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3093 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3094 3095 return (0); 3096} 3097 3098static void 3099bwn_stop(struct bwn_softc *sc, int statechg) 3100{ 3101 3102 BWN_LOCK(sc); 3103 bwn_stop_locked(sc, statechg); 3104 BWN_UNLOCK(sc); 3105} 3106 3107static void 3108bwn_stop_locked(struct bwn_softc *sc, int statechg) 3109{ 3110 struct bwn_mac *mac = sc->sc_curmac; 3111 struct ifnet *ifp = sc->sc_ifp; 3112 3113 BWN_ASSERT_LOCKED(sc); 3114 3115 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3116 /* XXX FIXME opmode not based on VAP */ 3117 bwn_set_opmode(mac); 3118 bwn_set_macaddr(mac); 3119 } 3120 3121 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3122 bwn_core_stop(mac); 3123 3124 callout_stop(&sc->sc_led_blink_ch); 3125 sc->sc_led_blinking = 0; 3126 3127 bwn_core_exit(mac); 3128 sc->sc_rf_enabled = 0; 3129 3130 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3131} 3132 3133static void 3134bwn_wme_clear(struct bwn_softc *sc) 3135{ 3136#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3137 struct wmeParams *p; 3138 unsigned int i; 3139 3140 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3141 ("%s:%d: fail", __func__, __LINE__)); 3142 3143 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3144 p = &(sc->sc_wmeParams[i]); 3145 3146 switch (bwn_wme_shm_offsets[i]) { 3147 case BWN_WME_VOICE: 3148 p->wmep_txopLimit = 0; 3149 p->wmep_aifsn = 2; 3150 /* XXX FIXME: log2(cwmin) */ 3151 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3152 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3153 break; 3154 case BWN_WME_VIDEO: 3155 p->wmep_txopLimit = 0; 3156 p->wmep_aifsn = 2; 3157 /* XXX FIXME: log2(cwmin) */ 3158 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3159 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3160 break; 3161 case BWN_WME_BESTEFFORT: 3162 p->wmep_txopLimit = 0; 3163 p->wmep_aifsn = 3; 3164 /* XXX FIXME: log2(cwmin) */ 3165 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3166 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3167 break; 3168 case BWN_WME_BACKGROUND: 3169 p->wmep_txopLimit = 0; 3170 p->wmep_aifsn = 7; 3171 /* XXX FIXME: log2(cwmin) */ 3172 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3173 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3174 break; 3175 default: 3176 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3177 } 3178 } 3179} 3180 3181static int 3182bwn_core_init(struct bwn_mac *mac) 3183{ 3184#ifdef BWN_DEBUG 3185 struct bwn_softc *sc = mac->mac_sc; 3186#endif 3187 struct siba_dev_softc *sd = mac->mac_sd; 3188 struct siba_softc *siba = sd->sd_bus; 3189 struct siba_sprom *sprom = &siba->siba_sprom; 3190 uint64_t hf; 3191 int error; 3192 3193 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3194 ("%s:%d: fail", __func__, __LINE__)); 3195 3196 siba_powerup(siba, 0); 3197 if (!siba_dev_isup(sd)) 3198 bwn_reset_core(mac, 3199 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3200 3201 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3202 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3203 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3204 BWN_GETTIME(mac->mac_phy.nexttime); 3205 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3206 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3207 mac->mac_stats.link_noise = -95; 3208 mac->mac_reason_intr = 0; 3209 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3210 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3211#ifdef BWN_DEBUG 3212 if (sc->sc_debug & BWN_DEBUG_XMIT) 3213 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3214#endif 3215 mac->mac_suspended = 1; 3216 mac->mac_task_state = 0; 3217 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3218 3219 mac->mac_phy.init_pre(mac); 3220 3221 siba_pcicore_intr(&siba->siba_pci, sd); 3222 3223 bwn_fix_imcfglobug(mac); 3224 bwn_bt_disable(mac); 3225 if (mac->mac_phy.prepare_hw) { 3226 error = mac->mac_phy.prepare_hw(mac); 3227 if (error) 3228 goto fail0; 3229 } 3230 error = bwn_chip_init(mac); 3231 if (error) 3232 goto fail0; 3233 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3234 mac->mac_sd->sd_id.sd_rev); 3235 hf = bwn_hf_read(mac); 3236 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3237 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3238 if (sprom->bf_lo & BWN_BFL_PACTRL) 3239 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3240 if (mac->mac_phy.rev == 1) 3241 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3242 } 3243 if (mac->mac_phy.rf_ver == 0x2050) { 3244 if (mac->mac_phy.rf_rev < 6) 3245 hf |= BWN_HF_FORCE_VCO_RECALC; 3246 if (mac->mac_phy.rf_rev == 6) 3247 hf |= BWN_HF_4318_TSSI; 3248 } 3249 if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW) 3250 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3251 if ((siba->siba_type == SIBA_TYPE_PCI) && 3252 (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10)) 3253 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3254 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3255 bwn_hf_write(mac, hf); 3256 3257 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3258 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3259 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3260 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3261 3262 bwn_rate_init(mac); 3263 bwn_set_phytxctl(mac); 3264 3265 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3266 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3267 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3268 3269 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3270 bwn_pio_init(mac); 3271 else 3272 bwn_dma_init(mac); 3273 if (error) 3274 goto fail1; 3275 bwn_wme_init(mac); 3276 bwn_spu_setdelay(mac, 1); 3277 bwn_bt_enable(mac); 3278 3279 siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)); 3280 bwn_set_macaddr(mac); 3281 bwn_crypt_init(mac); 3282 3283 /* XXX LED initializatin */ 3284 3285 mac->mac_status = BWN_MAC_STATUS_INITED; 3286 3287 return (error); 3288 3289fail1: 3290 bwn_chip_exit(mac); 3291fail0: 3292 siba_powerdown(siba); 3293 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3294 ("%s:%d: fail", __func__, __LINE__)); 3295 return (error); 3296} 3297 3298static void 3299bwn_core_start(struct bwn_mac *mac) 3300{ 3301 struct bwn_softc *sc = mac->mac_sc; 3302 uint32_t tmp; 3303 3304 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3305 ("%s:%d: fail", __func__, __LINE__)); 3306 3307 if (mac->mac_sd->sd_id.sd_rev < 5) 3308 return; 3309 3310 while (1) { 3311 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3312 if (!(tmp & 0x00000001)) 3313 break; 3314 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3315 } 3316 3317 bwn_mac_enable(mac); 3318 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3319 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3320 3321 mac->mac_status = BWN_MAC_STATUS_STARTED; 3322} 3323 3324static void 3325bwn_core_exit(struct bwn_mac *mac) 3326{ 3327 uint32_t macctl; 3328 3329 BWN_ASSERT_LOCKED(mac->mac_sc); 3330 3331 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3332 ("%s:%d: fail", __func__, __LINE__)); 3333 3334 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3335 return; 3336 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3337 3338 macctl = BWN_READ_4(mac, BWN_MACCTL); 3339 macctl &= ~BWN_MACCTL_MCODE_RUN; 3340 macctl |= BWN_MACCTL_MCODE_JMP0; 3341 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3342 3343 bwn_dma_stop(mac); 3344 bwn_pio_stop(mac); 3345 bwn_chip_exit(mac); 3346 mac->mac_phy.switch_analog(mac, 0); 3347 siba_dev_down(mac->mac_sd, 0); 3348 siba_powerdown(mac->mac_sd->sd_bus); 3349} 3350 3351static void 3352bwn_fix_imcfglobug(struct bwn_mac *mac) 3353{ 3354 struct siba_dev_softc *sd = mac->mac_sd; 3355 struct siba_softc *siba = sd->sd_bus; 3356 uint32_t tmp; 3357 3358 if (siba->siba_pci.spc_dev == NULL) 3359 return; 3360 if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI || 3361 siba->siba_pci.spc_dev->sd_id.sd_rev > 5) 3362 return; 3363 3364 tmp = siba_read_4(sd, SIBA_IMCFGLO) & 3365 ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO); 3366 switch (siba->siba_type) { 3367 case SIBA_TYPE_PCI: 3368 case SIBA_TYPE_PCMCIA: 3369 tmp |= 0x32; 3370 break; 3371 case SIBA_TYPE_SSB: 3372 tmp |= 0x53; 3373 break; 3374 } 3375 siba_write_4(sd, SIBA_IMCFGLO, tmp); 3376} 3377 3378static void 3379bwn_bt_disable(struct bwn_mac *mac) 3380{ 3381 struct bwn_softc *sc = mac->mac_sc; 3382 3383 (void)sc; 3384 /* XXX do nothing yet */ 3385} 3386 3387static int 3388bwn_chip_init(struct bwn_mac *mac) 3389{ 3390 struct bwn_phy *phy = &mac->mac_phy; 3391 uint32_t macctl; 3392 int error; 3393 3394 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3395 if (phy->gmode) 3396 macctl |= BWN_MACCTL_GMODE; 3397 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3398 3399 error = bwn_fw_fillinfo(mac); 3400 if (error) 3401 return (error); 3402 error = bwn_fw_loaducode(mac); 3403 if (error) 3404 return (error); 3405 3406 error = bwn_gpio_init(mac); 3407 if (error) 3408 return (error); 3409 3410 error = bwn_fw_loadinitvals(mac); 3411 if (error) { 3412 bwn_gpio_cleanup(mac); 3413 return (error); 3414 } 3415 phy->switch_analog(mac, 1); 3416 error = bwn_phy_init(mac); 3417 if (error) { 3418 bwn_gpio_cleanup(mac); 3419 return (error); 3420 } 3421 if (phy->set_im) 3422 phy->set_im(mac, BWN_IMMODE_NONE); 3423 if (phy->set_antenna) 3424 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3425 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3426 3427 if (phy->type == BWN_PHYTYPE_B) 3428 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3429 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3430 if (mac->mac_sd->sd_id.sd_rev < 5) 3431 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3432 3433 BWN_WRITE_4(mac, BWN_MACCTL, 3434 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3435 BWN_WRITE_4(mac, BWN_MACCTL, 3436 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3437 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3438 3439 bwn_set_opmode(mac); 3440 if (mac->mac_sd->sd_id.sd_rev < 3) { 3441 BWN_WRITE_2(mac, 0x060e, 0x0000); 3442 BWN_WRITE_2(mac, 0x0610, 0x8000); 3443 BWN_WRITE_2(mac, 0x0604, 0x0000); 3444 BWN_WRITE_2(mac, 0x0606, 0x0200); 3445 } else { 3446 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3447 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3448 } 3449 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3450 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3451 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3452 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3453 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3454 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3455 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3456 siba_write_4(mac->mac_sd, SIBA_TGSLOW, 3457 siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000); 3458 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, 3459 mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay); 3460 return (error); 3461} 3462 3463/* read hostflags */ 3464static uint64_t 3465bwn_hf_read(struct bwn_mac *mac) 3466{ 3467 uint64_t ret; 3468 3469 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3470 ret <<= 16; 3471 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3472 ret <<= 16; 3473 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3474 return (ret); 3475} 3476 3477static void 3478bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3479{ 3480 3481 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3482 (value & 0x00000000ffffull)); 3483 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3484 (value & 0x0000ffff0000ull) >> 16); 3485 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3486 (value & 0xffff00000000ULL) >> 32); 3487} 3488 3489static void 3490bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3491{ 3492 3493 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3494 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3495} 3496 3497static void 3498bwn_rate_init(struct bwn_mac *mac) 3499{ 3500 3501 switch (mac->mac_phy.type) { 3502 case BWN_PHYTYPE_A: 3503 case BWN_PHYTYPE_G: 3504 case BWN_PHYTYPE_LP: 3505 case BWN_PHYTYPE_N: 3506 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3507 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3508 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3509 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3510 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3511 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3512 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3513 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3514 break; 3515 /* FALLTHROUGH */ 3516 case BWN_PHYTYPE_B: 3517 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3518 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3519 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3520 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3521 break; 3522 default: 3523 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3524 } 3525} 3526 3527static void 3528bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3529{ 3530 uint16_t offset; 3531 3532 if (ofdm) { 3533 offset = 0x480; 3534 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3535 } else { 3536 offset = 0x4c0; 3537 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3538 } 3539 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3540 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3541} 3542 3543static uint8_t 3544bwn_plcp_getcck(const uint8_t bitrate) 3545{ 3546 3547 switch (bitrate) { 3548 case BWN_CCK_RATE_1MB: 3549 return (0x0a); 3550 case BWN_CCK_RATE_2MB: 3551 return (0x14); 3552 case BWN_CCK_RATE_5MB: 3553 return (0x37); 3554 case BWN_CCK_RATE_11MB: 3555 return (0x6e); 3556 } 3557 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3558 return (0); 3559} 3560 3561static uint8_t 3562bwn_plcp_getofdm(const uint8_t bitrate) 3563{ 3564 3565 switch (bitrate) { 3566 case BWN_OFDM_RATE_6MB: 3567 return (0xb); 3568 case BWN_OFDM_RATE_9MB: 3569 return (0xf); 3570 case BWN_OFDM_RATE_12MB: 3571 return (0xa); 3572 case BWN_OFDM_RATE_18MB: 3573 return (0xe); 3574 case BWN_OFDM_RATE_24MB: 3575 return (0x9); 3576 case BWN_OFDM_RATE_36MB: 3577 return (0xd); 3578 case BWN_OFDM_RATE_48MB: 3579 return (0x8); 3580 case BWN_OFDM_RATE_54MB: 3581 return (0xc); 3582 } 3583 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3584 return (0); 3585} 3586 3587static void 3588bwn_set_phytxctl(struct bwn_mac *mac) 3589{ 3590 uint16_t ctl; 3591 3592 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3593 BWN_TX_PHY_TXPWR); 3594 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3595 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3596 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3597} 3598 3599static void 3600bwn_pio_init(struct bwn_mac *mac) 3601{ 3602 struct bwn_pio *pio = &mac->mac_method.pio; 3603 3604 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3605 & ~BWN_MACCTL_BIGENDIAN); 3606 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3607 3608 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3609 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3610 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3611 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3612 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3613 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3614} 3615 3616static void 3617bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3618 int index) 3619{ 3620 struct bwn_pio_txpkt *tp; 3621 unsigned int i; 3622 3623 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3624 tq->tq_index = index; 3625 3626 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3627 if (mac->mac_sd->sd_id.sd_rev >= 8) 3628 tq->tq_size = 1920; 3629 else { 3630 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3631 tq->tq_size -= 80; 3632 } 3633 3634 TAILQ_INIT(&tq->tq_pktlist); 3635 for (i = 0; i < N(tq->tq_pkts); i++) { 3636 tp = &(tq->tq_pkts[i]); 3637 tp->tp_index = i; 3638 tp->tp_queue = tq; 3639 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3640 } 3641} 3642 3643static uint16_t 3644bwn_pio_idx2base(struct bwn_mac *mac, int index) 3645{ 3646 struct bwn_softc *sc = mac->mac_sc; 3647 static const uint16_t bases[] = { 3648 BWN_PIO_BASE0, 3649 BWN_PIO_BASE1, 3650 BWN_PIO_BASE2, 3651 BWN_PIO_BASE3, 3652 BWN_PIO_BASE4, 3653 BWN_PIO_BASE5, 3654 BWN_PIO_BASE6, 3655 BWN_PIO_BASE7, 3656 }; 3657 static const uint16_t bases_rev11[] = { 3658 BWN_PIO11_BASE0, 3659 BWN_PIO11_BASE1, 3660 BWN_PIO11_BASE2, 3661 BWN_PIO11_BASE3, 3662 BWN_PIO11_BASE4, 3663 BWN_PIO11_BASE5, 3664 }; 3665 3666 if (mac->mac_sd->sd_id.sd_rev >= 11) { 3667 if (index >= N(bases_rev11)) 3668 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3669 return (bases_rev11[index]); 3670 } 3671 if (index >= N(bases)) 3672 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3673 return (bases[index]); 3674} 3675 3676static void 3677bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3678 int index) 3679{ 3680 3681 prq->prq_mac = mac; 3682 prq->prq_rev = mac->mac_sd->sd_id.sd_rev; 3683 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3684 bwn_dma_rxdirectfifo(mac, index, 1); 3685} 3686 3687static void 3688bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3689{ 3690 if (tq == NULL) 3691 return; 3692 bwn_pio_cancel_tx_packets(tq); 3693} 3694 3695static void 3696bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3697{ 3698 3699 bwn_destroy_pioqueue_tx(pio); 3700} 3701 3702static uint16_t 3703bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3704 uint16_t offset) 3705{ 3706 3707 return (BWN_READ_2(mac, tq->tq_base + offset)); 3708} 3709 3710static void 3711bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3712{ 3713 uint32_t ctl; 3714 int type; 3715 uint16_t base; 3716 3717 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3718 base = bwn_dma_base(type, idx); 3719 if (type == BWN_DMA_64BIT) { 3720 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3721 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3722 if (enable) 3723 ctl |= BWN_DMA64_RXDIRECTFIFO; 3724 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3725 } else { 3726 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3727 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3728 if (enable) 3729 ctl |= BWN_DMA32_RXDIRECTFIFO; 3730 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3731 } 3732} 3733 3734static uint64_t 3735bwn_dma_mask(struct bwn_mac *mac) 3736{ 3737 uint32_t tmp; 3738 uint16_t base; 3739 3740 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3741 if (tmp & SIBA_TGSHIGH_DMA64) 3742 return (BWN_DMA_BIT_MASK(64)); 3743 base = bwn_dma_base(0, 0); 3744 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3745 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3746 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3747 return (BWN_DMA_BIT_MASK(32)); 3748 3749 return (BWN_DMA_BIT_MASK(30)); 3750} 3751 3752static int 3753bwn_dma_mask2type(uint64_t dmamask) 3754{ 3755 3756 if (dmamask == BWN_DMA_BIT_MASK(30)) 3757 return (BWN_DMA_30BIT); 3758 if (dmamask == BWN_DMA_BIT_MASK(32)) 3759 return (BWN_DMA_32BIT); 3760 if (dmamask == BWN_DMA_BIT_MASK(64)) 3761 return (BWN_DMA_64BIT); 3762 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3763 return (BWN_DMA_30BIT); 3764} 3765 3766static void 3767bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3768{ 3769 struct bwn_pio_txpkt *tp; 3770 unsigned int i; 3771 3772 for (i = 0; i < N(tq->tq_pkts); i++) { 3773 tp = &(tq->tq_pkts[i]); 3774 if (tp->tp_m) { 3775 m_freem(tp->tp_m); 3776 tp->tp_m = NULL; 3777 } 3778 } 3779} 3780 3781static uint16_t 3782bwn_dma_base(int type, int controller_idx) 3783{ 3784 static const uint16_t map64[] = { 3785 BWN_DMA64_BASE0, 3786 BWN_DMA64_BASE1, 3787 BWN_DMA64_BASE2, 3788 BWN_DMA64_BASE3, 3789 BWN_DMA64_BASE4, 3790 BWN_DMA64_BASE5, 3791 }; 3792 static const uint16_t map32[] = { 3793 BWN_DMA32_BASE0, 3794 BWN_DMA32_BASE1, 3795 BWN_DMA32_BASE2, 3796 BWN_DMA32_BASE3, 3797 BWN_DMA32_BASE4, 3798 BWN_DMA32_BASE5, 3799 }; 3800 3801 if (type == BWN_DMA_64BIT) { 3802 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3803 ("%s:%d: fail", __func__, __LINE__)); 3804 return (map64[controller_idx]); 3805 } 3806 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3807 ("%s:%d: fail", __func__, __LINE__)); 3808 return (map32[controller_idx]); 3809} 3810 3811static void 3812bwn_dma_init(struct bwn_mac *mac) 3813{ 3814 struct bwn_dma *dma = &mac->mac_method.dma; 3815 3816 /* setup TX DMA channels. */ 3817 bwn_dma_setup(dma->wme[WME_AC_BK]); 3818 bwn_dma_setup(dma->wme[WME_AC_BE]); 3819 bwn_dma_setup(dma->wme[WME_AC_VI]); 3820 bwn_dma_setup(dma->wme[WME_AC_VO]); 3821 bwn_dma_setup(dma->mcast); 3822 /* setup RX DMA channel. */ 3823 bwn_dma_setup(dma->rx); 3824} 3825 3826static struct bwn_dma_ring * 3827bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3828 int for_tx, int type) 3829{ 3830 struct bwn_dma *dma = &mac->mac_method.dma; 3831 struct bwn_dma_ring *dr; 3832 struct bwn_dmadesc_generic *desc; 3833 struct bwn_dmadesc_meta *mt; 3834 struct bwn_softc *sc = mac->mac_sc; 3835 int error, i; 3836 3837 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3838 if (dr == NULL) 3839 goto out; 3840 dr->dr_numslots = BWN_RXRING_SLOTS; 3841 if (for_tx) 3842 dr->dr_numslots = BWN_TXRING_SLOTS; 3843 3844 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3845 M_DEVBUF, M_NOWAIT | M_ZERO); 3846 if (dr->dr_meta == NULL) 3847 goto fail0; 3848 3849 dr->dr_type = type; 3850 dr->dr_mac = mac; 3851 dr->dr_base = bwn_dma_base(type, controller_index); 3852 dr->dr_index = controller_index; 3853 if (type == BWN_DMA_64BIT) { 3854 dr->getdesc = bwn_dma_64_getdesc; 3855 dr->setdesc = bwn_dma_64_setdesc; 3856 dr->start_transfer = bwn_dma_64_start_transfer; 3857 dr->suspend = bwn_dma_64_suspend; 3858 dr->resume = bwn_dma_64_resume; 3859 dr->get_curslot = bwn_dma_64_get_curslot; 3860 dr->set_curslot = bwn_dma_64_set_curslot; 3861 } else { 3862 dr->getdesc = bwn_dma_32_getdesc; 3863 dr->setdesc = bwn_dma_32_setdesc; 3864 dr->start_transfer = bwn_dma_32_start_transfer; 3865 dr->suspend = bwn_dma_32_suspend; 3866 dr->resume = bwn_dma_32_resume; 3867 dr->get_curslot = bwn_dma_32_get_curslot; 3868 dr->set_curslot = bwn_dma_32_set_curslot; 3869 } 3870 if (for_tx) { 3871 dr->dr_tx = 1; 3872 dr->dr_curslot = -1; 3873 } else { 3874 if (dr->dr_index == 0) { 3875 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3876 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3877 } else 3878 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3879 } 3880 3881 error = bwn_dma_allocringmemory(dr); 3882 if (error) 3883 goto fail2; 3884 3885 if (for_tx) { 3886 /* 3887 * Assumption: BWN_TXRING_SLOTS can be divided by 3888 * BWN_TX_SLOTS_PER_FRAME 3889 */ 3890 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3891 ("%s:%d: fail", __func__, __LINE__)); 3892 3893 dr->dr_txhdr_cache = 3894 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3895 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3896 KASSERT(dr->dr_txhdr_cache != NULL, 3897 ("%s:%d: fail", __func__, __LINE__)); 3898 3899 /* 3900 * Create TX ring DMA stuffs 3901 */ 3902 error = bus_dma_tag_create(dma->parent_dtag, 3903 BWN_ALIGN, 0, 3904 BUS_SPACE_MAXADDR, 3905 BUS_SPACE_MAXADDR, 3906 NULL, NULL, 3907 BWN_HDRSIZE(mac), 3908 1, 3909 BUS_SPACE_MAXSIZE_32BIT, 3910 0, 3911 NULL, NULL, 3912 &dr->dr_txring_dtag); 3913 if (error) { 3914 device_printf(sc->sc_dev, 3915 "can't create TX ring DMA tag: TODO frees\n"); 3916 goto fail1; 3917 } 3918 3919 for (i = 0; i < dr->dr_numslots; i += 2) { 3920 dr->getdesc(dr, i, &desc, &mt); 3921 3922 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3923 mt->mt_m = NULL; 3924 mt->mt_ni = NULL; 3925 mt->mt_islast = 0; 3926 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3927 &mt->mt_dmap); 3928 if (error) { 3929 device_printf(sc->sc_dev, 3930 "can't create RX buf DMA map\n"); 3931 goto fail1; 3932 } 3933 3934 dr->getdesc(dr, i + 1, &desc, &mt); 3935 3936 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3937 mt->mt_m = NULL; 3938 mt->mt_ni = NULL; 3939 mt->mt_islast = 1; 3940 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3941 &mt->mt_dmap); 3942 if (error) { 3943 device_printf(sc->sc_dev, 3944 "can't create RX buf DMA map\n"); 3945 goto fail1; 3946 } 3947 } 3948 } else { 3949 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3950 &dr->dr_spare_dmap); 3951 if (error) { 3952 device_printf(sc->sc_dev, 3953 "can't create RX buf DMA map\n"); 3954 goto out; /* XXX wrong! */ 3955 } 3956 3957 for (i = 0; i < dr->dr_numslots; i++) { 3958 dr->getdesc(dr, i, &desc, &mt); 3959 3960 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3961 &mt->mt_dmap); 3962 if (error) { 3963 device_printf(sc->sc_dev, 3964 "can't create RX buf DMA map\n"); 3965 goto out; /* XXX wrong! */ 3966 } 3967 error = bwn_dma_newbuf(dr, desc, mt, 1); 3968 if (error) { 3969 device_printf(sc->sc_dev, 3970 "failed to allocate RX buf\n"); 3971 goto out; /* XXX wrong! */ 3972 } 3973 } 3974 3975 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3976 BUS_DMASYNC_PREWRITE); 3977 3978 dr->dr_usedslot = dr->dr_numslots; 3979 } 3980 3981 out: 3982 return (dr); 3983 3984fail2: 3985 free(dr->dr_txhdr_cache, M_DEVBUF); 3986fail1: 3987 free(dr->dr_meta, M_DEVBUF); 3988fail0: 3989 free(dr, M_DEVBUF); 3990 return (NULL); 3991} 3992 3993static void 3994bwn_dma_ringfree(struct bwn_dma_ring **dr) 3995{ 3996 3997 if (dr == NULL) 3998 return; 3999 4000 bwn_dma_free_descbufs(*dr); 4001 bwn_dma_free_ringmemory(*dr); 4002 4003 free((*dr)->dr_txhdr_cache, M_DEVBUF); 4004 free((*dr)->dr_meta, M_DEVBUF); 4005 free(*dr, M_DEVBUF); 4006 4007 *dr = NULL; 4008} 4009 4010static void 4011bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 4012 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4013{ 4014 struct bwn_dmadesc32 *desc; 4015 4016 *meta = &(dr->dr_meta[slot]); 4017 desc = dr->dr_ring_descbase; 4018 desc = &(desc[slot]); 4019 4020 *gdesc = (struct bwn_dmadesc_generic *)desc; 4021} 4022 4023static void 4024bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 4025 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4026 int start, int end, int irq) 4027{ 4028 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 4029 uint32_t addr, addrext, ctl; 4030 int slot; 4031 4032 slot = (int)(&(desc->dma.dma32) - descbase); 4033 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4034 ("%s:%d: fail", __func__, __LINE__)); 4035 4036 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 4037 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 4038 addr |= siba_dma_translation(dr->dr_mac->mac_sd); 4039 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 4040 if (slot == dr->dr_numslots - 1) 4041 ctl |= BWN_DMA32_DCTL_DTABLEEND; 4042 if (start) 4043 ctl |= BWN_DMA32_DCTL_FRAMESTART; 4044 if (end) 4045 ctl |= BWN_DMA32_DCTL_FRAMEEND; 4046 if (irq) 4047 ctl |= BWN_DMA32_DCTL_IRQ; 4048 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 4049 & BWN_DMA32_DCTL_ADDREXT_MASK; 4050 4051 desc->dma.dma32.control = htole32(ctl); 4052 desc->dma.dma32.address = htole32(addr); 4053} 4054 4055static void 4056bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 4057{ 4058 4059 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 4060 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 4061} 4062 4063static void 4064bwn_dma_32_suspend(struct bwn_dma_ring *dr) 4065{ 4066 4067 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4068 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 4069} 4070 4071static void 4072bwn_dma_32_resume(struct bwn_dma_ring *dr) 4073{ 4074 4075 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4076 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 4077} 4078 4079static int 4080bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4081{ 4082 uint32_t val; 4083 4084 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4085 val &= BWN_DMA32_RXDPTR; 4086 4087 return (val / sizeof(struct bwn_dmadesc32)); 4088} 4089 4090static void 4091bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4092{ 4093 4094 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4095 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4096} 4097 4098static void 4099bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4100 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4101{ 4102 struct bwn_dmadesc64 *desc; 4103 4104 *meta = &(dr->dr_meta[slot]); 4105 desc = dr->dr_ring_descbase; 4106 desc = &(desc[slot]); 4107 4108 *gdesc = (struct bwn_dmadesc_generic *)desc; 4109} 4110 4111static void 4112bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4113 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4114 int start, int end, int irq) 4115{ 4116 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4117 int slot; 4118 uint32_t ctl0 = 0, ctl1 = 0; 4119 uint32_t addrlo, addrhi; 4120 uint32_t addrext; 4121 4122 slot = (int)(&(desc->dma.dma64) - descbase); 4123 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4124 ("%s:%d: fail", __func__, __LINE__)); 4125 4126 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4127 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4128 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4129 30; 4130 addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1); 4131 if (slot == dr->dr_numslots - 1) 4132 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4133 if (start) 4134 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4135 if (end) 4136 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4137 if (irq) 4138 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4139 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4140 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4141 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4142 4143 desc->dma.dma64.control0 = htole32(ctl0); 4144 desc->dma.dma64.control1 = htole32(ctl1); 4145 desc->dma.dma64.address_low = htole32(addrlo); 4146 desc->dma.dma64.address_high = htole32(addrhi); 4147} 4148 4149static void 4150bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4151{ 4152 4153 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4154 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4155} 4156 4157static void 4158bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4159{ 4160 4161 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4162 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4163} 4164 4165static void 4166bwn_dma_64_resume(struct bwn_dma_ring *dr) 4167{ 4168 4169 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4170 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4171} 4172 4173static int 4174bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4175{ 4176 uint32_t val; 4177 4178 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4179 val &= BWN_DMA64_RXSTATDPTR; 4180 4181 return (val / sizeof(struct bwn_dmadesc64)); 4182} 4183 4184static void 4185bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4186{ 4187 4188 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4189 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4190} 4191 4192static int 4193bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4194{ 4195 struct bwn_mac *mac = dr->dr_mac; 4196 struct bwn_dma *dma = &mac->mac_method.dma; 4197 struct bwn_softc *sc = mac->mac_sc; 4198 int error; 4199 4200 error = bus_dma_tag_create(dma->parent_dtag, 4201 BWN_ALIGN, 0, 4202 BUS_SPACE_MAXADDR, 4203 BUS_SPACE_MAXADDR, 4204 NULL, NULL, 4205 BWN_DMA_RINGMEMSIZE, 4206 1, 4207 BUS_SPACE_MAXSIZE_32BIT, 4208 0, 4209 NULL, NULL, 4210 &dr->dr_ring_dtag); 4211 if (error) { 4212 device_printf(sc->sc_dev, 4213 "can't create TX ring DMA tag: TODO frees\n"); 4214 return (-1); 4215 } 4216 4217 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4218 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4219 &dr->dr_ring_dmap); 4220 if (error) { 4221 device_printf(sc->sc_dev, 4222 "can't allocate DMA mem: TODO frees\n"); 4223 return (-1); 4224 } 4225 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4226 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4227 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4228 if (error) { 4229 device_printf(sc->sc_dev, 4230 "can't load DMA mem: TODO free\n"); 4231 return (-1); 4232 } 4233 4234 return (0); 4235} 4236 4237static void 4238bwn_dma_setup(struct bwn_dma_ring *dr) 4239{ 4240 uint64_t ring64; 4241 uint32_t addrext, ring32, value; 4242 uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd); 4243 4244 if (dr->dr_tx) { 4245 dr->dr_curslot = -1; 4246 4247 if (dr->dr_type == BWN_DMA_64BIT) { 4248 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4249 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4250 >> 30; 4251 value = BWN_DMA64_TXENABLE; 4252 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4253 & BWN_DMA64_TXADDREXT_MASK; 4254 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4255 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4256 (ring64 & 0xffffffff)); 4257 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4258 ((ring64 >> 32) & 4259 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4260 } else { 4261 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4262 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4263 value = BWN_DMA32_TXENABLE; 4264 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4265 & BWN_DMA32_TXADDREXT_MASK; 4266 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4267 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4268 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4269 } 4270 return; 4271 } 4272 4273 /* 4274 * set for RX 4275 */ 4276 dr->dr_usedslot = dr->dr_numslots; 4277 4278 if (dr->dr_type == BWN_DMA_64BIT) { 4279 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4280 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4281 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4282 value |= BWN_DMA64_RXENABLE; 4283 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4284 & BWN_DMA64_RXADDREXT_MASK; 4285 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4286 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4287 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4288 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4289 | (trans << 1)); 4290 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4291 sizeof(struct bwn_dmadesc64)); 4292 } else { 4293 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4294 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4295 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4296 value |= BWN_DMA32_RXENABLE; 4297 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4298 & BWN_DMA32_RXADDREXT_MASK; 4299 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4300 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4301 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4302 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4303 sizeof(struct bwn_dmadesc32)); 4304 } 4305} 4306 4307static void 4308bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4309{ 4310 4311 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4312 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4313 dr->dr_ring_dmap); 4314} 4315 4316static void 4317bwn_dma_cleanup(struct bwn_dma_ring *dr) 4318{ 4319 4320 if (dr->dr_tx) { 4321 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4322 if (dr->dr_type == BWN_DMA_64BIT) { 4323 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4324 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4325 } else 4326 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4327 } else { 4328 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4329 if (dr->dr_type == BWN_DMA_64BIT) { 4330 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4331 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4332 } else 4333 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4334 } 4335} 4336 4337static void 4338bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4339{ 4340 struct bwn_dmadesc_generic *desc; 4341 struct bwn_dmadesc_meta *meta; 4342 struct bwn_mac *mac = dr->dr_mac; 4343 struct bwn_dma *dma = &mac->mac_method.dma; 4344 struct bwn_softc *sc = mac->mac_sc; 4345 int i; 4346 4347 if (!dr->dr_usedslot) 4348 return; 4349 for (i = 0; i < dr->dr_numslots; i++) { 4350 dr->getdesc(dr, i, &desc, &meta); 4351 4352 if (meta->mt_m == NULL) { 4353 if (!dr->dr_tx) 4354 device_printf(sc->sc_dev, "%s: not TX?\n", 4355 __func__); 4356 continue; 4357 } 4358 if (dr->dr_tx) { 4359 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4360 bus_dmamap_unload(dr->dr_txring_dtag, 4361 meta->mt_dmap); 4362 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4363 bus_dmamap_unload(dma->txbuf_dtag, 4364 meta->mt_dmap); 4365 } else 4366 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4367 bwn_dma_free_descbuf(dr, meta); 4368 } 4369} 4370 4371static int 4372bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4373 int type) 4374{ 4375 struct bwn_softc *sc = mac->mac_sc; 4376 uint32_t value; 4377 int i; 4378 uint16_t offset; 4379 4380 for (i = 0; i < 10; i++) { 4381 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4382 BWN_DMA32_TXSTATUS; 4383 value = BWN_READ_4(mac, base + offset); 4384 if (type == BWN_DMA_64BIT) { 4385 value &= BWN_DMA64_TXSTAT; 4386 if (value == BWN_DMA64_TXSTAT_DISABLED || 4387 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4388 value == BWN_DMA64_TXSTAT_STOPPED) 4389 break; 4390 } else { 4391 value &= BWN_DMA32_TXSTATE; 4392 if (value == BWN_DMA32_TXSTAT_DISABLED || 4393 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4394 value == BWN_DMA32_TXSTAT_STOPPED) 4395 break; 4396 } 4397 DELAY(1000); 4398 } 4399 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4400 BWN_WRITE_4(mac, base + offset, 0); 4401 for (i = 0; i < 10; i++) { 4402 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4403 BWN_DMA32_TXSTATUS; 4404 value = BWN_READ_4(mac, base + offset); 4405 if (type == BWN_DMA_64BIT) { 4406 value &= BWN_DMA64_TXSTAT; 4407 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4408 i = -1; 4409 break; 4410 } 4411 } else { 4412 value &= BWN_DMA32_TXSTATE; 4413 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4414 i = -1; 4415 break; 4416 } 4417 } 4418 DELAY(1000); 4419 } 4420 if (i != -1) { 4421 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4422 return (ENODEV); 4423 } 4424 DELAY(1000); 4425 4426 return (0); 4427} 4428 4429static int 4430bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4431 int type) 4432{ 4433 struct bwn_softc *sc = mac->mac_sc; 4434 uint32_t value; 4435 int i; 4436 uint16_t offset; 4437 4438 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4439 BWN_WRITE_4(mac, base + offset, 0); 4440 for (i = 0; i < 10; i++) { 4441 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4442 BWN_DMA32_RXSTATUS; 4443 value = BWN_READ_4(mac, base + offset); 4444 if (type == BWN_DMA_64BIT) { 4445 value &= BWN_DMA64_RXSTAT; 4446 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4447 i = -1; 4448 break; 4449 } 4450 } else { 4451 value &= BWN_DMA32_RXSTATE; 4452 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4453 i = -1; 4454 break; 4455 } 4456 } 4457 DELAY(1000); 4458 } 4459 if (i != -1) { 4460 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4461 return (ENODEV); 4462 } 4463 4464 return (0); 4465} 4466 4467static void 4468bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4469 struct bwn_dmadesc_meta *meta) 4470{ 4471 4472 if (meta->mt_m != NULL) { 4473 m_freem(meta->mt_m); 4474 meta->mt_m = NULL; 4475 } 4476 if (meta->mt_ni != NULL) { 4477 ieee80211_free_node(meta->mt_ni); 4478 meta->mt_ni = NULL; 4479 } 4480} 4481 4482static void 4483bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4484{ 4485 struct bwn_rxhdr4 *rxhdr; 4486 unsigned char *frame; 4487 4488 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4489 rxhdr->frame_len = 0; 4490 4491 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4492 sizeof(struct bwn_plcp6) + 2, 4493 ("%s:%d: fail", __func__, __LINE__)); 4494 frame = mtod(m, char *) + dr->dr_frameoffset; 4495 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4496} 4497 4498static uint8_t 4499bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4500{ 4501 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4502 4503 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4504 == 0xff); 4505} 4506 4507static void 4508bwn_wme_init(struct bwn_mac *mac) 4509{ 4510 4511 bwn_wme_load(mac); 4512 4513 /* enable WME support. */ 4514 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4515 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4516 BWN_IFSCTL_USE_EDCF); 4517} 4518 4519static void 4520bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4521{ 4522 struct bwn_softc *sc = mac->mac_sc; 4523 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4524 uint16_t delay; /* microsec */ 4525 4526 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4527 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4528 delay = 500; 4529 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4530 delay = max(delay, (uint16_t)2400); 4531 4532 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4533} 4534 4535static void 4536bwn_bt_enable(struct bwn_mac *mac) 4537{ 4538 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 4539 uint64_t hf; 4540 4541 if (bwn_bluetooth == 0) 4542 return; 4543 if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0) 4544 return; 4545 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4546 return; 4547 4548 hf = bwn_hf_read(mac); 4549 if (sprom->bf_lo & BWN_BFL_BTCMOD) 4550 hf |= BWN_HF_BT_COEXISTALT; 4551 else 4552 hf |= BWN_HF_BT_COEXIST; 4553 bwn_hf_write(mac, hf); 4554} 4555 4556static void 4557bwn_set_macaddr(struct bwn_mac *mac) 4558{ 4559 4560 bwn_mac_write_bssid(mac); 4561 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4562} 4563 4564static void 4565bwn_clear_keys(struct bwn_mac *mac) 4566{ 4567 int i; 4568 4569 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4570 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4571 ("%s:%d: fail", __func__, __LINE__)); 4572 4573 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4574 NULL, BWN_SEC_KEYSIZE, NULL); 4575 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4576 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4577 NULL, BWN_SEC_KEYSIZE, NULL); 4578 } 4579 mac->mac_key[i].keyconf = NULL; 4580 } 4581} 4582 4583static void 4584bwn_crypt_init(struct bwn_mac *mac) 4585{ 4586 4587 mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20; 4588 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4589 ("%s:%d: fail", __func__, __LINE__)); 4590 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4591 mac->mac_ktp *= 2; 4592 if (mac->mac_sd->sd_id.sd_rev >= 5) { 4593 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, 4594 mac->mac_max_nr_keys - 8); 4595 } 4596 bwn_clear_keys(mac); 4597} 4598 4599static void 4600bwn_chip_exit(struct bwn_mac *mac) 4601{ 4602 4603 bwn_phy_exit(mac); 4604 bwn_gpio_cleanup(mac); 4605} 4606 4607static int 4608bwn_fw_fillinfo(struct bwn_mac *mac) 4609{ 4610 int error; 4611 4612 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4613 if (error == 0) 4614 return (0); 4615 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4616 if (error == 0) 4617 return (0); 4618 return (error); 4619} 4620 4621static int 4622bwn_gpio_init(struct bwn_mac *mac) 4623{ 4624 struct siba_softc *bus = mac->mac_sd->sd_bus; 4625 struct siba_dev_softc *sd; 4626 uint32_t mask = 0x0000001f, set = 0x0000000f; 4627 4628 BWN_WRITE_4(mac, BWN_MACCTL, 4629 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4630 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4631 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4632 4633 if (bus->siba_chipid == 0x4301) { 4634 mask |= 0x0060; 4635 set |= 0x0060; 4636 } 4637 if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) { 4638 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4639 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4640 mask |= 0x0200; 4641 set |= 0x0200; 4642 } 4643 if (mac->mac_sd->sd_id.sd_rev >= 2) 4644 mask |= 0x0010; 4645 sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev : 4646 bus->siba_pci.spc_dev; 4647 if (sd == NULL) 4648 return (0); 4649 siba_write_4(sd, BWN_GPIOCTL, 4650 (siba_read_4(sd, BWN_GPIOCTL) & mask) | set); 4651 4652 return (0); 4653} 4654 4655static int 4656bwn_fw_loadinitvals(struct bwn_mac *mac) 4657{ 4658#define GETFWOFFSET(fwp, offset) \ 4659 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4660 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4661 const struct bwn_fwhdr *hdr; 4662 struct bwn_fw *fw = &mac->mac_fw; 4663 int error; 4664 4665 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4666 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4667 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4668 if (error) 4669 return (error); 4670 if (fw->initvals_band.fw) { 4671 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4672 error = bwn_fwinitvals_write(mac, 4673 GETFWOFFSET(fw->initvals_band, hdr_len), 4674 be32toh(hdr->size), 4675 fw->initvals_band.fw->datasize - hdr_len); 4676 } 4677 return (error); 4678#undef GETFWOFFSET 4679} 4680 4681static int 4682bwn_phy_init(struct bwn_mac *mac) 4683{ 4684 struct bwn_softc *sc = mac->mac_sc; 4685 int error; 4686 4687 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4688 mac->mac_phy.rf_onoff(mac, 1); 4689 error = mac->mac_phy.init(mac); 4690 if (error) { 4691 device_printf(sc->sc_dev, "PHY init failed\n"); 4692 goto fail0; 4693 } 4694 error = bwn_switch_channel(mac, 4695 mac->mac_phy.get_default_chan(mac)); 4696 if (error) { 4697 device_printf(sc->sc_dev, 4698 "failed to switch default channel\n"); 4699 goto fail1; 4700 } 4701 return (0); 4702fail1: 4703 if (mac->mac_phy.exit) 4704 mac->mac_phy.exit(mac); 4705fail0: 4706 mac->mac_phy.rf_onoff(mac, 0); 4707 4708 return (error); 4709} 4710 4711static void 4712bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4713{ 4714 uint16_t ant; 4715 uint16_t tmp; 4716 4717 ant = bwn_ant2phy(antenna); 4718 4719 /* For ACK/CTS */ 4720 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4721 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4722 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4723 /* For Probe Resposes */ 4724 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4725 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4726 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4727} 4728 4729static void 4730bwn_set_opmode(struct bwn_mac *mac) 4731{ 4732 struct bwn_softc *sc = mac->mac_sc; 4733 struct ifnet *ifp = sc->sc_ifp; 4734 struct ieee80211com *ic = ifp->if_l2com; 4735 uint32_t ctl; 4736 uint16_t cfp_pretbtt; 4737 4738 ctl = BWN_READ_4(mac, BWN_MACCTL); 4739 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4740 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4741 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4742 ctl |= BWN_MACCTL_STA; 4743 4744 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4745 ic->ic_opmode == IEEE80211_M_MBSS) 4746 ctl |= BWN_MACCTL_HOSTAP; 4747 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4748 ctl &= ~BWN_MACCTL_STA; 4749 ctl |= sc->sc_filters; 4750 4751 if (mac->mac_sd->sd_id.sd_rev <= 4) 4752 ctl |= BWN_MACCTL_PROMISC; 4753 4754 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4755 4756 cfp_pretbtt = 2; 4757 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4758 if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 && 4759 mac->mac_sd->sd_bus->siba_chiprev == 3) 4760 cfp_pretbtt = 100; 4761 else 4762 cfp_pretbtt = 50; 4763 } 4764 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4765} 4766 4767static void 4768bwn_gpio_cleanup(struct bwn_mac *mac) 4769{ 4770 struct siba_softc *bus = mac->mac_sd->sd_bus; 4771 struct siba_dev_softc *gpiodev, *pcidev = NULL; 4772 4773 pcidev = bus->siba_pci.spc_dev; 4774 gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev; 4775 if (!gpiodev) 4776 return; 4777 siba_write_4(gpiodev, BWN_GPIOCTL, 0); 4778} 4779 4780static int 4781bwn_dma_gettype(struct bwn_mac *mac) 4782{ 4783 uint32_t tmp; 4784 uint16_t base; 4785 4786 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4787 if (tmp & SIBA_TGSHIGH_DMA64) 4788 return (BWN_DMA_64BIT); 4789 base = bwn_dma_base(0, 0); 4790 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4791 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4792 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4793 return (BWN_DMA_32BIT); 4794 4795 return (BWN_DMA_30BIT); 4796} 4797 4798static void 4799bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4800{ 4801 if (!error) { 4802 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4803 *((bus_addr_t *)arg) = seg->ds_addr; 4804 } 4805} 4806 4807static void 4808bwn_phy_g_init_sub(struct bwn_mac *mac) 4809{ 4810 struct bwn_phy *phy = &mac->mac_phy; 4811 struct bwn_phy_g *pg = &phy->phy_g; 4812 uint16_t i, tmp; 4813 4814 if (phy->rev == 1) 4815 bwn_phy_init_b5(mac); 4816 else 4817 bwn_phy_init_b6(mac); 4818 4819 if (phy->rev >= 2 || phy->gmode) 4820 bwn_phy_init_a(mac); 4821 4822 if (phy->rev >= 2) { 4823 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4824 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4825 } 4826 if (phy->rev == 2) { 4827 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4828 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4829 } 4830 if (phy->rev > 5) { 4831 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4832 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4833 } 4834 if (phy->gmode || phy->rev >= 2) { 4835 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4836 tmp &= BWN_PHYVER_VERSION; 4837 if (tmp == 3 || tmp == 5) { 4838 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4839 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4840 } 4841 if (tmp == 5) { 4842 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4843 0x1f00); 4844 } 4845 } 4846 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4847 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4848 if (phy->rf_rev == 8) { 4849 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4850 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4851 } 4852 if (BWN_HAS_LOOPBACK(phy)) 4853 bwn_loopback_calcgain(mac); 4854 4855 if (phy->rf_rev != 8) { 4856 if (pg->pg_initval == 0xffff) 4857 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4858 else 4859 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4860 } 4861 bwn_lo_g_init(mac); 4862 if (BWN_HAS_TXMAG(phy)) { 4863 BWN_RF_WRITE(mac, 0x52, 4864 (BWN_RF_READ(mac, 0x52) & 0xff00) 4865 | pg->pg_loctl.tx_bias | 4866 pg->pg_loctl.tx_magn); 4867 } else { 4868 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4869 } 4870 if (phy->rev >= 6) { 4871 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4872 (pg->pg_loctl.tx_bias << 12)); 4873 } 4874 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) 4875 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4876 else 4877 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4878 if (phy->rev < 2) 4879 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4880 else 4881 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4882 if (phy->gmode || phy->rev >= 2) { 4883 bwn_lo_g_adjust(mac); 4884 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4885 } 4886 4887 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 4888 for (i = 0; i < 64; i++) { 4889 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4890 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4891 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4892 -32), 31)); 4893 } 4894 bwn_nrssi_threshold(mac); 4895 } else if (phy->gmode || phy->rev >= 2) { 4896 if (pg->pg_nrssi[0] == -1000) { 4897 KASSERT(pg->pg_nrssi[1] == -1000, 4898 ("%s:%d: fail", __func__, __LINE__)); 4899 bwn_nrssi_slope_11g(mac); 4900 } else 4901 bwn_nrssi_threshold(mac); 4902 } 4903 if (phy->rf_rev == 8) 4904 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4905 bwn_phy_hwpctl_init(mac); 4906 if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306 4907 && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) { 4908 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4909 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4910 } 4911} 4912 4913static uint8_t 4914bwn_has_hwpctl(struct bwn_mac *mac) 4915{ 4916 4917 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4918 return (0); 4919 return (mac->mac_phy.use_hwpctl(mac)); 4920} 4921 4922static void 4923bwn_phy_init_b5(struct bwn_mac *mac) 4924{ 4925 struct siba_softc *bus = mac->mac_sd->sd_bus; 4926 struct bwn_phy *phy = &mac->mac_phy; 4927 struct bwn_phy_g *pg = &phy->phy_g; 4928 uint16_t offset, value; 4929 uint8_t old_channel; 4930 4931 if (phy->analog == 1) 4932 BWN_RF_SET(mac, 0x007a, 0x0050); 4933 if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) && 4934 (bus->siba_board_type != SIBA_BOARD_BU4306)) { 4935 value = 0x2120; 4936 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4937 BWN_PHY_WRITE(mac, offset, value); 4938 value += 0x202; 4939 } 4940 } 4941 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4942 if (phy->rf_ver == 0x2050) 4943 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4944 4945 if (phy->gmode || phy->rev >= 2) { 4946 if (phy->rf_ver == 0x2050) { 4947 BWN_RF_SET(mac, 0x007a, 0x0020); 4948 BWN_RF_SET(mac, 0x0051, 0x0004); 4949 } 4950 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4951 4952 BWN_PHY_SET(mac, 0x0802, 0x0100); 4953 BWN_PHY_SET(mac, 0x042b, 0x2000); 4954 4955 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4956 4957 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4958 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4959 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4960 } 4961 4962 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4963 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4964 4965 if (phy->analog == 1) { 4966 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4967 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4968 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4969 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4970 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4971 } else 4972 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4973 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4974 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4975 4976 if (phy->analog == 1) 4977 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4978 else 4979 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4980 4981 if (phy->analog == 0) 4982 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4983 4984 old_channel = phy->chan; 4985 bwn_phy_g_switch_chan(mac, 7, 0); 4986 4987 if (phy->rf_ver != 0x2050) { 4988 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4989 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4990 } 4991 4992 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4993 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4994 4995 if (phy->rf_ver == 0x2050) { 4996 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4997 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4998 } 4999 5000 BWN_RF_WRITE(mac, 0x005b, 0x007b); 5001 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 5002 BWN_RF_SET(mac, 0x007a, 0x0007); 5003 5004 bwn_phy_g_switch_chan(mac, old_channel, 0); 5005 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 5006 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 5007 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 5008 5009 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5010 pg->pg_txctl); 5011 5012 if (phy->rf_ver == 0x2050) 5013 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5014 5015 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 5016} 5017 5018static void 5019bwn_loopback_calcgain(struct bwn_mac *mac) 5020{ 5021 struct bwn_phy *phy = &mac->mac_phy; 5022 struct bwn_phy_g *pg = &phy->phy_g; 5023 uint16_t backup_phy[16] = { 0 }; 5024 uint16_t backup_radio[3]; 5025 uint16_t backup_bband; 5026 uint16_t i, j, loop_i_max; 5027 uint16_t trsw_rx; 5028 uint16_t loop1_outer_done, loop1_inner_done; 5029 5030 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5031 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 5032 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5033 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5034 if (phy->rev != 1) { 5035 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5036 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5037 } 5038 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5039 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5040 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5041 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 5042 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 5043 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5044 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5045 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 5046 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5047 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5048 backup_bband = pg->pg_bbatt.att; 5049 backup_radio[0] = BWN_RF_READ(mac, 0x52); 5050 backup_radio[1] = BWN_RF_READ(mac, 0x43); 5051 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 5052 5053 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 5054 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 5055 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 5056 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 5057 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 5058 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 5059 if (phy->rev != 1) { 5060 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 5061 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 5062 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 5063 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 5064 } 5065 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 5066 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 5067 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 5068 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 5069 5070 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 5071 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5072 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5073 5074 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 5075 if (phy->rev != 1) { 5076 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 5077 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 5078 } 5079 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 5080 5081 if (phy->rf_rev == 8) 5082 BWN_RF_WRITE(mac, 0x43, 0x000f); 5083 else { 5084 BWN_RF_WRITE(mac, 0x52, 0); 5085 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 5086 } 5087 bwn_phy_g_set_bbatt(mac, 11); 5088 5089 if (phy->rev >= 3) 5090 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5091 else 5092 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5093 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5094 5095 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5096 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5097 5098 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5099 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5100 5101 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) { 5102 if (phy->rev >= 7) { 5103 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5104 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5105 } 5106 } 5107 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5108 5109 j = 0; 5110 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5111 for (i = 0; i < loop_i_max; i++) { 5112 for (j = 0; j < 16; j++) { 5113 BWN_RF_WRITE(mac, 0x43, i); 5114 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5115 (j << 8)); 5116 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5117 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5118 DELAY(20); 5119 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5120 goto done0; 5121 } 5122 } 5123done0: 5124 loop1_outer_done = i; 5125 loop1_inner_done = j; 5126 if (j >= 8) { 5127 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5128 trsw_rx = 0x1b; 5129 for (j = j - 8; j < 16; j++) { 5130 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5131 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5132 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5133 DELAY(20); 5134 trsw_rx -= 3; 5135 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5136 goto done1; 5137 } 5138 } else 5139 trsw_rx = 0x18; 5140done1: 5141 5142 if (phy->rev != 1) { 5143 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5144 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5145 } 5146 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5147 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5148 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5150 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5151 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5152 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5153 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5154 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5155 5156 bwn_phy_g_set_bbatt(mac, backup_bband); 5157 5158 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5159 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5160 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5161 5162 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5163 DELAY(10); 5164 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5165 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5166 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5167 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5168 5169 pg->pg_max_lb_gain = 5170 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5171 pg->pg_trsw_rx_gain = trsw_rx * 2; 5172} 5173 5174static uint16_t 5175bwn_rf_init_bcm2050(struct bwn_mac *mac) 5176{ 5177 struct bwn_phy *phy = &mac->mac_phy; 5178 uint32_t tmp1 = 0, tmp2 = 0; 5179 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5180 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5181 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5182 static const uint8_t rcc_table[] = { 5183 0x02, 0x03, 0x01, 0x0f, 5184 0x06, 0x07, 0x05, 0x0f, 5185 0x0a, 0x0b, 0x09, 0x0f, 5186 0x0e, 0x0f, 0x0d, 0x0f, 5187 }; 5188 5189 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5190 rfoverval = rfover = cck3 = 0; 5191 radio0 = BWN_RF_READ(mac, 0x43); 5192 radio1 = BWN_RF_READ(mac, 0x51); 5193 radio2 = BWN_RF_READ(mac, 0x52); 5194 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5195 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5196 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5197 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5198 5199 if (phy->type == BWN_PHYTYPE_B) { 5200 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5201 reg0 = BWN_READ_2(mac, 0x3ec); 5202 5203 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5204 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5205 } else if (phy->gmode || phy->rev >= 2) { 5206 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5207 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5208 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5209 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5210 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5211 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5212 5213 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5214 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5215 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5216 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5217 if (BWN_HAS_LOOPBACK(phy)) { 5218 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5219 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5220 if (phy->rev >= 3) 5221 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5222 else 5223 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5224 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5225 } 5226 5227 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5228 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5229 BWN_LPD(0, 1, 1))); 5230 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5231 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5232 } 5233 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5234 5235 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5236 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5237 reg1 = BWN_READ_2(mac, 0x3e6); 5238 reg2 = BWN_READ_2(mac, 0x3f4); 5239 5240 if (phy->analog == 0) 5241 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5242 else { 5243 if (phy->analog >= 2) 5244 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5245 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5246 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5247 } 5248 5249 reg = BWN_RF_READ(mac, 0x60); 5250 index = (reg & 0x001e) >> 1; 5251 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5252 5253 if (phy->type == BWN_PHYTYPE_B) 5254 BWN_RF_WRITE(mac, 0x78, 0x26); 5255 if (phy->gmode || phy->rev >= 2) { 5256 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5257 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5258 BWN_LPD(0, 1, 1))); 5259 } 5260 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5261 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5262 if (phy->gmode || phy->rev >= 2) { 5263 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5264 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5265 BWN_LPD(0, 0, 1))); 5266 } 5267 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5268 BWN_RF_SET(mac, 0x51, 0x0004); 5269 if (phy->rf_rev == 8) 5270 BWN_RF_WRITE(mac, 0x43, 0x1f); 5271 else { 5272 BWN_RF_WRITE(mac, 0x52, 0); 5273 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5274 } 5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5276 5277 for (i = 0; i < 16; i++) { 5278 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5279 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5280 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5281 if (phy->gmode || phy->rev >= 2) { 5282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5283 bwn_rf_2050_rfoverval(mac, 5284 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5285 } 5286 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5287 DELAY(10); 5288 if (phy->gmode || phy->rev >= 2) { 5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5290 bwn_rf_2050_rfoverval(mac, 5291 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5292 } 5293 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5294 DELAY(10); 5295 if (phy->gmode || phy->rev >= 2) { 5296 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5297 bwn_rf_2050_rfoverval(mac, 5298 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5299 } 5300 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5301 DELAY(20); 5302 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5303 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5304 if (phy->gmode || phy->rev >= 2) { 5305 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5306 bwn_rf_2050_rfoverval(mac, 5307 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5308 } 5309 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5310 } 5311 DELAY(10); 5312 5313 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5314 tmp1++; 5315 tmp1 >>= 9; 5316 5317 for (i = 0; i < 16; i++) { 5318 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5319 BWN_RF_WRITE(mac, 0x78, radio78); 5320 DELAY(10); 5321 for (j = 0; j < 16; j++) { 5322 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5324 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5325 if (phy->gmode || phy->rev >= 2) { 5326 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5327 bwn_rf_2050_rfoverval(mac, 5328 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5329 } 5330 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5331 DELAY(10); 5332 if (phy->gmode || phy->rev >= 2) { 5333 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5334 bwn_rf_2050_rfoverval(mac, 5335 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5336 } 5337 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5338 DELAY(10); 5339 if (phy->gmode || phy->rev >= 2) { 5340 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5341 bwn_rf_2050_rfoverval(mac, 5342 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5343 } 5344 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5345 DELAY(10); 5346 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5347 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5348 if (phy->gmode || phy->rev >= 2) { 5349 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5350 bwn_rf_2050_rfoverval(mac, 5351 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5352 } 5353 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5354 } 5355 tmp2++; 5356 tmp2 >>= 8; 5357 if (tmp1 < tmp2) 5358 break; 5359 } 5360 5361 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5362 BWN_RF_WRITE(mac, 0x51, radio1); 5363 BWN_RF_WRITE(mac, 0x52, radio2); 5364 BWN_RF_WRITE(mac, 0x43, radio0); 5365 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5366 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5367 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5368 BWN_WRITE_2(mac, 0x3e6, reg1); 5369 if (phy->analog != 0) 5370 BWN_WRITE_2(mac, 0x3f4, reg2); 5371 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5372 bwn_spu_workaround(mac, phy->chan); 5373 if (phy->type == BWN_PHYTYPE_B) { 5374 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5375 BWN_WRITE_2(mac, 0x3ec, reg0); 5376 } else if (phy->gmode) { 5377 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5378 BWN_READ_2(mac, BWN_PHY_RADIO) 5379 & 0x7fff); 5380 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5381 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5382 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5383 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5384 analogoverval); 5385 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5386 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5387 if (BWN_HAS_LOOPBACK(phy)) { 5388 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5389 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5390 } 5391 } 5392 5393 return ((i > 15) ? radio78 : rcc); 5394} 5395 5396static void 5397bwn_phy_init_b6(struct bwn_mac *mac) 5398{ 5399 struct bwn_phy *phy = &mac->mac_phy; 5400 struct bwn_phy_g *pg = &phy->phy_g; 5401 uint16_t offset, val; 5402 uint8_t old_channel; 5403 5404 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5405 ("%s:%d: fail", __func__, __LINE__)); 5406 5407 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5408 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5409 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5410 BWN_RF_WRITE(mac, 0x51, 0x37); 5411 BWN_RF_WRITE(mac, 0x52, 0x70); 5412 BWN_RF_WRITE(mac, 0x53, 0xb3); 5413 BWN_RF_WRITE(mac, 0x54, 0x9b); 5414 BWN_RF_WRITE(mac, 0x5a, 0x88); 5415 BWN_RF_WRITE(mac, 0x5b, 0x88); 5416 BWN_RF_WRITE(mac, 0x5d, 0x88); 5417 BWN_RF_WRITE(mac, 0x5e, 0x88); 5418 BWN_RF_WRITE(mac, 0x7d, 0x88); 5419 bwn_hf_write(mac, 5420 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5421 } 5422 if (phy->rf_rev == 8) { 5423 BWN_RF_WRITE(mac, 0x51, 0); 5424 BWN_RF_WRITE(mac, 0x52, 0x40); 5425 BWN_RF_WRITE(mac, 0x53, 0xb7); 5426 BWN_RF_WRITE(mac, 0x54, 0x98); 5427 BWN_RF_WRITE(mac, 0x5a, 0x88); 5428 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5429 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5430 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) { 5431 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5432 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5433 } else { 5434 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5435 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5436 } 5437 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5438 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5439 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5440 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5441 } 5442 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5443 BWN_PHY_WRITE(mac, offset, val); 5444 val -= 0x0202; 5445 } 5446 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5447 BWN_PHY_WRITE(mac, offset, val); 5448 val -= 0x0202; 5449 } 5450 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5451 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5452 val += 0x0202; 5453 } 5454 if (phy->type == BWN_PHYTYPE_G) { 5455 BWN_RF_SET(mac, 0x007a, 0x0020); 5456 BWN_RF_SET(mac, 0x0051, 0x0004); 5457 BWN_PHY_SET(mac, 0x0802, 0x0100); 5458 BWN_PHY_SET(mac, 0x042b, 0x2000); 5459 BWN_PHY_WRITE(mac, 0x5b, 0); 5460 BWN_PHY_WRITE(mac, 0x5c, 0); 5461 } 5462 5463 old_channel = phy->chan; 5464 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5465 5466 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5467 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5468 DELAY(40); 5469 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5470 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5471 BWN_RF_WRITE(mac, 0x50, 0x20); 5472 } 5473 if (phy->rf_rev <= 2) { 5474 BWN_RF_WRITE(mac, 0x7c, 0x20); 5475 BWN_RF_WRITE(mac, 0x5a, 0x70); 5476 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5477 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5478 } 5479 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5480 5481 bwn_phy_g_switch_chan(mac, old_channel, 0); 5482 5483 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5484 if (phy->rf_rev >= 6) 5485 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5486 else 5487 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5488 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5489 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5490 pg->pg_txctl); 5491 if (phy->rf_rev <= 5) 5492 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5493 if (phy->rf_rev <= 2) 5494 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5495 5496 if (phy->analog == 4) { 5497 BWN_WRITE_2(mac, 0x3e4, 9); 5498 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5499 } else 5500 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5501 if (phy->type == BWN_PHYTYPE_B) 5502 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5503 else if (phy->type == BWN_PHYTYPE_G) 5504 BWN_WRITE_2(mac, 0x03e6, 0x0); 5505} 5506 5507static void 5508bwn_phy_init_a(struct bwn_mac *mac) 5509{ 5510 struct bwn_phy *phy = &mac->mac_phy; 5511 5512 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5513 ("%s:%d: fail", __func__, __LINE__)); 5514 5515 if (phy->rev >= 6) { 5516 if (phy->type == BWN_PHYTYPE_A) 5517 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5518 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5519 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5520 else 5521 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5522 } 5523 5524 bwn_wa_init(mac); 5525 5526 if (phy->type == BWN_PHYTYPE_G && 5527 (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)) 5528 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5529} 5530 5531static void 5532bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5533{ 5534 int i; 5535 5536 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5537 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5538} 5539 5540static void 5541bwn_wa_agc(struct bwn_mac *mac) 5542{ 5543 struct bwn_phy *phy = &mac->mac_phy; 5544 5545 if (phy->rev == 1) { 5546 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5547 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5548 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5549 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5550 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5551 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5552 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5554 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5555 } else { 5556 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5557 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5560 } 5561 5562 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5563 0x5700); 5564 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5565 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5566 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5567 BWN_RF_SET(mac, 0x7a, 0x0008); 5568 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5569 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5570 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5571 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5572 if (phy->rev == 1) 5573 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5574 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5575 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5576 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5577 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5578 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5579 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5580 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5581 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5582 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5583 if (phy->rev == 1) { 5584 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5585 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5586 } else { 5587 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5588 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5589 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5590 if (phy->rev >= 6) { 5591 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5592 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5593 (uint16_t)~0xf000, 0x3000); 5594 } 5595 } 5596 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5597 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5598 if (phy->rev == 1) { 5599 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5600 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5601 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5602 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5603 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5604 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5605 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5606 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5607 } else { 5608 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5609 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5610 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5611 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5612 } 5613 if (phy->rev >= 6) { 5614 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5615 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5616 } 5617 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5618} 5619 5620static void 5621bwn_wa_grev1(struct bwn_mac *mac) 5622{ 5623 struct bwn_phy *phy = &mac->mac_phy; 5624 int i; 5625 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5626 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5627 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5628 5629 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5630 5631 /* init CRSTHRES and ANTDWELL */ 5632 if (phy->rev == 1) { 5633 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5634 } else if (phy->rev == 2) { 5635 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5636 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5637 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5638 } else { 5639 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5640 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5641 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5642 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5643 } 5644 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5645 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5646 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5647 5648 /* XXX support PHY-A??? */ 5649 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5650 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5651 bwn_tab_finefreqg[i]); 5652 5653 /* XXX support PHY-A??? */ 5654 if (phy->rev == 1) 5655 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5656 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5657 bwn_tab_noise_g1[i]); 5658 else 5659 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5660 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5661 bwn_tab_noise_g2[i]); 5662 5663 5664 for (i = 0; i < N(bwn_tab_rotor); i++) 5665 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5666 bwn_tab_rotor[i]); 5667 5668 /* XXX support PHY-A??? */ 5669 if (phy->rev >= 6) { 5670 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5671 BWN_PHY_ENCORE_EN) 5672 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5673 else 5674 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5675 } else 5676 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5677 5678 for (i = 0; i < N(bwn_tab_retard); i++) 5679 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5680 bwn_tab_retard[i]); 5681 5682 if (phy->rev == 1) { 5683 for (i = 0; i < 16; i++) 5684 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5685 i, 0x0020); 5686 } else { 5687 for (i = 0; i < 32; i++) 5688 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5689 } 5690 5691 bwn_wa_agc(mac); 5692} 5693 5694static void 5695bwn_wa_grev26789(struct bwn_mac *mac) 5696{ 5697 struct bwn_phy *phy = &mac->mac_phy; 5698 int i; 5699 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5700 uint16_t ofdmrev; 5701 5702 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5703 5704 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5705 5706 /* init CRSTHRES and ANTDWELL */ 5707 if (phy->rev == 1) 5708 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5709 else if (phy->rev == 2) { 5710 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5711 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5712 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5713 } else { 5714 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5715 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5716 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5717 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5718 } 5719 5720 for (i = 0; i < 64; i++) 5721 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5722 5723 /* XXX support PHY-A??? */ 5724 if (phy->rev == 1) 5725 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5727 bwn_tab_noise_g1[i]); 5728 else 5729 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5731 bwn_tab_noise_g2[i]); 5732 5733 /* XXX support PHY-A??? */ 5734 if (phy->rev >= 6) { 5735 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5736 BWN_PHY_ENCORE_EN) 5737 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5738 else 5739 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5740 } else 5741 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5742 5743 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5744 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5745 bwn_tab_sigmasqr2[i]); 5746 5747 if (phy->rev == 1) { 5748 for (i = 0; i < 16; i++) 5749 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5750 0x0020); 5751 } else { 5752 for (i = 0; i < 32; i++) 5753 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5754 } 5755 5756 bwn_wa_agc(mac); 5757 5758 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5759 if (ofdmrev > 2) { 5760 if (phy->type == BWN_PHYTYPE_A) 5761 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5762 else 5763 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5764 } else { 5765 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5766 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5767 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5768 } 5769 5770 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5771 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5772} 5773 5774static void 5775bwn_wa_init(struct bwn_mac *mac) 5776{ 5777 struct bwn_phy *phy = &mac->mac_phy; 5778 struct siba_softc *bus = mac->mac_sd->sd_bus; 5779 5780 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5781 5782 switch (phy->rev) { 5783 case 1: 5784 bwn_wa_grev1(mac); 5785 break; 5786 case 2: 5787 case 6: 5788 case 7: 5789 case 8: 5790 case 9: 5791 bwn_wa_grev26789(mac); 5792 break; 5793 default: 5794 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5795 } 5796 5797 if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM || 5798 bus->siba_board_type != SIBA_BOARD_BU4306 || 5799 bus->siba_board_rev != 0x17) { 5800 if (phy->rev < 2) { 5801 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5802 0x0002); 5803 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5804 0x0001); 5805 } else { 5806 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5807 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5808 if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) && 5809 (phy->rev >= 7)) { 5810 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5811 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5812 0x0020, 0x0001); 5813 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5814 0x0021, 0x0001); 5815 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5816 0x0022, 0x0001); 5817 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5818 0x0023, 0x0000); 5819 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5820 0x0000, 0x0000); 5821 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5822 0x0003, 0x0002); 5823 } 5824 } 5825 } 5826 if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) { 5827 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5828 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5829 } 5830 5831 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5832 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5833} 5834 5835static void 5836bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5837 uint16_t value) 5838{ 5839 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5840 uint16_t addr; 5841 5842 addr = table + offset; 5843 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5844 (addr - 1 != pg->pg_ofdmtab_addr)) { 5845 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5846 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5847 } 5848 pg->pg_ofdmtab_addr = addr; 5849 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5850} 5851 5852static void 5853bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5854 uint32_t value) 5855{ 5856 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5857 uint16_t addr; 5858 5859 addr = table + offset; 5860 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5861 (addr - 1 != pg->pg_ofdmtab_addr)) { 5862 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5863 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5864 } 5865 pg->pg_ofdmtab_addr = addr; 5866 5867 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5868 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5869} 5870 5871static void 5872bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5873 uint16_t value) 5874{ 5875 5876 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5877 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5878} 5879 5880static void 5881bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5882{ 5883 struct bwn_phy *phy = &mac->mac_phy; 5884 unsigned int i, max_loop; 5885 uint16_t value; 5886 uint32_t buffer[5] = { 5887 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5888 }; 5889 5890 if (ofdm) { 5891 max_loop = 0x1e; 5892 buffer[0] = 0x000201cc; 5893 } else { 5894 max_loop = 0xfa; 5895 buffer[0] = 0x000b846e; 5896 } 5897 5898 BWN_ASSERT_LOCKED(mac->mac_sc); 5899 5900 for (i = 0; i < 5; i++) 5901 bwn_ram_write(mac, i * 4, buffer[i]); 5902 5903 BWN_WRITE_2(mac, 0x0568, 0x0000); 5904 BWN_WRITE_2(mac, 0x07c0, 5905 (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100); 5906 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5907 BWN_WRITE_2(mac, 0x050c, value); 5908 if (phy->type == BWN_PHYTYPE_LP) 5909 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5910 BWN_WRITE_2(mac, 0x0508, 0x0000); 5911 BWN_WRITE_2(mac, 0x050a, 0x0000); 5912 BWN_WRITE_2(mac, 0x054c, 0x0000); 5913 BWN_WRITE_2(mac, 0x056a, 0x0014); 5914 BWN_WRITE_2(mac, 0x0568, 0x0826); 5915 BWN_WRITE_2(mac, 0x0500, 0x0000); 5916 if (phy->type == BWN_PHYTYPE_LP) 5917 BWN_WRITE_2(mac, 0x0502, 0x0050); 5918 else 5919 BWN_WRITE_2(mac, 0x0502, 0x0030); 5920 5921 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5922 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5923 for (i = 0x00; i < max_loop; i++) { 5924 value = BWN_READ_2(mac, 0x050e); 5925 if (value & 0x0080) 5926 break; 5927 DELAY(10); 5928 } 5929 for (i = 0x00; i < 0x0a; i++) { 5930 value = BWN_READ_2(mac, 0x050e); 5931 if (value & 0x0400) 5932 break; 5933 DELAY(10); 5934 } 5935 for (i = 0x00; i < 0x19; i++) { 5936 value = BWN_READ_2(mac, 0x0690); 5937 if (!(value & 0x0100)) 5938 break; 5939 DELAY(10); 5940 } 5941 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5942 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5943} 5944 5945static void 5946bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5947{ 5948 uint32_t macctl; 5949 5950 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5951 5952 macctl = BWN_READ_4(mac, BWN_MACCTL); 5953 if (macctl & BWN_MACCTL_BIGENDIAN) 5954 printf("TODO: need swap\n"); 5955 5956 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5957 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5958 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5959} 5960 5961static void 5962bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5963{ 5964 uint16_t value; 5965 5966 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5967 ("%s:%d: fail", __func__, __LINE__)); 5968 5969 value = (uint8_t) (ctl->q); 5970 value |= ((uint8_t) (ctl->i)) << 8; 5971 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5972} 5973 5974static uint16_t 5975bwn_lo_calcfeed(struct bwn_mac *mac, 5976 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5977{ 5978 struct bwn_phy *phy = &mac->mac_phy; 5979 uint16_t rfover; 5980 uint16_t feedthrough; 5981 5982 if (phy->gmode) { 5983 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5984 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5985 5986 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5987 ("%s:%d: fail", __func__, __LINE__)); 5988 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5989 ("%s:%d: fail", __func__, __LINE__)); 5990 5991 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5992 5993 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5994 if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) 5995 && phy->rev > 6) 5996 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5997 5998 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5999 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6000 DELAY(10); 6001 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 6002 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6003 DELAY(10); 6004 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 6005 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6006 DELAY(10); 6007 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 6008 } else { 6009 pga |= BWN_PHY_PGACTL_UNKNOWN; 6010 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6011 DELAY(10); 6012 pga |= BWN_PHY_PGACTL_LOWBANDW; 6013 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6014 DELAY(10); 6015 pga |= BWN_PHY_PGACTL_LPF; 6016 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6017 } 6018 DELAY(21); 6019 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 6020 6021 return (feedthrough); 6022} 6023 6024static uint16_t 6025bwn_lo_txctl_regtable(struct bwn_mac *mac, 6026 uint16_t *value, uint16_t *pad_mix_gain) 6027{ 6028 struct bwn_phy *phy = &mac->mac_phy; 6029 uint16_t reg, v, padmix; 6030 6031 if (phy->type == BWN_PHYTYPE_B) { 6032 v = 0x30; 6033 if (phy->rf_rev <= 5) { 6034 reg = 0x43; 6035 padmix = 0; 6036 } else { 6037 reg = 0x52; 6038 padmix = 5; 6039 } 6040 } else { 6041 if (phy->rev >= 2 && phy->rf_rev == 8) { 6042 reg = 0x43; 6043 v = 0x10; 6044 padmix = 2; 6045 } else { 6046 reg = 0x52; 6047 v = 0x30; 6048 padmix = 5; 6049 } 6050 } 6051 if (value) 6052 *value = v; 6053 if (pad_mix_gain) 6054 *pad_mix_gain = padmix; 6055 6056 return (reg); 6057} 6058 6059static void 6060bwn_lo_measure_txctl_values(struct bwn_mac *mac) 6061{ 6062 struct bwn_phy *phy = &mac->mac_phy; 6063 struct bwn_phy_g *pg = &phy->phy_g; 6064 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6065 uint16_t reg, mask; 6066 uint16_t trsw_rx, pga; 6067 uint16_t rf_pctl_reg; 6068 6069 static const uint8_t tx_bias_values[] = { 6070 0x09, 0x08, 0x0a, 0x01, 0x00, 6071 0x02, 0x05, 0x04, 0x06, 6072 }; 6073 static const uint8_t tx_magn_values[] = { 6074 0x70, 0x40, 6075 }; 6076 6077 if (!BWN_HAS_LOOPBACK(phy)) { 6078 rf_pctl_reg = 6; 6079 trsw_rx = 2; 6080 pga = 0; 6081 } else { 6082 int lb_gain; 6083 6084 trsw_rx = 0; 6085 lb_gain = pg->pg_max_lb_gain / 2; 6086 if (lb_gain > 10) { 6087 rf_pctl_reg = 0; 6088 pga = abs(10 - lb_gain) / 6; 6089 pga = MIN(MAX(pga, 0), 15); 6090 } else { 6091 int cmp_val; 6092 int tmp; 6093 6094 pga = 0; 6095 cmp_val = 0x24; 6096 if ((phy->rev >= 2) && 6097 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6098 cmp_val = 0x3c; 6099 tmp = lb_gain; 6100 if ((10 - lb_gain) < cmp_val) 6101 tmp = (10 - lb_gain); 6102 if (tmp < 0) 6103 tmp += 6; 6104 else 6105 tmp += 3; 6106 cmp_val /= 4; 6107 tmp /= 4; 6108 if (tmp >= cmp_val) 6109 rf_pctl_reg = cmp_val; 6110 else 6111 rf_pctl_reg = tmp; 6112 } 6113 } 6114 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6115 bwn_phy_g_set_bbatt(mac, 2); 6116 6117 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6118 mask = ~mask; 6119 BWN_RF_MASK(mac, reg, mask); 6120 6121 if (BWN_HAS_TXMAG(phy)) { 6122 int i, j; 6123 int feedthrough; 6124 int min_feedth = 0xffff; 6125 uint8_t tx_magn, tx_bias; 6126 6127 for (i = 0; i < N(tx_magn_values); i++) { 6128 tx_magn = tx_magn_values[i]; 6129 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6130 for (j = 0; j < N(tx_bias_values); j++) { 6131 tx_bias = tx_bias_values[j]; 6132 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6133 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6134 trsw_rx); 6135 if (feedthrough < min_feedth) { 6136 lo->tx_bias = tx_bias; 6137 lo->tx_magn = tx_magn; 6138 min_feedth = feedthrough; 6139 } 6140 if (lo->tx_bias == 0) 6141 break; 6142 } 6143 BWN_RF_WRITE(mac, 0x52, 6144 (BWN_RF_READ(mac, 0x52) 6145 & 0xff00) | lo->tx_bias | lo-> 6146 tx_magn); 6147 } 6148 } else { 6149 lo->tx_magn = 0; 6150 lo->tx_bias = 0; 6151 BWN_RF_MASK(mac, 0x52, 0xfff0); 6152 } 6153 6154 BWN_GETTIME(lo->txctl_measured_time); 6155} 6156 6157static void 6158bwn_lo_get_powervector(struct bwn_mac *mac) 6159{ 6160 struct bwn_phy *phy = &mac->mac_phy; 6161 struct bwn_phy_g *pg = &phy->phy_g; 6162 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6163 int i; 6164 uint64_t tmp; 6165 uint64_t power_vector = 0; 6166 6167 for (i = 0; i < 8; i += 2) { 6168 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6169 power_vector |= (tmp << (i * 8)); 6170 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6171 } 6172 if (power_vector) 6173 lo->power_vector = power_vector; 6174 6175 BWN_GETTIME(lo->pwr_vec_read_time); 6176} 6177 6178static void 6179bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6180 int use_trsw_rx) 6181{ 6182 struct bwn_phy *phy = &mac->mac_phy; 6183 struct bwn_phy_g *pg = &phy->phy_g; 6184 uint16_t tmp; 6185 6186 if (max_rx_gain < 0) 6187 max_rx_gain = 0; 6188 6189 if (BWN_HAS_LOOPBACK(phy)) { 6190 int trsw_rx = 0; 6191 int trsw_rx_gain; 6192 6193 if (use_trsw_rx) { 6194 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6195 if (max_rx_gain >= trsw_rx_gain) { 6196 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6197 trsw_rx = 0x20; 6198 } 6199 } else 6200 trsw_rx_gain = max_rx_gain; 6201 if (trsw_rx_gain < 9) { 6202 pg->pg_lna_lod_gain = 0; 6203 } else { 6204 pg->pg_lna_lod_gain = 1; 6205 trsw_rx_gain -= 8; 6206 } 6207 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6208 pg->pg_pga_gain = trsw_rx_gain / 3; 6209 if (pg->pg_pga_gain >= 5) { 6210 pg->pg_pga_gain -= 5; 6211 pg->pg_lna_gain = 2; 6212 } else 6213 pg->pg_lna_gain = 0; 6214 } else { 6215 pg->pg_lna_gain = 0; 6216 pg->pg_trsw_rx_gain = 0x20; 6217 if (max_rx_gain >= 0x14) { 6218 pg->pg_lna_lod_gain = 1; 6219 pg->pg_pga_gain = 2; 6220 } else if (max_rx_gain >= 0x12) { 6221 pg->pg_lna_lod_gain = 1; 6222 pg->pg_pga_gain = 1; 6223 } else if (max_rx_gain >= 0xf) { 6224 pg->pg_lna_lod_gain = 1; 6225 pg->pg_pga_gain = 0; 6226 } else { 6227 pg->pg_lna_lod_gain = 0; 6228 pg->pg_pga_gain = 0; 6229 } 6230 } 6231 6232 tmp = BWN_RF_READ(mac, 0x7a); 6233 if (pg->pg_lna_lod_gain == 0) 6234 tmp &= ~0x0008; 6235 else 6236 tmp |= 0x0008; 6237 BWN_RF_WRITE(mac, 0x7a, tmp); 6238} 6239 6240static void 6241bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6242{ 6243 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 6244 struct bwn_phy *phy = &mac->mac_phy; 6245 struct bwn_phy_g *pg = &phy->phy_g; 6246 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6247 struct timespec ts; 6248 uint16_t tmp; 6249 6250 if (bwn_has_hwpctl(mac)) { 6251 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6252 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6253 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6254 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6255 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6256 6257 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6258 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6259 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6260 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6261 } 6262 if (phy->type == BWN_PHYTYPE_B && 6263 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6264 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6265 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6266 } 6267 if (phy->rev >= 2) { 6268 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6269 sav->phy_analogoverval = 6270 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6271 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6272 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6273 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6274 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6275 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6276 6277 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6278 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6279 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6280 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6281 if (phy->type == BWN_PHYTYPE_G) { 6282 if ((phy->rev >= 7) && 6283 (sprom->bf_lo & BWN_BFL_EXTLNA)) { 6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6285 } else { 6286 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6287 } 6288 } else { 6289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6290 } 6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6292 } 6293 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6294 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6295 sav->rf0 = BWN_RF_READ(mac, 0x43); 6296 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6297 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6298 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6299 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6300 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6301 6302 if (!BWN_HAS_TXMAG(phy)) { 6303 sav->rf2 = BWN_RF_READ(mac, 0x52); 6304 sav->rf2 &= 0x00f0; 6305 } 6306 if (phy->type == BWN_PHYTYPE_B) { 6307 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6308 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6309 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6310 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6311 } else { 6312 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6313 | 0x8000); 6314 } 6315 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6316 & 0xf000); 6317 6318 tmp = 6319 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6320 BWN_PHY_WRITE(mac, tmp, 0x007f); 6321 6322 tmp = sav->phy_syncctl; 6323 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6324 tmp = sav->rf1; 6325 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6326 6327 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6328 if (phy->type == BWN_PHYTYPE_G || 6329 (phy->type == BWN_PHYTYPE_B && 6330 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6331 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6332 } else 6333 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6334 if (phy->rev >= 2) 6335 bwn_dummy_transmission(mac, 0, 1); 6336 bwn_phy_g_switch_chan(mac, 6, 0); 6337 BWN_RF_READ(mac, 0x51); 6338 if (phy->type == BWN_PHYTYPE_G) 6339 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6340 6341 nanouptime(&ts); 6342 if (time_before(lo->txctl_measured_time, 6343 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6344 bwn_lo_measure_txctl_values(mac); 6345 6346 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6347 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6348 else { 6349 if (phy->type == BWN_PHYTYPE_B) 6350 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6351 else 6352 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6353 } 6354} 6355 6356static void 6357bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6358{ 6359 struct bwn_phy *phy = &mac->mac_phy; 6360 struct bwn_phy_g *pg = &phy->phy_g; 6361 uint16_t tmp; 6362 6363 if (phy->rev >= 2) { 6364 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6365 tmp = (pg->pg_pga_gain << 8); 6366 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6367 DELAY(5); 6368 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6369 DELAY(2); 6370 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6371 } else { 6372 tmp = (pg->pg_pga_gain | 0xefa0); 6373 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6374 } 6375 if (phy->type == BWN_PHYTYPE_G) { 6376 if (phy->rev >= 3) 6377 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6378 else 6379 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6380 if (phy->rev >= 2) 6381 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6382 else 6383 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6384 } 6385 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6386 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6387 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6388 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6389 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6390 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6391 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6392 if (!BWN_HAS_TXMAG(phy)) { 6393 tmp = sav->rf2; 6394 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6395 } 6396 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6397 if (phy->type == BWN_PHYTYPE_B && 6398 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6399 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6400 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6401 } 6402 if (phy->rev >= 2) { 6403 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6404 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6405 sav->phy_analogoverval); 6406 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6407 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6408 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6409 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6410 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6411 } 6412 if (bwn_has_hwpctl(mac)) { 6413 tmp = (sav->phy_lomask & 0xbfff); 6414 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6415 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6416 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6417 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6418 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6419 } 6420 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6421} 6422 6423static int 6424bwn_lo_probe_loctl(struct bwn_mac *mac, 6425 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6426{ 6427 struct bwn_phy *phy = &mac->mac_phy; 6428 struct bwn_phy_g *pg = &phy->phy_g; 6429 struct bwn_loctl orig, test; 6430 struct bwn_loctl prev = { -100, -100 }; 6431 static const struct bwn_loctl modifiers[] = { 6432 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6433 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6434 }; 6435 int begin, end, lower = 0, i; 6436 uint16_t feedth; 6437 6438 if (d->curstate == 0) { 6439 begin = 1; 6440 end = 8; 6441 } else if (d->curstate % 2 == 0) { 6442 begin = d->curstate - 1; 6443 end = d->curstate + 1; 6444 } else { 6445 begin = d->curstate - 2; 6446 end = d->curstate + 2; 6447 } 6448 if (begin < 1) 6449 begin += 8; 6450 if (end > 8) 6451 end -= 8; 6452 6453 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6454 i = begin; 6455 d->curstate = i; 6456 while (1) { 6457 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6458 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6459 test.i += modifiers[i - 1].i * d->multipler; 6460 test.q += modifiers[i - 1].q * d->multipler; 6461 if ((test.i != prev.i || test.q != prev.q) && 6462 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6463 bwn_lo_write(mac, &test); 6464 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6465 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6466 if (feedth < d->feedth) { 6467 memcpy(probe, &test, 6468 sizeof(struct bwn_loctl)); 6469 lower = 1; 6470 d->feedth = feedth; 6471 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6472 break; 6473 } 6474 } 6475 memcpy(&prev, &test, sizeof(prev)); 6476 if (i == end) 6477 break; 6478 if (i == 8) 6479 i = 1; 6480 else 6481 i++; 6482 d->curstate = i; 6483 } 6484 6485 return (lower); 6486} 6487 6488static void 6489bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6490{ 6491 struct bwn_phy *phy = &mac->mac_phy; 6492 struct bwn_phy_g *pg = &phy->phy_g; 6493 struct bwn_lo_g_sm d; 6494 struct bwn_loctl probe; 6495 int lower, repeat, cnt = 0; 6496 uint16_t feedth; 6497 6498 d.nmeasure = 0; 6499 d.multipler = 1; 6500 if (BWN_HAS_LOOPBACK(phy)) 6501 d.multipler = 3; 6502 6503 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6504 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6505 6506 do { 6507 bwn_lo_write(mac, &d.loctl); 6508 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6509 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6510 if (feedth < 0x258) { 6511 if (feedth >= 0x12c) 6512 *rxgain += 6; 6513 else 6514 *rxgain += 3; 6515 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6516 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6517 } 6518 d.feedth = feedth; 6519 d.curstate = 0; 6520 do { 6521 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6522 ("%s:%d: fail", __func__, __LINE__)); 6523 memcpy(&probe, &d.loctl, 6524 sizeof(struct bwn_loctl)); 6525 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6526 if (!lower) 6527 break; 6528 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6529 break; 6530 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6531 d.nmeasure++; 6532 } while (d.nmeasure < 24); 6533 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6534 6535 if (BWN_HAS_LOOPBACK(phy)) { 6536 if (d.feedth > 0x1194) 6537 *rxgain -= 6; 6538 else if (d.feedth < 0x5dc) 6539 *rxgain += 3; 6540 if (cnt == 0) { 6541 if (d.feedth <= 0x5dc) { 6542 d.multipler = 1; 6543 cnt++; 6544 } else 6545 d.multipler = 2; 6546 } else if (cnt == 2) 6547 d.multipler = 1; 6548 } 6549 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6550 } while (++cnt < repeat); 6551} 6552 6553static struct bwn_lo_calib * 6554bwn_lo_calibset(struct bwn_mac *mac, 6555 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6556{ 6557 struct bwn_phy *phy = &mac->mac_phy; 6558 struct bwn_phy_g *pg = &phy->phy_g; 6559 struct bwn_loctl loctl = { 0, 0 }; 6560 struct bwn_lo_calib *cal; 6561 struct bwn_lo_g_value sval = { 0 }; 6562 int rxgain; 6563 uint16_t pad, reg, value; 6564 6565 sval.old_channel = phy->chan; 6566 bwn_mac_suspend(mac); 6567 bwn_lo_save(mac, &sval); 6568 6569 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6570 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6571 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6572 6573 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6574 if (rfatt->padmix) 6575 rxgain -= pad; 6576 if (BWN_HAS_LOOPBACK(phy)) 6577 rxgain += pg->pg_max_lb_gain; 6578 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6579 bwn_phy_g_set_bbatt(mac, bbatt->att); 6580 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6581 6582 bwn_lo_restore(mac, &sval); 6583 bwn_mac_enable(mac); 6584 6585 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6586 if (!cal) { 6587 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6588 return (NULL); 6589 } 6590 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6591 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6592 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6593 6594 BWN_GETTIME(cal->calib_time); 6595 6596 return (cal); 6597} 6598 6599static struct bwn_lo_calib * 6600bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6601 const struct bwn_rfatt *rfatt) 6602{ 6603 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6604 struct bwn_lo_calib *c; 6605 6606 TAILQ_FOREACH(c, &lo->calib_list, list) { 6607 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6608 continue; 6609 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6610 continue; 6611 return (c); 6612 } 6613 6614 c = bwn_lo_calibset(mac, bbatt, rfatt); 6615 if (!c) 6616 return (NULL); 6617 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6618 6619 return (c); 6620} 6621 6622static void 6623bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6624{ 6625 struct bwn_phy *phy = &mac->mac_phy; 6626 struct bwn_phy_g *pg = &phy->phy_g; 6627 struct bwn_softc *sc = mac->mac_sc; 6628 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6629 const struct bwn_rfatt *rfatt; 6630 const struct bwn_bbatt *bbatt; 6631 uint64_t pvector; 6632 int i; 6633 int rf_offset, bb_offset; 6634 uint8_t changed = 0; 6635 6636 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6637 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6638 ("%s:%d: fail", __func__, __LINE__)); 6639 6640 pvector = lo->power_vector; 6641 if (!update && !pvector) 6642 return; 6643 6644 bwn_mac_suspend(mac); 6645 6646 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6647 struct bwn_lo_calib *cal; 6648 int idx; 6649 uint16_t val; 6650 6651 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6652 continue; 6653 bb_offset = i / lo->rfatt.len; 6654 rf_offset = i % lo->rfatt.len; 6655 bbatt = &(lo->bbatt.array[bb_offset]); 6656 rfatt = &(lo->rfatt.array[rf_offset]); 6657 6658 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6659 if (!cal) { 6660 device_printf(sc->sc_dev, "LO: Could not " 6661 "calibrate DC table entry\n"); 6662 continue; 6663 } 6664 val = (uint8_t)(cal->ctl.q); 6665 val |= ((uint8_t)(cal->ctl.i)) << 4; 6666 free(cal, M_DEVBUF); 6667 6668 idx = i / 2; 6669 if (i % 2) 6670 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6671 | ((val & 0x00ff) << 8); 6672 else 6673 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6674 | (val & 0x00ff); 6675 changed = 1; 6676 } 6677 if (changed) { 6678 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6679 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6680 } 6681 bwn_mac_enable(mac); 6682} 6683 6684static void 6685bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6686{ 6687 6688 if (!rf->padmix) 6689 return; 6690 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6691 rf->att = 4; 6692} 6693 6694static void 6695bwn_lo_g_adjust(struct bwn_mac *mac) 6696{ 6697 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6698 struct bwn_lo_calib *cal; 6699 struct bwn_rfatt rf; 6700 6701 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6702 bwn_lo_fixup_rfatt(&rf); 6703 6704 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6705 if (!cal) 6706 return; 6707 bwn_lo_write(mac, &cal->ctl); 6708} 6709 6710static void 6711bwn_lo_g_init(struct bwn_mac *mac) 6712{ 6713 6714 if (!bwn_has_hwpctl(mac)) 6715 return; 6716 6717 bwn_lo_get_powervector(mac); 6718 bwn_phy_g_dc_lookup_init(mac, 1); 6719} 6720 6721static void 6722bwn_mac_suspend(struct bwn_mac *mac) 6723{ 6724 struct bwn_softc *sc = mac->mac_sc; 6725 int i; 6726 uint32_t tmp; 6727 6728 KASSERT(mac->mac_suspended >= 0, 6729 ("%s:%d: fail", __func__, __LINE__)); 6730 6731 if (mac->mac_suspended == 0) { 6732 bwn_psctl(mac, BWN_PS_AWAKE); 6733 BWN_WRITE_4(mac, BWN_MACCTL, 6734 BWN_READ_4(mac, BWN_MACCTL) 6735 & ~BWN_MACCTL_ON); 6736 BWN_READ_4(mac, BWN_MACCTL); 6737 for (i = 35; i; i--) { 6738 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6739 if (tmp & BWN_INTR_MAC_SUSPENDED) 6740 goto out; 6741 DELAY(10); 6742 } 6743 for (i = 40; i; i--) { 6744 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6745 if (tmp & BWN_INTR_MAC_SUSPENDED) 6746 goto out; 6747 DELAY(1000); 6748 } 6749 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6750 } 6751out: 6752 mac->mac_suspended++; 6753} 6754 6755static void 6756bwn_mac_enable(struct bwn_mac *mac) 6757{ 6758 struct bwn_softc *sc = mac->mac_sc; 6759 uint16_t state; 6760 6761 state = bwn_shm_read_2(mac, BWN_SHARED, 6762 BWN_SHARED_UCODESTAT); 6763 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6764 state != BWN_SHARED_UCODESTAT_SLEEP) 6765 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6766 6767 mac->mac_suspended--; 6768 KASSERT(mac->mac_suspended >= 0, 6769 ("%s:%d: fail", __func__, __LINE__)); 6770 if (mac->mac_suspended == 0) { 6771 BWN_WRITE_4(mac, BWN_MACCTL, 6772 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6773 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6774 BWN_READ_4(mac, BWN_MACCTL); 6775 BWN_READ_4(mac, BWN_INTR_REASON); 6776 bwn_psctl(mac, 0); 6777 } 6778} 6779 6780static void 6781bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6782{ 6783 int i; 6784 uint16_t ucstat; 6785 6786 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6787 ("%s:%d: fail", __func__, __LINE__)); 6788 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6789 ("%s:%d: fail", __func__, __LINE__)); 6790 6791 /* XXX forcibly awake and hwps-off */ 6792 6793 BWN_WRITE_4(mac, BWN_MACCTL, 6794 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6795 ~BWN_MACCTL_HWPS); 6796 BWN_READ_4(mac, BWN_MACCTL); 6797 if (mac->mac_sd->sd_id.sd_rev >= 5) { 6798 for (i = 0; i < 100; i++) { 6799 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6800 BWN_SHARED_UCODESTAT); 6801 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6802 break; 6803 DELAY(10); 6804 } 6805 } 6806} 6807 6808static int16_t 6809bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6810{ 6811 6812 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6813 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6814} 6815 6816static void 6817bwn_nrssi_threshold(struct bwn_mac *mac) 6818{ 6819 struct bwn_phy *phy = &mac->mac_phy; 6820 struct bwn_phy_g *pg = &phy->phy_g; 6821 struct siba_softc *siba = mac->mac_sd->sd_bus; 6822 int32_t a, b; 6823 int16_t tmp16; 6824 uint16_t tmpu16; 6825 6826 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6827 6828 if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 6829 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6830 a = 0x13; 6831 b = 0x12; 6832 } else { 6833 a = 0xe; 6834 b = 0x11; 6835 } 6836 6837 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6838 a += (pg->pg_nrssi[0] << 6); 6839 a += (a < 32) ? 31 : 32; 6840 a = a >> 6; 6841 a = MIN(MAX(a, -31), 31); 6842 6843 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6844 b += (pg->pg_nrssi[0] << 6); 6845 if (b < 32) 6846 b += 31; 6847 else 6848 b += 32; 6849 b = b >> 6; 6850 b = MIN(MAX(b, -31), 31); 6851 6852 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6853 tmpu16 |= ((uint32_t)b & 0x0000003f); 6854 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6855 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6856 return; 6857 } 6858 6859 tmp16 = bwn_nrssi_read(mac, 0x20); 6860 if (tmp16 >= 0x20) 6861 tmp16 -= 0x40; 6862 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6863} 6864 6865static void 6866bwn_nrssi_slope_11g(struct bwn_mac *mac) 6867{ 6868#define SAVE_RF_MAX 3 6869#define SAVE_PHY_COMM_MAX 4 6870#define SAVE_PHY3_MAX 8 6871 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6872 { 0x7a, 0x52, 0x43 }; 6873 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6874 { 0x15, 0x5a, 0x59, 0x58 }; 6875 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6876 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6877 0x0801, 0x0060, 0x0014, 0x0478 6878 }; 6879 struct bwn_phy *phy = &mac->mac_phy; 6880 struct bwn_phy_g *pg = &phy->phy_g; 6881 int32_t i, tmp32, phy3_idx = 0; 6882 uint16_t delta, tmp; 6883 uint16_t save_rf[SAVE_RF_MAX]; 6884 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6885 uint16_t save_phy3[SAVE_PHY3_MAX]; 6886 uint16_t ant_div, phy0, chan_ex; 6887 int16_t nrssi0, nrssi1; 6888 6889 KASSERT(phy->type == BWN_PHYTYPE_G, 6890 ("%s:%d: fail", __func__, __LINE__)); 6891 6892 if (phy->rf_rev >= 9) 6893 return; 6894 if (phy->rf_rev == 8) 6895 bwn_nrssi_offset(mac); 6896 6897 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6898 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6899 6900 /* 6901 * Save RF/PHY registers for later restoration 6902 */ 6903 ant_div = BWN_READ_2(mac, 0x03e2); 6904 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6905 for (i = 0; i < SAVE_RF_MAX; ++i) 6906 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6907 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6908 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6909 6910 phy0 = BWN_READ_2(mac, BWN_PHY0); 6911 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6912 if (phy->rev >= 3) { 6913 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6914 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6915 BWN_PHY_WRITE(mac, 0x002e, 0); 6916 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6917 switch (phy->rev) { 6918 case 4: 6919 case 6: 6920 case 7: 6921 BWN_PHY_SET(mac, 0x0478, 0x0100); 6922 BWN_PHY_SET(mac, 0x0801, 0x0040); 6923 break; 6924 case 3: 6925 case 5: 6926 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6927 break; 6928 } 6929 BWN_PHY_SET(mac, 0x0060, 0x0040); 6930 BWN_PHY_SET(mac, 0x0014, 0x0200); 6931 } 6932 /* 6933 * Calculate nrssi0 6934 */ 6935 BWN_RF_SET(mac, 0x007a, 0x0070); 6936 bwn_set_all_gains(mac, 0, 8, 0); 6937 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6938 if (phy->rev >= 2) { 6939 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6940 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6941 } 6942 BWN_RF_SET(mac, 0x007a, 0x0080); 6943 DELAY(20); 6944 6945 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6946 if (nrssi0 >= 0x0020) 6947 nrssi0 -= 0x0040; 6948 6949 /* 6950 * Calculate nrssi1 6951 */ 6952 BWN_RF_MASK(mac, 0x007a, 0x007f); 6953 if (phy->rev >= 2) 6954 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6955 6956 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6957 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6958 BWN_RF_SET(mac, 0x007a, 0x000f); 6959 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6960 if (phy->rev >= 2) { 6961 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6962 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6963 } 6964 6965 bwn_set_all_gains(mac, 3, 0, 1); 6966 if (phy->rf_rev == 8) { 6967 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6968 } else { 6969 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6970 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6971 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6972 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6973 } 6974 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6975 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6976 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6977 DELAY(20); 6978 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6979 6980 /* 6981 * Install calculated narrow RSSI values 6982 */ 6983 if (nrssi1 >= 0x0020) 6984 nrssi1 -= 0x0040; 6985 if (nrssi0 == nrssi1) 6986 pg->pg_nrssi_slope = 0x00010000; 6987 else 6988 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6989 if (nrssi0 >= -4) { 6990 pg->pg_nrssi[0] = nrssi1; 6991 pg->pg_nrssi[1] = nrssi0; 6992 } 6993 6994 /* 6995 * Restore saved RF/PHY registers 6996 */ 6997 if (phy->rev >= 3) { 6998 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6999 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7000 save_phy3[phy3_idx]); 7001 } 7002 } 7003 if (phy->rev >= 2) { 7004 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 7005 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 7006 } 7007 7008 for (i = 0; i < SAVE_RF_MAX; ++i) 7009 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7010 7011 BWN_WRITE_2(mac, 0x03e2, ant_div); 7012 BWN_WRITE_2(mac, 0x03e6, phy0); 7013 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 7014 7015 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7016 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7017 7018 bwn_spu_workaround(mac, phy->chan); 7019 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 7020 bwn_set_original_gains(mac); 7021 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 7022 if (phy->rev >= 3) { 7023 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 7024 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7025 save_phy3[phy3_idx]); 7026 } 7027 } 7028 7029 delta = 0x1f - pg->pg_nrssi[0]; 7030 for (i = 0; i < 64; i++) { 7031 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 7032 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 7033 pg->pg_nrssi_lt[i] = tmp32; 7034 } 7035 7036 bwn_nrssi_threshold(mac); 7037#undef SAVE_RF_MAX 7038#undef SAVE_PHY_COMM_MAX 7039#undef SAVE_PHY3_MAX 7040} 7041 7042static void 7043bwn_nrssi_offset(struct bwn_mac *mac) 7044{ 7045#define SAVE_RF_MAX 2 7046#define SAVE_PHY_COMM_MAX 10 7047#define SAVE_PHY6_MAX 8 7048 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 7049 { 0x7a, 0x43 }; 7050 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 7051 0x0001, 0x0811, 0x0812, 0x0814, 7052 0x0815, 0x005a, 0x0059, 0x0058, 7053 0x000a, 0x0003 7054 }; 7055 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 7056 0x002e, 0x002f, 0x080f, 0x0810, 7057 0x0801, 0x0060, 0x0014, 0x0478 7058 }; 7059 struct bwn_phy *phy = &mac->mac_phy; 7060 int i, phy6_idx = 0; 7061 uint16_t save_rf[SAVE_RF_MAX]; 7062 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 7063 uint16_t save_phy6[SAVE_PHY6_MAX]; 7064 int16_t nrssi; 7065 uint16_t saved = 0xffff; 7066 7067 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7068 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 7069 for (i = 0; i < SAVE_RF_MAX; ++i) 7070 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 7071 7072 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 7073 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 7074 BWN_PHY_SET(mac, 0x0811, 0x000c); 7075 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 7076 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 7077 if (phy->rev >= 6) { 7078 for (i = 0; i < SAVE_PHY6_MAX; ++i) 7079 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 7080 7081 BWN_PHY_WRITE(mac, 0x002e, 0); 7082 BWN_PHY_WRITE(mac, 0x002f, 0); 7083 BWN_PHY_WRITE(mac, 0x080f, 0); 7084 BWN_PHY_WRITE(mac, 0x0810, 0); 7085 BWN_PHY_SET(mac, 0x0478, 0x0100); 7086 BWN_PHY_SET(mac, 0x0801, 0x0040); 7087 BWN_PHY_SET(mac, 0x0060, 0x0040); 7088 BWN_PHY_SET(mac, 0x0014, 0x0200); 7089 } 7090 BWN_RF_SET(mac, 0x007a, 0x0070); 7091 BWN_RF_SET(mac, 0x007a, 0x0080); 7092 DELAY(30); 7093 7094 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7095 if (nrssi >= 0x20) 7096 nrssi -= 0x40; 7097 if (nrssi == 31) { 7098 for (i = 7; i >= 4; i--) { 7099 BWN_RF_WRITE(mac, 0x007b, i); 7100 DELAY(20); 7101 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7102 0x003f); 7103 if (nrssi >= 0x20) 7104 nrssi -= 0x40; 7105 if (nrssi < 31 && saved == 0xffff) 7106 saved = i; 7107 } 7108 if (saved == 0xffff) 7109 saved = 4; 7110 } else { 7111 BWN_RF_MASK(mac, 0x007a, 0x007f); 7112 if (phy->rev != 1) { 7113 BWN_PHY_SET(mac, 0x0814, 0x0001); 7114 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7115 } 7116 BWN_PHY_SET(mac, 0x0811, 0x000c); 7117 BWN_PHY_SET(mac, 0x0812, 0x000c); 7118 BWN_PHY_SET(mac, 0x0811, 0x0030); 7119 BWN_PHY_SET(mac, 0x0812, 0x0030); 7120 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7121 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7122 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7123 if (phy->rev == 0) 7124 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7125 else 7126 BWN_PHY_SET(mac, 0x000a, 0x2000); 7127 if (phy->rev != 1) { 7128 BWN_PHY_SET(mac, 0x0814, 0x0004); 7129 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7130 } 7131 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7132 BWN_RF_SET(mac, 0x007a, 0x000f); 7133 bwn_set_all_gains(mac, 3, 0, 1); 7134 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7135 DELAY(30); 7136 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7137 if (nrssi >= 0x20) 7138 nrssi -= 0x40; 7139 if (nrssi == -32) { 7140 for (i = 0; i < 4; i++) { 7141 BWN_RF_WRITE(mac, 0x007b, i); 7142 DELAY(20); 7143 nrssi = (int16_t)((BWN_PHY_READ(mac, 7144 0x047f) >> 8) & 0x003f); 7145 if (nrssi >= 0x20) 7146 nrssi -= 0x40; 7147 if (nrssi > -31 && saved == 0xffff) 7148 saved = i; 7149 } 7150 if (saved == 0xffff) 7151 saved = 3; 7152 } else 7153 saved = 0; 7154 } 7155 BWN_RF_WRITE(mac, 0x007b, saved); 7156 7157 /* 7158 * Restore saved RF/PHY registers 7159 */ 7160 if (phy->rev >= 6) { 7161 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7162 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7163 save_phy6[phy6_idx]); 7164 } 7165 } 7166 if (phy->rev != 1) { 7167 for (i = 3; i < 5; i++) 7168 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7169 save_phy_comm[i]); 7170 } 7171 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7172 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7173 7174 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7175 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7176 7177 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7178 BWN_PHY_SET(mac, 0x0429, 0x8000); 7179 bwn_set_original_gains(mac); 7180 if (phy->rev >= 6) { 7181 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7182 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7183 save_phy6[phy6_idx]); 7184 } 7185 } 7186 7187 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7188 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7189 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7190} 7191 7192static void 7193bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7194 int16_t third) 7195{ 7196 struct bwn_phy *phy = &mac->mac_phy; 7197 uint16_t i; 7198 uint16_t start = 0x08, end = 0x18; 7199 uint16_t tmp; 7200 uint16_t table; 7201 7202 if (phy->rev <= 1) { 7203 start = 0x10; 7204 end = 0x20; 7205 } 7206 7207 table = BWN_OFDMTAB_GAINX; 7208 if (phy->rev <= 1) 7209 table = BWN_OFDMTAB_GAINX_R1; 7210 for (i = 0; i < 4; i++) 7211 bwn_ofdmtab_write_2(mac, table, i, first); 7212 7213 for (i = start; i < end; i++) 7214 bwn_ofdmtab_write_2(mac, table, i, second); 7215 7216 if (third != -1) { 7217 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7218 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7219 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7220 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7221 } 7222 bwn_dummy_transmission(mac, 0, 1); 7223} 7224 7225static void 7226bwn_set_original_gains(struct bwn_mac *mac) 7227{ 7228 struct bwn_phy *phy = &mac->mac_phy; 7229 uint16_t i, tmp; 7230 uint16_t table; 7231 uint16_t start = 0x0008, end = 0x0018; 7232 7233 if (phy->rev <= 1) { 7234 start = 0x0010; 7235 end = 0x0020; 7236 } 7237 7238 table = BWN_OFDMTAB_GAINX; 7239 if (phy->rev <= 1) 7240 table = BWN_OFDMTAB_GAINX_R1; 7241 for (i = 0; i < 4; i++) { 7242 tmp = (i & 0xfffc); 7243 tmp |= (i & 0x0001) << 1; 7244 tmp |= (i & 0x0002) >> 1; 7245 7246 bwn_ofdmtab_write_2(mac, table, i, tmp); 7247 } 7248 7249 for (i = start; i < end; i++) 7250 bwn_ofdmtab_write_2(mac, table, i, i - start); 7251 7252 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7253 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7254 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7255 bwn_dummy_transmission(mac, 0, 1); 7256} 7257 7258static void 7259bwn_phy_hwpctl_init(struct bwn_mac *mac) 7260{ 7261 struct siba_softc *bus = mac->mac_sd->sd_bus; 7262 struct bwn_phy *phy = &mac->mac_phy; 7263 struct bwn_phy_g *pg = &phy->phy_g; 7264 struct bwn_rfatt old_rfatt, rfatt; 7265 struct bwn_bbatt old_bbatt, bbatt; 7266 uint8_t old_txctl = 0; 7267 7268 KASSERT(phy->type == BWN_PHYTYPE_G, 7269 ("%s:%d: fail", __func__, __LINE__)); 7270 7271 if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) && 7272 (bus->siba_board_type == SIBA_BOARD_BU4306)) 7273 return; 7274 7275 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7276 7277 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7278 7279 if (!phy->gmode) 7280 return; 7281 bwn_hwpctl_early_init(mac); 7282 if (pg->pg_curtssi == 0) { 7283 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7284 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7285 } else { 7286 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7287 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7288 old_txctl = pg->pg_txctl; 7289 7290 bbatt.att = 11; 7291 if (phy->rf_rev == 8) { 7292 rfatt.att = 15; 7293 rfatt.padmix = 1; 7294 } else { 7295 rfatt.att = 9; 7296 rfatt.padmix = 0; 7297 } 7298 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7299 } 7300 bwn_dummy_transmission(mac, 0, 1); 7301 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7302 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7303 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7304 else 7305 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7306 &old_rfatt, old_txctl); 7307 } 7308 bwn_hwpctl_init_gphy(mac); 7309 7310 /* clear TSSI */ 7311 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7312 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7313 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7314 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7315} 7316 7317static void 7318bwn_hwpctl_early_init(struct bwn_mac *mac) 7319{ 7320 struct bwn_phy *phy = &mac->mac_phy; 7321 7322 if (!bwn_has_hwpctl(mac)) { 7323 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7324 return; 7325 } 7326 7327 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7328 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7329 BWN_PHY_SET(mac, 0x047c, 0x0002); 7330 BWN_PHY_SET(mac, 0x047a, 0xf000); 7331 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7332 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7333 BWN_PHY_SET(mac, 0x005d, 0x8000); 7334 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7335 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7336 BWN_PHY_SET(mac, 0x0036, 0x0400); 7337 } else { 7338 BWN_PHY_SET(mac, 0x0036, 0x0200); 7339 BWN_PHY_SET(mac, 0x0036, 0x0400); 7340 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7341 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7342 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7343 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7344 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7345 } 7346} 7347 7348static void 7349bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7350{ 7351 struct bwn_phy *phy = &mac->mac_phy; 7352 struct bwn_phy_g *pg = &phy->phy_g; 7353 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7354 int i; 7355 uint16_t nr_written = 0, tmp, value; 7356 uint8_t rf, bb; 7357 7358 if (!bwn_has_hwpctl(mac)) { 7359 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7360 return; 7361 } 7362 7363 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7364 (pg->pg_idletssi - pg->pg_curtssi)); 7365 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7366 (pg->pg_idletssi - pg->pg_curtssi)); 7367 7368 for (i = 0; i < 32; i++) 7369 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7370 for (i = 32; i < 64; i++) 7371 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7372 for (i = 0; i < 64; i += 2) { 7373 value = (uint16_t) pg->pg_tssi2dbm[i]; 7374 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7375 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7376 } 7377 7378 for (rf = 0; rf < lo->rfatt.len; rf++) { 7379 for (bb = 0; bb < lo->bbatt.len; bb++) { 7380 if (nr_written >= 0x40) 7381 return; 7382 tmp = lo->bbatt.array[bb].att; 7383 tmp <<= 8; 7384 if (phy->rf_rev == 8) 7385 tmp |= 0x50; 7386 else 7387 tmp |= 0x40; 7388 tmp |= lo->rfatt.array[rf].att; 7389 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7390 nr_written++; 7391 } 7392 } 7393 7394 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7395 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7396 7397 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7398 BWN_PHY_SET(mac, 0x0478, 0x0800); 7399 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7400 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7401 7402 bwn_phy_g_dc_lookup_init(mac, 1); 7403 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7404} 7405 7406static void 7407bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7408{ 7409 struct siba_softc *siba = mac->mac_sd->sd_bus; 7410 7411 if (spu != 0) 7412 bwn_spu_workaround(mac, channel); 7413 7414 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7415 7416 if (channel == 14) { 7417 if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN) 7418 bwn_hf_write(mac, 7419 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7420 else 7421 bwn_hf_write(mac, 7422 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7423 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7424 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7425 return; 7426 } 7427 7428 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7429 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7430} 7431 7432static uint16_t 7433bwn_phy_g_chan2freq(uint8_t channel) 7434{ 7435 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7436 7437 KASSERT(channel >= 1 && channel <= 14, 7438 ("%s:%d: fail", __func__, __LINE__)); 7439 7440 return (bwn_phy_g_rf_channels[channel - 1]); 7441} 7442 7443static void 7444bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7445 const struct bwn_rfatt *rfatt, uint8_t txctl) 7446{ 7447 struct bwn_phy *phy = &mac->mac_phy; 7448 struct bwn_phy_g *pg = &phy->phy_g; 7449 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7450 uint16_t bb, rf; 7451 uint16_t tx_bias, tx_magn; 7452 7453 bb = bbatt->att; 7454 rf = rfatt->att; 7455 tx_bias = lo->tx_bias; 7456 tx_magn = lo->tx_magn; 7457 if (tx_bias == 0xff) 7458 tx_bias = 0; 7459 7460 pg->pg_txctl = txctl; 7461 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7462 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7463 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7464 bwn_phy_g_set_bbatt(mac, bb); 7465 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7466 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7467 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7468 else { 7469 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7470 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7471 } 7472 if (BWN_HAS_TXMAG(phy)) 7473 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7474 else 7475 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7476 bwn_lo_g_adjust(mac); 7477} 7478 7479static void 7480bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7481 uint16_t bbatt) 7482{ 7483 struct bwn_phy *phy = &mac->mac_phy; 7484 7485 if (phy->analog == 0) { 7486 BWN_WRITE_2(mac, BWN_PHY0, 7487 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7488 return; 7489 } 7490 if (phy->analog > 1) { 7491 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7492 return; 7493 } 7494 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7495} 7496 7497static uint16_t 7498bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7499{ 7500 struct bwn_phy *phy = &mac->mac_phy; 7501 struct bwn_phy_g *pg = &phy->phy_g; 7502 struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom); 7503 int max_lb_gain; 7504 uint16_t extlna; 7505 uint16_t i; 7506 7507 if (phy->gmode == 0) 7508 return (0); 7509 7510 if (BWN_HAS_LOOPBACK(phy)) { 7511 max_lb_gain = pg->pg_max_lb_gain; 7512 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7513 if (max_lb_gain >= 0x46) { 7514 extlna = 0x3000; 7515 max_lb_gain -= 0x46; 7516 } else if (max_lb_gain >= 0x3a) { 7517 extlna = 0x1000; 7518 max_lb_gain -= 0x3a; 7519 } else if (max_lb_gain >= 0x2e) { 7520 extlna = 0x2000; 7521 max_lb_gain -= 0x2e; 7522 } else { 7523 extlna = 0; 7524 max_lb_gain -= 0x10; 7525 } 7526 7527 for (i = 0; i < 16; i++) { 7528 max_lb_gain -= (i * 6); 7529 if (max_lb_gain < 6) 7530 break; 7531 } 7532 7533 if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7534 if (reg == BWN_PHY_RFOVER) { 7535 return (0x1b3); 7536 } else if (reg == BWN_PHY_RFOVERVAL) { 7537 extlna |= (i << 8); 7538 switch (lpd) { 7539 case BWN_LPD(0, 1, 1): 7540 return (0x0f92); 7541 case BWN_LPD(0, 0, 1): 7542 case BWN_LPD(1, 0, 1): 7543 return (0x0092 | extlna); 7544 case BWN_LPD(1, 0, 0): 7545 return (0x0093 | extlna); 7546 } 7547 KASSERT(0 == 1, 7548 ("%s:%d: fail", __func__, __LINE__)); 7549 } 7550 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7551 } else { 7552 if (reg == BWN_PHY_RFOVER) 7553 return (0x9b3); 7554 if (reg == BWN_PHY_RFOVERVAL) { 7555 if (extlna) 7556 extlna |= 0x8000; 7557 extlna |= (i << 8); 7558 switch (lpd) { 7559 case BWN_LPD(0, 1, 1): 7560 return (0x8f92); 7561 case BWN_LPD(0, 0, 1): 7562 return (0x8092 | extlna); 7563 case BWN_LPD(1, 0, 1): 7564 return (0x2092 | extlna); 7565 case BWN_LPD(1, 0, 0): 7566 return (0x2093 | extlna); 7567 } 7568 KASSERT(0 == 1, 7569 ("%s:%d: fail", __func__, __LINE__)); 7570 } 7571 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7572 } 7573 return (0); 7574 } 7575 7576 if ((phy->rev < 7) || 7577 !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7578 if (reg == BWN_PHY_RFOVER) { 7579 return (0x1b3); 7580 } else if (reg == BWN_PHY_RFOVERVAL) { 7581 switch (lpd) { 7582 case BWN_LPD(0, 1, 1): 7583 return (0x0fb2); 7584 case BWN_LPD(0, 0, 1): 7585 return (0x00b2); 7586 case BWN_LPD(1, 0, 1): 7587 return (0x30b2); 7588 case BWN_LPD(1, 0, 0): 7589 return (0x30b3); 7590 } 7591 KASSERT(0 == 1, 7592 ("%s:%d: fail", __func__, __LINE__)); 7593 } 7594 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7595 } else { 7596 if (reg == BWN_PHY_RFOVER) { 7597 return (0x9b3); 7598 } else if (reg == BWN_PHY_RFOVERVAL) { 7599 switch (lpd) { 7600 case BWN_LPD(0, 1, 1): 7601 return (0x8fb2); 7602 case BWN_LPD(0, 0, 1): 7603 return (0x80b2); 7604 case BWN_LPD(1, 0, 1): 7605 return (0x20b2); 7606 case BWN_LPD(1, 0, 0): 7607 return (0x20b3); 7608 } 7609 KASSERT(0 == 1, 7610 ("%s:%d: fail", __func__, __LINE__)); 7611 } 7612 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7613 } 7614 return (0); 7615} 7616 7617static void 7618bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7619{ 7620 7621 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7622 return; 7623 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7624 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7625 DELAY(1000); 7626 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7627} 7628 7629static int 7630bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7631{ 7632 struct bwn_softc *sc = mac->mac_sc; 7633 struct bwn_fw *fw = &mac->mac_fw; 7634 const uint8_t rev = mac->mac_sd->sd_id.sd_rev; 7635 const char *filename; 7636 uint32_t high; 7637 int error; 7638 7639 /* microcode */ 7640 if (rev >= 5 && rev <= 10) 7641 filename = "ucode5"; 7642 else if (rev >= 11 && rev <= 12) 7643 filename = "ucode11"; 7644 else if (rev == 13) 7645 filename = "ucode13"; 7646 else if (rev == 14) 7647 filename = "ucode14"; 7648 else if (rev >= 15) 7649 filename = "ucode15"; 7650 else { 7651 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7652 bwn_release_firmware(mac); 7653 return (EOPNOTSUPP); 7654 } 7655 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7656 if (error) { 7657 bwn_release_firmware(mac); 7658 return (error); 7659 } 7660 7661 /* PCM */ 7662 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7663 if (rev >= 5 && rev <= 10) { 7664 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7665 if (error == ENOENT) 7666 fw->no_pcmfile = 1; 7667 else if (error) { 7668 bwn_release_firmware(mac); 7669 return (error); 7670 } 7671 } else if (rev < 11) { 7672 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7673 return (EOPNOTSUPP); 7674 } 7675 7676 /* initvals */ 7677 high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH); 7678 switch (mac->mac_phy.type) { 7679 case BWN_PHYTYPE_A: 7680 if (rev < 5 || rev > 10) 7681 goto fail1; 7682 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7683 filename = "a0g1initvals5"; 7684 else 7685 filename = "a0g0initvals5"; 7686 break; 7687 case BWN_PHYTYPE_G: 7688 if (rev >= 5 && rev <= 10) 7689 filename = "b0g0initvals5"; 7690 else if (rev >= 13) 7691 filename = "b0g0initvals13"; 7692 else 7693 goto fail1; 7694 break; 7695 case BWN_PHYTYPE_LP: 7696 if (rev == 13) 7697 filename = "lp0initvals13"; 7698 else if (rev == 14) 7699 filename = "lp0initvals14"; 7700 else if (rev >= 15) 7701 filename = "lp0initvals15"; 7702 else 7703 goto fail1; 7704 break; 7705 case BWN_PHYTYPE_N: 7706 if (rev >= 11 && rev <= 12) 7707 filename = "n0initvals11"; 7708 else 7709 goto fail1; 7710 break; 7711 default: 7712 goto fail1; 7713 } 7714 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7715 if (error) { 7716 bwn_release_firmware(mac); 7717 return (error); 7718 } 7719 7720 /* bandswitch initvals */ 7721 switch (mac->mac_phy.type) { 7722 case BWN_PHYTYPE_A: 7723 if (rev >= 5 && rev <= 10) { 7724 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7725 filename = "a0g1bsinitvals5"; 7726 else 7727 filename = "a0g0bsinitvals5"; 7728 } else if (rev >= 11) 7729 filename = NULL; 7730 else 7731 goto fail1; 7732 break; 7733 case BWN_PHYTYPE_G: 7734 if (rev >= 5 && rev <= 10) 7735 filename = "b0g0bsinitvals5"; 7736 else if (rev >= 11) 7737 filename = NULL; 7738 else 7739 goto fail1; 7740 break; 7741 case BWN_PHYTYPE_LP: 7742 if (rev == 13) 7743 filename = "lp0bsinitvals13"; 7744 else if (rev == 14) 7745 filename = "lp0bsinitvals14"; 7746 else if (rev >= 15) 7747 filename = "lp0bsinitvals15"; 7748 else 7749 goto fail1; 7750 break; 7751 case BWN_PHYTYPE_N: 7752 if (rev >= 11 && rev <= 12) 7753 filename = "n0bsinitvals11"; 7754 else 7755 goto fail1; 7756 break; 7757 default: 7758 goto fail1; 7759 } 7760 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7761 if (error) { 7762 bwn_release_firmware(mac); 7763 return (error); 7764 } 7765 return (0); 7766fail1: 7767 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7768 bwn_release_firmware(mac); 7769 return (EOPNOTSUPP); 7770} 7771 7772static int 7773bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7774 const char *name, struct bwn_fwfile *bfw) 7775{ 7776 const struct bwn_fwhdr *hdr; 7777 struct bwn_softc *sc = mac->mac_sc; 7778 const struct firmware *fw; 7779 char namebuf[64]; 7780 7781 if (name == NULL) { 7782 bwn_do_release_fw(bfw); 7783 return (0); 7784 } 7785 if (bfw->filename != NULL) { 7786 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7787 return (0); 7788 bwn_do_release_fw(bfw); 7789 } 7790 7791 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s", 7792 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name); 7793 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7794 fw = firmware_get(namebuf); 7795 if (fw == NULL) { 7796 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7797 namebuf); 7798 return (ENOENT); 7799 } 7800 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7801 goto fail; 7802 hdr = (const struct bwn_fwhdr *)(fw->data); 7803 switch (hdr->type) { 7804 case BWN_FWTYPE_UCODE: 7805 case BWN_FWTYPE_PCM: 7806 if (be32toh(hdr->size) != 7807 (fw->datasize - sizeof(struct bwn_fwhdr))) 7808 goto fail; 7809 /* FALLTHROUGH */ 7810 case BWN_FWTYPE_IV: 7811 if (hdr->ver != 1) 7812 goto fail; 7813 break; 7814 default: 7815 goto fail; 7816 } 7817 bfw->filename = name; 7818 bfw->fw = fw; 7819 bfw->type = type; 7820 return (0); 7821fail: 7822 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7823 if (fw != NULL) 7824 firmware_put(fw, FIRMWARE_UNLOAD); 7825 return (EPROTO); 7826} 7827 7828static void 7829bwn_release_firmware(struct bwn_mac *mac) 7830{ 7831 7832 bwn_do_release_fw(&mac->mac_fw.ucode); 7833 bwn_do_release_fw(&mac->mac_fw.pcm); 7834 bwn_do_release_fw(&mac->mac_fw.initvals); 7835 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7836} 7837 7838static void 7839bwn_do_release_fw(struct bwn_fwfile *bfw) 7840{ 7841 7842 if (bfw->fw != NULL) 7843 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7844 bfw->fw = NULL; 7845 bfw->filename = NULL; 7846} 7847 7848static int 7849bwn_fw_loaducode(struct bwn_mac *mac) 7850{ 7851#define GETFWOFFSET(fwp, offset) \ 7852 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7853#define GETFWSIZE(fwp, offset) \ 7854 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7855 struct bwn_softc *sc = mac->mac_sc; 7856 const uint32_t *data; 7857 unsigned int i; 7858 uint32_t ctl; 7859 uint16_t date, fwcaps, time; 7860 int error = 0; 7861 7862 ctl = BWN_READ_4(mac, BWN_MACCTL); 7863 ctl |= BWN_MACCTL_MCODE_JMP0; 7864 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7865 __LINE__)); 7866 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7867 for (i = 0; i < 64; i++) 7868 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7869 for (i = 0; i < 4096; i += 2) 7870 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7871 7872 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7873 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7874 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7875 i++) { 7876 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7877 DELAY(10); 7878 } 7879 7880 if (mac->mac_fw.pcm.fw) { 7881 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7882 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7883 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7884 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7885 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7886 sizeof(struct bwn_fwhdr)); i++) { 7887 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7888 DELAY(10); 7889 } 7890 } 7891 7892 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7893 BWN_WRITE_4(mac, BWN_MACCTL, 7894 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7895 BWN_MACCTL_MCODE_RUN); 7896 7897 for (i = 0; i < 21; i++) { 7898 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7899 break; 7900 if (i >= 20) { 7901 device_printf(sc->sc_dev, "ucode timeout\n"); 7902 error = ENXIO; 7903 goto error; 7904 } 7905 DELAY(50000); 7906 } 7907 BWN_READ_4(mac, BWN_INTR_REASON); 7908 7909 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7910 if (mac->mac_fw.rev <= 0x128) { 7911 device_printf(sc->sc_dev, "the firmware is too old\n"); 7912 error = EOPNOTSUPP; 7913 goto error; 7914 } 7915 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7916 BWN_SHARED_UCODE_PATCH); 7917 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7918 mac->mac_fw.opensource = (date == 0xffff); 7919 if (bwn_wme != 0) 7920 mac->mac_flags |= BWN_MAC_FLAG_WME; 7921 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7922 7923 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7924 if (mac->mac_fw.opensource == 0) { 7925 device_printf(sc->sc_dev, 7926 "firmware version (rev %u patch %u date %#x time %#x)\n", 7927 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7928 if (mac->mac_fw.no_pcmfile) 7929 device_printf(sc->sc_dev, 7930 "no HW crypto acceleration due to pcm5\n"); 7931 } else { 7932 mac->mac_fw.patch = time; 7933 fwcaps = bwn_fwcaps_read(mac); 7934 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7935 device_printf(sc->sc_dev, 7936 "disabling HW crypto acceleration\n"); 7937 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7938 } 7939 if (!(fwcaps & BWN_FWCAPS_WME)) { 7940 device_printf(sc->sc_dev, "disabling WME support\n"); 7941 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7942 } 7943 } 7944 7945 if (BWN_ISOLDFMT(mac)) 7946 device_printf(sc->sc_dev, "using old firmware image\n"); 7947 7948 return (0); 7949 7950error: 7951 BWN_WRITE_4(mac, BWN_MACCTL, 7952 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7953 BWN_MACCTL_MCODE_JMP0); 7954 7955 return (error); 7956#undef GETFWSIZE 7957#undef GETFWOFFSET 7958} 7959 7960/* OpenFirmware only */ 7961static uint16_t 7962bwn_fwcaps_read(struct bwn_mac *mac) 7963{ 7964 7965 KASSERT(mac->mac_fw.opensource == 1, 7966 ("%s:%d: fail", __func__, __LINE__)); 7967 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7968} 7969 7970static int 7971bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7972 size_t count, size_t array_size) 7973{ 7974#define GET_NEXTIV16(iv) \ 7975 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7976 sizeof(uint16_t) + sizeof(uint16_t))) 7977#define GET_NEXTIV32(iv) \ 7978 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7979 sizeof(uint16_t) + sizeof(uint32_t))) 7980 struct bwn_softc *sc = mac->mac_sc; 7981 const struct bwn_fwinitvals *iv; 7982 uint16_t offset; 7983 size_t i; 7984 uint8_t bit32; 7985 7986 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7987 ("%s:%d: fail", __func__, __LINE__)); 7988 iv = ivals; 7989 for (i = 0; i < count; i++) { 7990 if (array_size < sizeof(iv->offset_size)) 7991 goto fail; 7992 array_size -= sizeof(iv->offset_size); 7993 offset = be16toh(iv->offset_size); 7994 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7995 offset &= BWN_FWINITVALS_OFFSET_MASK; 7996 if (offset >= 0x1000) 7997 goto fail; 7998 if (bit32) { 7999 if (array_size < sizeof(iv->data.d32)) 8000 goto fail; 8001 array_size -= sizeof(iv->data.d32); 8002 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 8003 iv = GET_NEXTIV32(iv); 8004 } else { 8005 8006 if (array_size < sizeof(iv->data.d16)) 8007 goto fail; 8008 array_size -= sizeof(iv->data.d16); 8009 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 8010 8011 iv = GET_NEXTIV16(iv); 8012 } 8013 } 8014 if (array_size != 0) 8015 goto fail; 8016 return (0); 8017fail: 8018 device_printf(sc->sc_dev, "initvals: invalid format\n"); 8019 return (EPROTO); 8020#undef GET_NEXTIV16 8021#undef GET_NEXTIV32 8022} 8023 8024static int 8025bwn_switch_channel(struct bwn_mac *mac, int chan) 8026{ 8027 struct bwn_phy *phy = &(mac->mac_phy); 8028 struct bwn_softc *sc = mac->mac_sc; 8029 struct ifnet *ifp = sc->sc_ifp; 8030 struct ieee80211com *ic = ifp->if_l2com; 8031 uint16_t channelcookie, savedcookie; 8032 int error; 8033 8034 if (chan == 0xffff) 8035 chan = phy->get_default_chan(mac); 8036 8037 channelcookie = chan; 8038 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 8039 channelcookie |= 0x100; 8040 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 8041 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 8042 error = phy->switch_channel(mac, chan); 8043 if (error) 8044 goto fail; 8045 8046 mac->mac_phy.chan = chan; 8047 DELAY(8000); 8048 return (0); 8049fail: 8050 device_printf(sc->sc_dev, "failed to switch channel\n"); 8051 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 8052 return (error); 8053} 8054 8055static uint16_t 8056bwn_ant2phy(int antenna) 8057{ 8058 8059 switch (antenna) { 8060 case BWN_ANT0: 8061 return (BWN_TX_PHY_ANT0); 8062 case BWN_ANT1: 8063 return (BWN_TX_PHY_ANT1); 8064 case BWN_ANT2: 8065 return (BWN_TX_PHY_ANT2); 8066 case BWN_ANT3: 8067 return (BWN_TX_PHY_ANT3); 8068 case BWN_ANTAUTO: 8069 return (BWN_TX_PHY_ANT01AUTO); 8070 } 8071 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8072 return (0); 8073} 8074 8075static void 8076bwn_wme_load(struct bwn_mac *mac) 8077{ 8078 struct bwn_softc *sc = mac->mac_sc; 8079 int i; 8080 8081 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8082 ("%s:%d: fail", __func__, __LINE__)); 8083 8084 bwn_mac_suspend(mac); 8085 for (i = 0; i < N(sc->sc_wmeParams); i++) 8086 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8087 bwn_wme_shm_offsets[i]); 8088 bwn_mac_enable(mac); 8089} 8090 8091static void 8092bwn_wme_loadparams(struct bwn_mac *mac, 8093 const struct wmeParams *p, uint16_t shm_offset) 8094{ 8095#define SM(_v, _f) (((_v) << _f##_S) & _f) 8096 struct bwn_softc *sc = mac->mac_sc; 8097 uint16_t params[BWN_NR_WMEPARAMS]; 8098 int slot, tmp; 8099 unsigned int i; 8100 8101 slot = BWN_READ_2(mac, BWN_RNG) & 8102 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8103 8104 memset(¶ms, 0, sizeof(params)); 8105 8106 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8107 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8108 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8109 8110 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8111 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8112 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8113 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8114 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8115 params[BWN_WMEPARAM_BSLOTS] = slot; 8116 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8117 8118 for (i = 0; i < N(params); i++) { 8119 if (i == BWN_WMEPARAM_STATUS) { 8120 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8121 shm_offset + (i * 2)); 8122 tmp |= 0x100; 8123 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8124 tmp); 8125 } else { 8126 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8127 params[i]); 8128 } 8129 } 8130} 8131 8132static void 8133bwn_mac_write_bssid(struct bwn_mac *mac) 8134{ 8135 struct bwn_softc *sc = mac->mac_sc; 8136 uint32_t tmp; 8137 int i; 8138 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8139 8140 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8141 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8142 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8143 IEEE80211_ADDR_LEN); 8144 8145 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8146 tmp = (uint32_t) (mac_bssid[i + 0]); 8147 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8148 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8149 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8150 bwn_ram_write(mac, 0x20 + i, tmp); 8151 } 8152} 8153 8154static void 8155bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8156 const uint8_t *macaddr) 8157{ 8158 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8159 uint16_t data; 8160 8161 if (!mac) 8162 macaddr = zero; 8163 8164 offset |= 0x0020; 8165 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8166 8167 data = macaddr[0]; 8168 data |= macaddr[1] << 8; 8169 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8170 data = macaddr[2]; 8171 data |= macaddr[3] << 8; 8172 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8173 data = macaddr[4]; 8174 data |= macaddr[5] << 8; 8175 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8176} 8177 8178static void 8179bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8180 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8181{ 8182 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8183 uint8_t per_sta_keys_start = 8; 8184 8185 if (BWN_SEC_NEWAPI(mac)) 8186 per_sta_keys_start = 4; 8187 8188 KASSERT(index < mac->mac_max_nr_keys, 8189 ("%s:%d: fail", __func__, __LINE__)); 8190 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8191 ("%s:%d: fail", __func__, __LINE__)); 8192 8193 if (index >= per_sta_keys_start) 8194 bwn_key_macwrite(mac, index, NULL); 8195 if (key) 8196 memcpy(buf, key, key_len); 8197 bwn_key_write(mac, index, algorithm, buf); 8198 if (index >= per_sta_keys_start) 8199 bwn_key_macwrite(mac, index, mac_addr); 8200 8201 mac->mac_key[index].algorithm = algorithm; 8202} 8203 8204static void 8205bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8206{ 8207 uint32_t addrtmp[2] = { 0, 0 }; 8208 uint8_t start = 8; 8209 8210 if (BWN_SEC_NEWAPI(mac)) 8211 start = 4; 8212 8213 KASSERT(index >= start, 8214 ("%s:%d: fail", __func__, __LINE__)); 8215 index -= start; 8216 8217 if (addr) { 8218 addrtmp[0] = addr[0]; 8219 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8220 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8221 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8222 addrtmp[1] = addr[4]; 8223 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8224 } 8225 8226 if (mac->mac_sd->sd_id.sd_rev >= 5) { 8227 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8228 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8229 } else { 8230 if (index >= 8) { 8231 bwn_shm_write_4(mac, BWN_SHARED, 8232 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8233 bwn_shm_write_2(mac, BWN_SHARED, 8234 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8235 } 8236 } 8237} 8238 8239static void 8240bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8241 const uint8_t *key) 8242{ 8243 unsigned int i; 8244 uint32_t offset; 8245 uint16_t kidx, value; 8246 8247 kidx = BWN_SEC_KEY2FW(mac, index); 8248 bwn_shm_write_2(mac, BWN_SHARED, 8249 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8250 8251 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8252 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8253 value = key[i]; 8254 value |= (uint16_t)(key[i + 1]) << 8; 8255 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8256 } 8257} 8258 8259static void 8260bwn_phy_exit(struct bwn_mac *mac) 8261{ 8262 8263 mac->mac_phy.rf_onoff(mac, 0); 8264 if (mac->mac_phy.exit != NULL) 8265 mac->mac_phy.exit(mac); 8266} 8267 8268static void 8269bwn_dma_free(struct bwn_mac *mac) 8270{ 8271 struct bwn_dma *dma; 8272 8273 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8274 return; 8275 dma = &mac->mac_method.dma; 8276 8277 bwn_dma_ringfree(&dma->rx); 8278 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8279 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8280 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8281 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8282 bwn_dma_ringfree(&dma->mcast); 8283} 8284 8285static void 8286bwn_core_stop(struct bwn_mac *mac) 8287{ 8288 struct bwn_softc *sc = mac->mac_sc; 8289 8290 BWN_ASSERT_LOCKED(sc); 8291 8292 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8293 return; 8294 8295 callout_stop(&sc->sc_rfswitch_ch); 8296 callout_stop(&sc->sc_task_ch); 8297 callout_stop(&sc->sc_watchdog_ch); 8298 sc->sc_watchdog_timer = 0; 8299 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8300 BWN_READ_4(mac, BWN_INTR_MASK); 8301 bwn_mac_suspend(mac); 8302 8303 mac->mac_status = BWN_MAC_STATUS_INITED; 8304} 8305 8306static int 8307bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8308{ 8309 struct bwn_mac *up_dev = NULL; 8310 struct bwn_mac *down_dev; 8311 struct bwn_mac *mac; 8312 int err, status; 8313 uint8_t gmode; 8314 8315 BWN_ASSERT_LOCKED(sc); 8316 8317 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8318 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8319 mac->mac_phy.supports_2ghz) { 8320 up_dev = mac; 8321 gmode = 1; 8322 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8323 mac->mac_phy.supports_5ghz) { 8324 up_dev = mac; 8325 gmode = 0; 8326 } else { 8327 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8328 return (EINVAL); 8329 } 8330 if (up_dev != NULL) 8331 break; 8332 } 8333 if (up_dev == NULL) { 8334 device_printf(sc->sc_dev, "Could not find a device\n"); 8335 return (ENODEV); 8336 } 8337 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8338 return (0); 8339 8340 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8341 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8342 8343 down_dev = sc->sc_curmac;; 8344 status = down_dev->mac_status; 8345 if (status >= BWN_MAC_STATUS_STARTED) 8346 bwn_core_stop(down_dev); 8347 if (status >= BWN_MAC_STATUS_INITED) 8348 bwn_core_exit(down_dev); 8349 8350 if (down_dev != up_dev) 8351 bwn_phy_reset(down_dev); 8352 8353 up_dev->mac_phy.gmode = gmode; 8354 if (status >= BWN_MAC_STATUS_INITED) { 8355 err = bwn_core_init(up_dev); 8356 if (err) { 8357 device_printf(sc->sc_dev, 8358 "fatal: failed to initialize for %s-GHz\n", 8359 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8360 goto fail; 8361 } 8362 } 8363 if (status >= BWN_MAC_STATUS_STARTED) 8364 bwn_core_start(up_dev); 8365 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8366 sc->sc_curmac = up_dev; 8367 8368 return (0); 8369fail: 8370 sc->sc_curmac = NULL; 8371 return (err); 8372} 8373 8374static void 8375bwn_rf_turnon(struct bwn_mac *mac) 8376{ 8377 8378 bwn_mac_suspend(mac); 8379 mac->mac_phy.rf_onoff(mac, 1); 8380 mac->mac_phy.rf_on = 1; 8381 bwn_mac_enable(mac); 8382} 8383 8384static void 8385bwn_rf_turnoff(struct bwn_mac *mac) 8386{ 8387 8388 bwn_mac_suspend(mac); 8389 mac->mac_phy.rf_onoff(mac, 0); 8390 mac->mac_phy.rf_on = 0; 8391 bwn_mac_enable(mac); 8392} 8393 8394static void 8395bwn_phy_reset(struct bwn_mac *mac) 8396{ 8397 struct siba_dev_softc *sd = mac->mac_sd; 8398 8399 siba_write_4(sd, SIBA_TGSLOW, 8400 ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8401 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8402 DELAY(1000); 8403 siba_write_4(sd, SIBA_TGSLOW, 8404 (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8405 BWN_TGSLOW_PHYRESET); 8406 DELAY(1000); 8407} 8408 8409static int 8410bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8411{ 8412 struct bwn_vap *bvp = BWN_VAP(vap); 8413 struct ieee80211com *ic= vap->iv_ic; 8414 struct ifnet *ifp = ic->ic_ifp; 8415 enum ieee80211_state ostate = vap->iv_state; 8416 struct bwn_softc *sc = ifp->if_softc; 8417 struct bwn_mac *mac = sc->sc_curmac; 8418 int error; 8419 8420 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8421 ieee80211_state_name[vap->iv_state], 8422 ieee80211_state_name[nstate]); 8423 8424 error = bvp->bv_newstate(vap, nstate, arg); 8425 if (error != 0) 8426 return (error); 8427 8428 BWN_LOCK(sc); 8429 8430 bwn_led_newstate(mac, nstate); 8431 8432 /* 8433 * Clear the BSSID when we stop a STA 8434 */ 8435 if (vap->iv_opmode == IEEE80211_M_STA) { 8436 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8437 /* 8438 * Clear out the BSSID. If we reassociate to 8439 * the same AP, this will reinialize things 8440 * correctly... 8441 */ 8442 if (ic->ic_opmode == IEEE80211_M_STA && 8443 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8444 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8445 bwn_set_macaddr(mac); 8446 } 8447 } 8448 } 8449 8450 if (vap->iv_opmode == IEEE80211_M_MONITOR) { 8451 /* XXX nothing to do? */ 8452 } else if (nstate == IEEE80211_S_RUN) { 8453 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8454 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8455 bwn_set_opmode(mac); 8456 bwn_set_pretbtt(mac); 8457 bwn_spu_setdelay(mac, 0); 8458 bwn_set_macaddr(mac); 8459 } 8460 8461 BWN_UNLOCK(sc); 8462 8463 return (error); 8464} 8465 8466static void 8467bwn_set_pretbtt(struct bwn_mac *mac) 8468{ 8469 struct bwn_softc *sc = mac->mac_sc; 8470 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8471 uint16_t pretbtt; 8472 8473 if (ic->ic_opmode == IEEE80211_M_IBSS) 8474 pretbtt = 2; 8475 else 8476 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8477 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8478 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8479} 8480 8481static int 8482bwn_intr(void *arg) 8483{ 8484 struct bwn_mac *mac = arg; 8485 struct bwn_softc *sc = mac->mac_sc; 8486 struct siba_softc *siba = mac->mac_sd->sd_bus; 8487 uint32_t reason; 8488 8489 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) 8490 return (FILTER_STRAY); 8491 8492 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8493 if (reason == 0xffffffff) /* shared IRQ */ 8494 return (FILTER_STRAY); 8495 reason &= mac->mac_intr_mask; 8496 if (reason == 0) 8497 return (FILTER_HANDLED); 8498 8499 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8500 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8501 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8502 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8503 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8504 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8505 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8506 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8507 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8508 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8509 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8510 8511 /* Disable interrupts. */ 8512 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8513 8514 mac->mac_reason_intr = reason; 8515 8516 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8517 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8518 8519 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8520 return (FILTER_HANDLED); 8521} 8522 8523static void 8524bwn_intrtask(void *arg, int npending) 8525{ 8526 struct bwn_mac *mac = arg; 8527 struct bwn_softc *sc = mac->mac_sc; 8528 struct ifnet *ifp = sc->sc_ifp; 8529 struct siba_softc *siba = mac->mac_sd->sd_bus; 8530 uint32_t merged = 0; 8531 int i, tx = 0, rx = 0; 8532 8533 BWN_LOCK(sc); 8534 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) { 8535 BWN_UNLOCK(sc); 8536 return; 8537 } 8538 8539 for (i = 0; i < N(mac->mac_reason); i++) 8540 merged |= mac->mac_reason[i]; 8541 8542 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8543 device_printf(sc->sc_dev, "MAC trans error\n"); 8544 8545 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8546 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8547 mac->mac_phy.txerrors--; 8548 if (mac->mac_phy.txerrors == 0) { 8549 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8550 bwn_restart(mac, "PHY TX errors"); 8551 } 8552 } 8553 8554 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8555 if (merged & BWN_DMAINTR_FATALMASK) { 8556 device_printf(sc->sc_dev, 8557 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8558 mac->mac_reason[0], mac->mac_reason[1], 8559 mac->mac_reason[2], mac->mac_reason[3], 8560 mac->mac_reason[4], mac->mac_reason[5]); 8561 bwn_restart(mac, "DMA error"); 8562 BWN_UNLOCK(sc); 8563 return; 8564 } 8565 if (merged & BWN_DMAINTR_NONFATALMASK) { 8566 device_printf(sc->sc_dev, 8567 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8568 mac->mac_reason[0], mac->mac_reason[1], 8569 mac->mac_reason[2], mac->mac_reason[3], 8570 mac->mac_reason[4], mac->mac_reason[5]); 8571 } 8572 } 8573 8574 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8575 bwn_intr_ucode_debug(mac); 8576 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8577 bwn_intr_tbtt_indication(mac); 8578 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8579 bwn_intr_atim_end(mac); 8580 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8581 bwn_intr_beacon(mac); 8582 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8583 bwn_intr_pmq(mac); 8584 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8585 bwn_intr_noise(mac); 8586 8587 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8588 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8589 bwn_dma_rx(mac->mac_method.dma.rx); 8590 rx = 1; 8591 } 8592 } else 8593 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8594 8595 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8596 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8597 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8598 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8599 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8600 8601 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8602 bwn_intr_txeof(mac); 8603 tx = 1; 8604 } 8605 8606 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8607 8608 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8609 int evt = BWN_LED_EVENT_NONE; 8610 8611 if (tx && rx) { 8612 if (sc->sc_rx_rate > sc->sc_tx_rate) 8613 evt = BWN_LED_EVENT_RX; 8614 else 8615 evt = BWN_LED_EVENT_TX; 8616 } else if (tx) { 8617 evt = BWN_LED_EVENT_TX; 8618 } else if (rx) { 8619 evt = BWN_LED_EVENT_RX; 8620 } else if (rx == 0) { 8621 evt = BWN_LED_EVENT_POLL; 8622 } 8623 8624 if (evt != BWN_LED_EVENT_NONE) 8625 bwn_led_event(mac, evt); 8626 } 8627 8628 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8629 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8630 bwn_start_locked(ifp); 8631 } 8632 8633 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8634 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8635 8636 BWN_UNLOCK(sc); 8637} 8638 8639static void 8640bwn_restart(struct bwn_mac *mac, const char *msg) 8641{ 8642 struct bwn_softc *sc = mac->mac_sc; 8643 struct ifnet *ifp = sc->sc_ifp; 8644 struct ieee80211com *ic = ifp->if_l2com; 8645 8646 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8647 return; 8648 8649 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8650 ieee80211_runtask(ic, &mac->mac_hwreset); 8651} 8652 8653static void 8654bwn_intr_ucode_debug(struct bwn_mac *mac) 8655{ 8656 struct bwn_softc *sc = mac->mac_sc; 8657 uint16_t reason; 8658 8659 if (mac->mac_fw.opensource == 0) 8660 return; 8661 8662 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8663 switch (reason) { 8664 case BWN_DEBUGINTR_PANIC: 8665 bwn_handle_fwpanic(mac); 8666 break; 8667 case BWN_DEBUGINTR_DUMP_SHM: 8668 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8669 break; 8670 case BWN_DEBUGINTR_DUMP_REGS: 8671 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8672 break; 8673 case BWN_DEBUGINTR_MARKER: 8674 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8675 break; 8676 default: 8677 device_printf(sc->sc_dev, 8678 "ucode debug unknown reason: %#x\n", reason); 8679 } 8680 8681 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8682 BWN_DEBUGINTR_ACK); 8683} 8684 8685static void 8686bwn_intr_tbtt_indication(struct bwn_mac *mac) 8687{ 8688 struct bwn_softc *sc = mac->mac_sc; 8689 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8690 8691 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8692 bwn_psctl(mac, 0); 8693 if (ic->ic_opmode == IEEE80211_M_IBSS) 8694 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8695} 8696 8697static void 8698bwn_intr_atim_end(struct bwn_mac *mac) 8699{ 8700 8701 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8702 BWN_WRITE_4(mac, BWN_MACCMD, 8703 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8704 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8705 } 8706} 8707 8708static void 8709bwn_intr_beacon(struct bwn_mac *mac) 8710{ 8711 struct bwn_softc *sc = mac->mac_sc; 8712 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8713 uint32_t cmd, beacon0, beacon1; 8714 8715 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8716 ic->ic_opmode == IEEE80211_M_MBSS) 8717 return; 8718 8719 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8720 8721 cmd = BWN_READ_4(mac, BWN_MACCMD); 8722 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8723 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8724 8725 if (beacon0 && beacon1) { 8726 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8727 mac->mac_intr_mask |= BWN_INTR_BEACON; 8728 return; 8729 } 8730 8731 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8732 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8733 bwn_load_beacon0(mac); 8734 bwn_load_beacon1(mac); 8735 cmd = BWN_READ_4(mac, BWN_MACCMD); 8736 cmd |= BWN_MACCMD_BEACON0_VALID; 8737 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8738 } else { 8739 if (!beacon0) { 8740 bwn_load_beacon0(mac); 8741 cmd = BWN_READ_4(mac, BWN_MACCMD); 8742 cmd |= BWN_MACCMD_BEACON0_VALID; 8743 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8744 } else if (!beacon1) { 8745 bwn_load_beacon1(mac); 8746 cmd = BWN_READ_4(mac, BWN_MACCMD); 8747 cmd |= BWN_MACCMD_BEACON1_VALID; 8748 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8749 } 8750 } 8751} 8752 8753static void 8754bwn_intr_pmq(struct bwn_mac *mac) 8755{ 8756 uint32_t tmp; 8757 8758 while (1) { 8759 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8760 if (!(tmp & 0x00000008)) 8761 break; 8762 } 8763 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8764} 8765 8766static void 8767bwn_intr_noise(struct bwn_mac *mac) 8768{ 8769 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8770 uint16_t tmp; 8771 uint8_t noise[4]; 8772 uint8_t i, j; 8773 int32_t average; 8774 8775 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8776 return; 8777 8778 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8779 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8780 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8781 noise[3] == 0x7f) 8782 goto new; 8783 8784 KASSERT(mac->mac_noise.noi_nsamples < 8, 8785 ("%s:%d: fail", __func__, __LINE__)); 8786 i = mac->mac_noise.noi_nsamples; 8787 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8788 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8789 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8790 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8791 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8792 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8793 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8794 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8795 mac->mac_noise.noi_nsamples++; 8796 if (mac->mac_noise.noi_nsamples == 8) { 8797 average = 0; 8798 for (i = 0; i < 8; i++) { 8799 for (j = 0; j < 4; j++) 8800 average += mac->mac_noise.noi_samples[i][j]; 8801 } 8802 average = (((average / 32) * 125) + 64) / 128; 8803 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8804 if (tmp >= 8) 8805 average += 2; 8806 else 8807 average -= 25; 8808 average -= (tmp == 8) ? 72 : 48; 8809 8810 mac->mac_stats.link_noise = average; 8811 mac->mac_noise.noi_running = 0; 8812 return; 8813 } 8814new: 8815 bwn_noise_gensample(mac); 8816} 8817 8818static int 8819bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8820{ 8821 struct bwn_mac *mac = prq->prq_mac; 8822 struct bwn_softc *sc = mac->mac_sc; 8823 unsigned int i; 8824 8825 BWN_ASSERT_LOCKED(sc); 8826 8827 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8828 return (0); 8829 8830 for (i = 0; i < 5000; i++) { 8831 if (bwn_pio_rxeof(prq) == 0) 8832 break; 8833 } 8834 if (i >= 5000) 8835 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8836 return ((i > 0) ? 1 : 0); 8837} 8838 8839static void 8840bwn_dma_rx(struct bwn_dma_ring *dr) 8841{ 8842 int slot, curslot; 8843 8844 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8845 curslot = dr->get_curslot(dr); 8846 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8847 ("%s:%d: fail", __func__, __LINE__)); 8848 8849 slot = dr->dr_curslot; 8850 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8851 bwn_dma_rxeof(dr, &slot); 8852 8853 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8854 BUS_DMASYNC_PREWRITE); 8855 8856 dr->set_curslot(dr, slot); 8857 dr->dr_curslot = slot; 8858} 8859 8860static void 8861bwn_intr_txeof(struct bwn_mac *mac) 8862{ 8863 struct bwn_txstatus stat; 8864 uint32_t stat0, stat1; 8865 uint16_t tmp; 8866 8867 BWN_ASSERT_LOCKED(mac->mac_sc); 8868 8869 while (1) { 8870 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8871 if (!(stat0 & 0x00000001)) 8872 break; 8873 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8874 8875 stat.cookie = (stat0 >> 16); 8876 stat.seq = (stat1 & 0x0000ffff); 8877 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8878 tmp = (stat0 & 0x0000ffff); 8879 stat.framecnt = ((tmp & 0xf000) >> 12); 8880 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8881 stat.sreason = ((tmp & 0x001c) >> 2); 8882 stat.pm = (tmp & 0x0080) ? 1 : 0; 8883 stat.im = (tmp & 0x0040) ? 1 : 0; 8884 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8885 stat.ack = (tmp & 0x0002) ? 1 : 0; 8886 8887 bwn_handle_txeof(mac, &stat); 8888 } 8889} 8890 8891static void 8892bwn_hwreset(void *arg, int npending) 8893{ 8894 struct bwn_mac *mac = arg; 8895 struct bwn_softc *sc = mac->mac_sc; 8896 int error = 0; 8897 int prev_status; 8898 8899 BWN_LOCK(sc); 8900 8901 prev_status = mac->mac_status; 8902 if (prev_status >= BWN_MAC_STATUS_STARTED) 8903 bwn_core_stop(mac); 8904 if (prev_status >= BWN_MAC_STATUS_INITED) 8905 bwn_core_exit(mac); 8906 8907 if (prev_status >= BWN_MAC_STATUS_INITED) { 8908 error = bwn_core_init(mac); 8909 if (error) 8910 goto out; 8911 } 8912 if (prev_status >= BWN_MAC_STATUS_STARTED) 8913 bwn_core_start(mac); 8914out: 8915 if (error) { 8916 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8917 sc->sc_curmac = NULL; 8918 } 8919 BWN_UNLOCK(sc); 8920} 8921 8922static void 8923bwn_handle_fwpanic(struct bwn_mac *mac) 8924{ 8925 struct bwn_softc *sc = mac->mac_sc; 8926 uint16_t reason; 8927 8928 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8929 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8930 8931 if (reason == BWN_FWPANIC_RESTART) 8932 bwn_restart(mac, "ucode panic"); 8933} 8934 8935static void 8936bwn_load_beacon0(struct bwn_mac *mac) 8937{ 8938 8939 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8940} 8941 8942static void 8943bwn_load_beacon1(struct bwn_mac *mac) 8944{ 8945 8946 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8947} 8948 8949static uint32_t 8950bwn_jssi_read(struct bwn_mac *mac) 8951{ 8952 uint32_t val = 0; 8953 8954 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8955 val <<= 16; 8956 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8957 8958 return (val); 8959} 8960 8961static void 8962bwn_noise_gensample(struct bwn_mac *mac) 8963{ 8964 uint32_t jssi = 0x7f7f7f7f; 8965 8966 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8967 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8968 BWN_WRITE_4(mac, BWN_MACCMD, 8969 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8970} 8971 8972static int 8973bwn_dma_freeslot(struct bwn_dma_ring *dr) 8974{ 8975 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8976 8977 return (dr->dr_numslots - dr->dr_usedslot); 8978} 8979 8980static int 8981bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8982{ 8983 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8984 8985 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8986 ("%s:%d: fail", __func__, __LINE__)); 8987 if (slot == dr->dr_numslots - 1) 8988 return (0); 8989 return (slot + 1); 8990} 8991 8992static void 8993bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8994{ 8995 struct bwn_mac *mac = dr->dr_mac; 8996 struct bwn_softc *sc = mac->mac_sc; 8997 struct bwn_dma *dma = &mac->mac_method.dma; 8998 struct bwn_dmadesc_generic *desc; 8999 struct bwn_dmadesc_meta *meta; 9000 struct bwn_rxhdr4 *rxhdr; 9001 struct ifnet *ifp = sc->sc_ifp; 9002 struct mbuf *m; 9003 uint32_t macstat; 9004 int32_t tmp; 9005 int cnt = 0; 9006 uint16_t len; 9007 9008 dr->getdesc(dr, *slot, &desc, &meta); 9009 9010 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 9011 m = meta->mt_m; 9012 9013 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 9014 ifp->if_ierrors++; 9015 return; 9016 } 9017 9018 rxhdr = mtod(m, struct bwn_rxhdr4 *); 9019 len = le16toh(rxhdr->frame_len); 9020 if (len <= 0) { 9021 ifp->if_ierrors++; 9022 return; 9023 } 9024 if (bwn_dma_check_redzone(dr, m)) { 9025 device_printf(sc->sc_dev, "redzone error.\n"); 9026 bwn_dma_set_redzone(dr, m); 9027 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9028 BUS_DMASYNC_PREWRITE); 9029 return; 9030 } 9031 if (len > dr->dr_rx_bufsize) { 9032 tmp = len; 9033 while (1) { 9034 dr->getdesc(dr, *slot, &desc, &meta); 9035 bwn_dma_set_redzone(dr, meta->mt_m); 9036 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9037 BUS_DMASYNC_PREWRITE); 9038 *slot = bwn_dma_nextslot(dr, *slot); 9039 cnt++; 9040 tmp -= dr->dr_rx_bufsize; 9041 if (tmp <= 0) 9042 break; 9043 } 9044 device_printf(sc->sc_dev, "too small buffer " 9045 "(len %u buffer %u dropped %d)\n", 9046 len, dr->dr_rx_bufsize, cnt); 9047 return; 9048 } 9049 macstat = le32toh(rxhdr->mac_status); 9050 if (macstat & BWN_RX_MAC_FCSERR) { 9051 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9052 device_printf(sc->sc_dev, "RX drop\n"); 9053 return; 9054 } 9055 } 9056 9057 m->m_pkthdr.rcvif = ifp; 9058 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 9059 m_adj(m, dr->dr_frameoffset); 9060 9061 bwn_rxeof(dr->dr_mac, m, rxhdr); 9062} 9063 9064static void 9065bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 9066{ 9067 struct bwn_dma_ring *dr; 9068 struct bwn_dmadesc_generic *desc; 9069 struct bwn_dmadesc_meta *meta; 9070 struct bwn_node *bn; 9071 struct bwn_pio_txqueue *tq; 9072 struct bwn_pio_txpkt *tp = NULL; 9073 struct bwn_softc *sc = mac->mac_sc; 9074 struct bwn_stats *stats = &mac->mac_stats; 9075 struct ieee80211_node *ni; 9076 int slot; 9077 9078 BWN_ASSERT_LOCKED(mac->mac_sc); 9079 9080 if (status->im) 9081 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9082 if (status->ampdu) 9083 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9084 if (status->rtscnt) { 9085 if (status->rtscnt == 0xf) 9086 stats->rtsfail++; 9087 else 9088 stats->rts++; 9089 } 9090 9091 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9092 if (status->ack) { 9093 dr = bwn_dma_parse_cookie(mac, status, 9094 status->cookie, &slot); 9095 if (dr == NULL) { 9096 device_printf(sc->sc_dev, 9097 "failed to parse cookie\n"); 9098 return; 9099 } 9100 while (1) { 9101 dr->getdesc(dr, slot, &desc, &meta); 9102 if (meta->mt_islast) { 9103 ni = meta->mt_ni; 9104 bn = (struct bwn_node *)ni; 9105 ieee80211_amrr_tx_complete(&bn->bn_amn, 9106 status->ack, 0); 9107 break; 9108 } 9109 slot = bwn_dma_nextslot(dr, slot); 9110 } 9111 } 9112 bwn_dma_handle_txeof(mac, status); 9113 } else { 9114 if (status->ack) { 9115 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9116 if (tq == NULL) { 9117 device_printf(sc->sc_dev, 9118 "failed to parse cookie\n"); 9119 return; 9120 } 9121 ni = tp->tp_ni; 9122 bn = (struct bwn_node *)ni; 9123 ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0); 9124 } 9125 bwn_pio_handle_txeof(mac, status); 9126 } 9127 9128 bwn_phy_txpower_check(mac, 0); 9129} 9130 9131static uint8_t 9132bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9133{ 9134 struct bwn_mac *mac = prq->prq_mac; 9135 struct bwn_softc *sc = mac->mac_sc; 9136 struct bwn_rxhdr4 rxhdr; 9137 struct ifnet *ifp = sc->sc_ifp; 9138 struct mbuf *m; 9139 uint32_t ctl32, macstat, v32; 9140 unsigned int i, padding; 9141 uint16_t ctl16, len, v16; 9142 unsigned char *mp; 9143 char *data; 9144 9145 memset(&rxhdr, 0, sizeof(rxhdr)); 9146 9147 if (prq->prq_rev >= 8) { 9148 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9149 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9150 return (0); 9151 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9152 BWN_PIO8_RXCTL_FRAMEREADY); 9153 for (i = 0; i < 10; i++) { 9154 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9155 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9156 goto ready; 9157 DELAY(10); 9158 } 9159 } else { 9160 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9161 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9162 return (0); 9163 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9164 BWN_PIO_RXCTL_FRAMEREADY); 9165 for (i = 0; i < 10; i++) { 9166 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9167 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9168 goto ready; 9169 DELAY(10); 9170 } 9171 } 9172 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9173 return (1); 9174ready: 9175 if (prq->prq_rev >= 8) 9176 siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9177 prq->prq_base + BWN_PIO8_RXDATA); 9178 else 9179 siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9180 prq->prq_base + BWN_PIO_RXDATA); 9181 len = le16toh(rxhdr.frame_len); 9182 if (len > 0x700) { 9183 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9184 goto error; 9185 } 9186 if (len == 0) { 9187 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9188 goto error; 9189 } 9190 9191 macstat = le32toh(rxhdr.mac_status); 9192 if (macstat & BWN_RX_MAC_FCSERR) { 9193 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9194 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9195 goto error; 9196 } 9197 } 9198 9199 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9200 KASSERT(len + padding <= MCLBYTES, ("too big..\n")); 9201 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9202 if (m == NULL) { 9203 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9204 goto error; 9205 } 9206 mp = mtod(m, unsigned char *); 9207 if (prq->prq_rev >= 8) { 9208 siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3), 9209 prq->prq_base + BWN_PIO8_RXDATA); 9210 if (len & 3) { 9211 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9212 data = &(mp[len + padding - 1]); 9213 switch (len & 3) { 9214 case 3: 9215 *data = (v32 >> 16); 9216 data--; 9217 case 2: 9218 *data = (v32 >> 8); 9219 data--; 9220 case 1: 9221 *data = v32; 9222 } 9223 } 9224 } else { 9225 siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1), 9226 prq->prq_base + BWN_PIO_RXDATA); 9227 if (len & 1) { 9228 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9229 mp[len + padding - 1] = v16; 9230 } 9231 } 9232 9233 m->m_pkthdr.rcvif = ifp; 9234 m->m_len = m->m_pkthdr.len = len + padding; 9235 9236 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9237 9238 return (1); 9239error: 9240 if (prq->prq_rev >= 8) 9241 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9242 BWN_PIO8_RXCTL_DATAREADY); 9243 else 9244 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9245 return (1); 9246} 9247 9248static int 9249bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9250 struct bwn_dmadesc_meta *meta, int init) 9251{ 9252 struct bwn_mac *mac = dr->dr_mac; 9253 struct bwn_dma *dma = &mac->mac_method.dma; 9254 struct bwn_rxhdr4 *hdr; 9255 bus_dmamap_t map; 9256 bus_addr_t paddr; 9257 struct mbuf *m; 9258 int error; 9259 9260 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9261 if (m == NULL) { 9262 error = ENOBUFS; 9263 9264 /* 9265 * If the NIC is up and running, we need to: 9266 * - Clear RX buffer's header. 9267 * - Restore RX descriptor settings. 9268 */ 9269 if (init) 9270 return (error); 9271 else 9272 goto back; 9273 } 9274 m->m_len = m->m_pkthdr.len = MCLBYTES; 9275 9276 bwn_dma_set_redzone(dr, m); 9277 9278 /* 9279 * Try to load RX buf into temporary DMA map 9280 */ 9281 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9282 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9283 if (error) { 9284 m_freem(m); 9285 9286 /* 9287 * See the comment above 9288 */ 9289 if (init) 9290 return (error); 9291 else 9292 goto back; 9293 } 9294 9295 if (!init) 9296 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9297 meta->mt_m = m; 9298 meta->mt_paddr = paddr; 9299 9300 /* 9301 * Swap RX buf's DMA map with the loaded temporary one 9302 */ 9303 map = meta->mt_dmap; 9304 meta->mt_dmap = dr->dr_spare_dmap; 9305 dr->dr_spare_dmap = map; 9306 9307back: 9308 /* 9309 * Clear RX buf header 9310 */ 9311 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9312 bzero(hdr, sizeof(*hdr)); 9313 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9314 BUS_DMASYNC_PREWRITE); 9315 9316 /* 9317 * Setup RX buf descriptor 9318 */ 9319 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9320 sizeof(*hdr), 0, 0, 0); 9321 return (error); 9322} 9323 9324static void 9325bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9326 bus_size_t mapsz __unused, int error) 9327{ 9328 9329 if (!error) { 9330 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9331 *((bus_addr_t *)arg) = seg->ds_addr; 9332 } 9333} 9334 9335static int 9336bwn_hwrate2ieeerate(int rate) 9337{ 9338 9339 switch (rate) { 9340 case BWN_CCK_RATE_1MB: 9341 return (2); 9342 case BWN_CCK_RATE_2MB: 9343 return (4); 9344 case BWN_CCK_RATE_5MB: 9345 return (11); 9346 case BWN_CCK_RATE_11MB: 9347 return (22); 9348 case BWN_OFDM_RATE_6MB: 9349 return (12); 9350 case BWN_OFDM_RATE_9MB: 9351 return (18); 9352 case BWN_OFDM_RATE_12MB: 9353 return (24); 9354 case BWN_OFDM_RATE_18MB: 9355 return (36); 9356 case BWN_OFDM_RATE_24MB: 9357 return (48); 9358 case BWN_OFDM_RATE_36MB: 9359 return (72); 9360 case BWN_OFDM_RATE_48MB: 9361 return (96); 9362 case BWN_OFDM_RATE_54MB: 9363 return (108); 9364 default: 9365 printf("Ooops\n"); 9366 return (0); 9367 } 9368} 9369 9370static void 9371bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9372{ 9373 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9374 struct bwn_plcp6 *plcp; 9375 struct bwn_softc *sc = mac->mac_sc; 9376 struct ieee80211_frame_min *wh; 9377 struct ieee80211_node *ni; 9378 struct ifnet *ifp = sc->sc_ifp; 9379 struct ieee80211com *ic = ifp->if_l2com; 9380 uint32_t macstat; 9381 int padding, rate, rssi = 0, noise = 0, type; 9382 uint16_t phytype, phystat0, phystat3, chanstat; 9383 unsigned char *mp = mtod(m, unsigned char *); 9384 static int rx_mac_dec_rpt = 0; 9385 9386 BWN_ASSERT_LOCKED(sc); 9387 9388 phystat0 = le16toh(rxhdr->phy_status0); 9389 phystat3 = le16toh(rxhdr->phy_status3); 9390 macstat = le32toh(rxhdr->mac_status); 9391 chanstat = le16toh(rxhdr->channel); 9392 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9393 9394 if (macstat & BWN_RX_MAC_FCSERR) 9395 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9396 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9397 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9398 if (phystat0 & BWN_RX_PHYST0_SHORTPRMBL) 9399 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_SHORTPRE\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