if_bwn.c revision 204256
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 204256 2010-02-23 19:44:51Z 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); 539 540static struct resource_spec bwn_res_spec_legacy[] = { 541 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 542 { -1, 0, 0 } 543}; 544 545static struct resource_spec bwn_res_spec_msi[] = { 546 { SYS_RES_IRQ, 1, RF_ACTIVE }, 547 { -1, 0, 0 } 548}; 549 550static const struct bwn_channelinfo bwn_chantable_bg = { 551 .channels = { 552 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 553 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 554 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 555 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 556 { 2472, 13, 30 }, { 2484, 14, 30 } }, 557 .nchannels = 14 558}; 559 560static const struct bwn_channelinfo bwn_chantable_a = { 561 .channels = { 562 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 563 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 564 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 565 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 566 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 567 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 568 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 569 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 570 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 571 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 572 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 573 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 574 { 6080, 216, 30 } }, 575 .nchannels = 37 576}; 577 578static const struct bwn_channelinfo bwn_chantable_n = { 579 .channels = { 580 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 581 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 582 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 583 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 584 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 585 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 586 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 587 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 588 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 589 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 590 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 591 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 592 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 593 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 594 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 595 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 596 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 597 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 598 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 599 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 600 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 601 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 602 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 603 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 604 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 605 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 606 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 607 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 608 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 609 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 610 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 611 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 612 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 613 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 614 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 615 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 616 { 6130, 226, 30 }, { 6140, 228, 30 } }, 617 .nchannels = 110 618}; 619 620static const uint8_t bwn_b2063_chantable_data[33][12] = { 621 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 622 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 623 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 624 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 625 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 626 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 627 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 628 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 629 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 630 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 631 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 632 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 633 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 634 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 635 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 636 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 637 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 638 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 639 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 640 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 641 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 642 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 643 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 644 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 645 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 646 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 647 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 648 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 649 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 650 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 651 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 652 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 653 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 654}; 655 656static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 657 { 1, 2412, bwn_b2063_chantable_data[0] }, 658 { 2, 2417, bwn_b2063_chantable_data[0] }, 659 { 3, 2422, bwn_b2063_chantable_data[0] }, 660 { 4, 2427, bwn_b2063_chantable_data[1] }, 661 { 5, 2432, bwn_b2063_chantable_data[1] }, 662 { 6, 2437, bwn_b2063_chantable_data[1] }, 663 { 7, 2442, bwn_b2063_chantable_data[1] }, 664 { 8, 2447, bwn_b2063_chantable_data[1] }, 665 { 9, 2452, bwn_b2063_chantable_data[2] }, 666 { 10, 2457, bwn_b2063_chantable_data[2] }, 667 { 11, 2462, bwn_b2063_chantable_data[3] }, 668 { 12, 2467, bwn_b2063_chantable_data[3] }, 669 { 13, 2472, bwn_b2063_chantable_data[3] }, 670 { 14, 2484, bwn_b2063_chantable_data[4] }, 671 { 34, 5170, bwn_b2063_chantable_data[5] }, 672 { 36, 5180, bwn_b2063_chantable_data[6] }, 673 { 38, 5190, bwn_b2063_chantable_data[7] }, 674 { 40, 5200, bwn_b2063_chantable_data[8] }, 675 { 42, 5210, bwn_b2063_chantable_data[9] }, 676 { 44, 5220, bwn_b2063_chantable_data[10] }, 677 { 46, 5230, bwn_b2063_chantable_data[11] }, 678 { 48, 5240, bwn_b2063_chantable_data[12] }, 679 { 52, 5260, bwn_b2063_chantable_data[13] }, 680 { 56, 5280, bwn_b2063_chantable_data[14] }, 681 { 60, 5300, bwn_b2063_chantable_data[14] }, 682 { 64, 5320, bwn_b2063_chantable_data[15] }, 683 { 100, 5500, bwn_b2063_chantable_data[16] }, 684 { 104, 5520, bwn_b2063_chantable_data[17] }, 685 { 108, 5540, bwn_b2063_chantable_data[18] }, 686 { 112, 5560, bwn_b2063_chantable_data[19] }, 687 { 116, 5580, bwn_b2063_chantable_data[20] }, 688 { 120, 5600, bwn_b2063_chantable_data[21] }, 689 { 124, 5620, bwn_b2063_chantable_data[21] }, 690 { 128, 5640, bwn_b2063_chantable_data[22] }, 691 { 132, 5660, bwn_b2063_chantable_data[22] }, 692 { 136, 5680, bwn_b2063_chantable_data[22] }, 693 { 140, 5700, bwn_b2063_chantable_data[23] }, 694 { 149, 5745, bwn_b2063_chantable_data[23] }, 695 { 153, 5765, bwn_b2063_chantable_data[23] }, 696 { 157, 5785, bwn_b2063_chantable_data[23] }, 697 { 161, 5805, bwn_b2063_chantable_data[23] }, 698 { 165, 5825, bwn_b2063_chantable_data[23] }, 699 { 184, 4920, bwn_b2063_chantable_data[24] }, 700 { 188, 4940, bwn_b2063_chantable_data[25] }, 701 { 192, 4960, bwn_b2063_chantable_data[26] }, 702 { 196, 4980, bwn_b2063_chantable_data[27] }, 703 { 200, 5000, bwn_b2063_chantable_data[28] }, 704 { 204, 5020, bwn_b2063_chantable_data[29] }, 705 { 208, 5040, bwn_b2063_chantable_data[30] }, 706 { 212, 5060, bwn_b2063_chantable_data[31] }, 707 { 216, 5080, bwn_b2063_chantable_data[32] } 708}; 709 710static const uint8_t bwn_b2062_chantable_data[22][12] = { 711 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 712 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 719 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 720 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 721 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 722 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 723 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 724 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 727 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 728 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 729 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 730 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 731 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 732 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 733}; 734 735static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 736 { 1, 2412, bwn_b2062_chantable_data[0] }, 737 { 2, 2417, bwn_b2062_chantable_data[0] }, 738 { 3, 2422, bwn_b2062_chantable_data[0] }, 739 { 4, 2427, bwn_b2062_chantable_data[0] }, 740 { 5, 2432, bwn_b2062_chantable_data[0] }, 741 { 6, 2437, bwn_b2062_chantable_data[0] }, 742 { 7, 2442, bwn_b2062_chantable_data[0] }, 743 { 8, 2447, bwn_b2062_chantable_data[0] }, 744 { 9, 2452, bwn_b2062_chantable_data[0] }, 745 { 10, 2457, bwn_b2062_chantable_data[0] }, 746 { 11, 2462, bwn_b2062_chantable_data[0] }, 747 { 12, 2467, bwn_b2062_chantable_data[0] }, 748 { 13, 2472, bwn_b2062_chantable_data[0] }, 749 { 14, 2484, bwn_b2062_chantable_data[0] }, 750 { 34, 5170, bwn_b2062_chantable_data[1] }, 751 { 38, 5190, bwn_b2062_chantable_data[2] }, 752 { 42, 5210, bwn_b2062_chantable_data[2] }, 753 { 46, 5230, bwn_b2062_chantable_data[3] }, 754 { 36, 5180, bwn_b2062_chantable_data[4] }, 755 { 40, 5200, bwn_b2062_chantable_data[5] }, 756 { 44, 5220, bwn_b2062_chantable_data[6] }, 757 { 48, 5240, bwn_b2062_chantable_data[3] }, 758 { 52, 5260, bwn_b2062_chantable_data[3] }, 759 { 56, 5280, bwn_b2062_chantable_data[3] }, 760 { 60, 5300, bwn_b2062_chantable_data[7] }, 761 { 64, 5320, bwn_b2062_chantable_data[8] }, 762 { 100, 5500, bwn_b2062_chantable_data[9] }, 763 { 104, 5520, bwn_b2062_chantable_data[10] }, 764 { 108, 5540, bwn_b2062_chantable_data[10] }, 765 { 112, 5560, bwn_b2062_chantable_data[10] }, 766 { 116, 5580, bwn_b2062_chantable_data[11] }, 767 { 120, 5600, bwn_b2062_chantable_data[12] }, 768 { 124, 5620, bwn_b2062_chantable_data[12] }, 769 { 128, 5640, bwn_b2062_chantable_data[12] }, 770 { 132, 5660, bwn_b2062_chantable_data[12] }, 771 { 136, 5680, bwn_b2062_chantable_data[12] }, 772 { 140, 5700, bwn_b2062_chantable_data[12] }, 773 { 149, 5745, bwn_b2062_chantable_data[12] }, 774 { 153, 5765, bwn_b2062_chantable_data[12] }, 775 { 157, 5785, bwn_b2062_chantable_data[12] }, 776 { 161, 5805, bwn_b2062_chantable_data[12] }, 777 { 165, 5825, bwn_b2062_chantable_data[12] }, 778 { 184, 4920, bwn_b2062_chantable_data[13] }, 779 { 188, 4940, bwn_b2062_chantable_data[14] }, 780 { 192, 4960, bwn_b2062_chantable_data[15] }, 781 { 196, 4980, bwn_b2062_chantable_data[16] }, 782 { 200, 5000, bwn_b2062_chantable_data[17] }, 783 { 204, 5020, bwn_b2062_chantable_data[18] }, 784 { 208, 5040, bwn_b2062_chantable_data[19] }, 785 { 212, 5060, bwn_b2062_chantable_data[20] }, 786 { 216, 5080, bwn_b2062_chantable_data[21] } 787}; 788 789/* for LP PHY */ 790static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 791 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 792 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 793 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 794 { 13, -66, 13 }, { 14, -66, 13 }, 795}; 796 797/* for LP PHY */ 798static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 799 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 800 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 801 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 802 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 803 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 804 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 805 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 806 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 807 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 808 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 809 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 810 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 811 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 812}; 813 814static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 815 816static const uint8_t bwn_tab_sigsq_tbl[] = { 817 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 818 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 819 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 820 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 821 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 822 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 823}; 824 825static const uint8_t bwn_tab_pllfrac_tbl[] = { 826 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 827 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 828}; 829 830static const uint16_t bwn_tabl_iqlocal_tbl[] = { 831 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 832 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 835 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 836 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x4000, 0x0000, 0x0000, 841 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 842 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 843}; 844 845static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 846static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 847static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 848static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 849static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 850const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 851 852#define VENDOR_LED_ACT(vendor) \ 853{ \ 854 .vid = PCI_VENDOR_##vendor, \ 855 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 856} 857 858static const struct { 859 uint16_t vid; 860 uint8_t led_act[BWN_LED_MAX]; 861} bwn_vendor_led_act[] = { 862 VENDOR_LED_ACT(COMPAQ), 863 VENDOR_LED_ACT(ASUSTEK) 864}; 865 866static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 867 { BWN_VENDOR_LED_ACT_DEFAULT }; 868 869#undef VENDOR_LED_ACT 870 871static const struct { 872 int on_dur; 873 int off_dur; 874} bwn_led_duration[109] = { 875 [0] = { 400, 100 }, 876 [2] = { 150, 75 }, 877 [4] = { 90, 45 }, 878 [11] = { 66, 34 }, 879 [12] = { 53, 26 }, 880 [18] = { 42, 21 }, 881 [22] = { 35, 17 }, 882 [24] = { 32, 16 }, 883 [36] = { 21, 10 }, 884 [48] = { 16, 8 }, 885 [72] = { 11, 5 }, 886 [96] = { 9, 4 }, 887 [108] = { 7, 3 } 888}; 889 890static const uint16_t bwn_wme_shm_offsets[] = { 891 [0] = BWN_WME_BESTEFFORT, 892 [1] = BWN_WME_BACKGROUND, 893 [2] = BWN_WME_VOICE, 894 [3] = BWN_WME_VIDEO, 895}; 896 897static const struct siba_devid bwn_devs[] = { 898 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 899 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 900 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 901 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 902 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 903 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 904 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 905 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 906 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 907}; 908 909static int 910bwn_probe(device_t dev) 911{ 912 struct siba_dev_softc *sd = device_get_ivars(dev); 913 int i; 914 915 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 916 if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor && 917 sd->sd_id.sd_device == bwn_devs[i].sd_device && 918 sd->sd_id.sd_rev == bwn_devs[i].sd_rev) 919 return (BUS_PROBE_DEFAULT); 920 } 921 922 return (ENXIO); 923} 924 925static int 926bwn_attach(device_t dev) 927{ 928 struct bwn_mac *mac; 929 struct bwn_softc *sc = device_get_softc(dev); 930 struct siba_dev_softc *sd = device_get_ivars(dev); 931 struct siba_softc *siba = sd->sd_bus; 932 int error, i, msic, reg; 933 934 sc->sc_dev = dev; 935 sc->sc_sd = sd; 936#ifdef BWN_DEBUG 937 sc->sc_debug = bwn_debug; 938#endif 939 940 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 941 error = bwn_attach_pre(sc); 942 if (error != 0) 943 return (error); 944 bwn_sprom_bugfixes(sd->sd_bus); 945 sc->sc_flags |= BWN_FLAG_ATTACHED; 946 } 947 948 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 949 if (siba->siba_pci_did != 0x4313 && 950 siba->siba_pci_did != 0x431a && 951 siba->siba_pci_did != 0x4321) { 952 device_printf(sc->sc_dev, 953 "skip 802.11 cores\n"); 954 return (ENODEV); 955 } 956 } 957 958 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 959 M_NOWAIT | M_ZERO); 960 if (mac == NULL) 961 return (ENOMEM); 962 mac->mac_sc = sc; 963 mac->mac_sd = sd; 964 mac->mac_status = BWN_MAC_STATUS_UNINIT; 965 if (bwn_bfp != 0) 966 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 967 968 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 969 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 970 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 971 972 error = bwn_attach_core(mac); 973 if (error) 974 goto fail0; 975 bwn_led_attach(mac); 976 977 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 978 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 979 sd->sd_bus->siba_chipid, sd->sd_id.sd_rev, 980 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 981 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 982 mac->mac_phy.rf_rev); 983 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 984 device_printf(sc->sc_dev, "DMA (%d bits)\n", 985 mac->mac_method.dma.dmatype); 986 else 987 device_printf(sc->sc_dev, "PIO\n"); 988 989 /* 990 * setup PCI resources and interrupt. 991 */ 992 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) { 993 msic = pci_msi_count(dev); 994 if (bootverbose) 995 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 996 } else 997 msic = 0; 998 999 mac->mac_intr_spec = bwn_res_spec_legacy; 1000 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 1001 if (pci_alloc_msi(dev, &msic) == 0) { 1002 device_printf(sc->sc_dev, 1003 "Using %d MSI messages\n", msic); 1004 mac->mac_intr_spec = bwn_res_spec_msi; 1005 mac->mac_msi = 1; 1006 } 1007 } 1008 1009 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1010 mac->mac_res_irq); 1011 if (error) { 1012 device_printf(sc->sc_dev, 1013 "couldn't allocate IRQ resources (%d)\n", error); 1014 goto fail1; 1015 } 1016 1017 if (mac->mac_msi == 0) 1018 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1019 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1020 &mac->mac_intrhand[0]); 1021 else { 1022 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1023 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1024 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1025 &mac->mac_intrhand[i]); 1026 if (error != 0) { 1027 device_printf(sc->sc_dev, 1028 "couldn't setup interrupt (%d)\n", error); 1029 break; 1030 } 1031 } 1032 } 1033 1034 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1035 1036 /* 1037 * calls attach-post routine 1038 */ 1039 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1040 bwn_attach_post(sc); 1041 1042 return (0); 1043fail1: 1044 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1045 pci_release_msi(dev); 1046fail0: 1047 free(mac, M_DEVBUF); 1048 return (error); 1049} 1050 1051static int 1052bwn_is_valid_ether_addr(uint8_t *addr) 1053{ 1054 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1055 1056 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1057 return (FALSE); 1058 1059 return (TRUE); 1060} 1061 1062static int 1063bwn_attach_post(struct bwn_softc *sc) 1064{ 1065 struct ieee80211com *ic; 1066 struct ifnet *ifp = sc->sc_ifp; 1067 struct siba_dev_softc *sd = sc->sc_sd; 1068 struct siba_sprom *sprom = &sd->sd_bus->siba_sprom; 1069#ifdef BWN_DEBUG 1070 device_t dev = sc->sc_dev; 1071#endif 1072 1073 ic = ifp->if_l2com; 1074 ic->ic_ifp = ifp; 1075 /* XXX not right but it's not used anywhere important */ 1076 ic->ic_phytype = IEEE80211_T_OFDM; 1077 ic->ic_opmode = IEEE80211_M_STA; 1078 ic->ic_caps = 1079 IEEE80211_C_STA /* station mode supported */ 1080 | IEEE80211_C_MONITOR /* monitor mode */ 1081 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1082 | IEEE80211_C_SHSLOT /* short slot time supported */ 1083 | IEEE80211_C_WME /* WME/WMM supported */ 1084 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1085 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1086 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1087 ; 1088 1089 /* call MI attach routine. */ 1090 ieee80211_ifattach(ic, 1091 bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a : 1092 sprom->mac_80211bg); 1093 1094 ic->ic_headroom = sizeof(struct bwn_txhdr); 1095 1096 /* override default methods */ 1097 ic->ic_raw_xmit = bwn_raw_xmit; 1098 ic->ic_newassoc = bwn_newassoc; 1099 ic->ic_updateslot = bwn_updateslot; 1100 ic->ic_update_promisc = bwn_update_promisc; 1101 ic->ic_wme.wme_update = bwn_wme_update; 1102 1103 ic->ic_node_alloc = bwn_node_alloc; 1104 sc->sc_node_cleanup = ic->ic_node_cleanup; 1105 ic->ic_node_cleanup = bwn_node_cleanup; 1106 1107 ic->ic_scan_start = bwn_scan_start; 1108 ic->ic_scan_end = bwn_scan_end; 1109 ic->ic_set_channel = bwn_set_channel; 1110 1111 ic->ic_vap_create = bwn_vap_create; 1112 ic->ic_vap_delete = bwn_vap_delete; 1113 1114 ieee80211_radiotap_attach(ic, 1115 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1116 BWN_TX_RADIOTAP_PRESENT, 1117 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1118 BWN_RX_RADIOTAP_PRESENT); 1119 1120#ifdef BWN_DEBUG 1121 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 1122 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1123 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 1124#endif 1125 1126 if (bootverbose) 1127 ieee80211_announce(ic); 1128 return (0); 1129} 1130 1131static void 1132bwn_phy_detach(struct bwn_mac *mac) 1133{ 1134 1135 if (mac->mac_phy.detach != NULL) 1136 mac->mac_phy.detach(mac); 1137} 1138 1139static int 1140bwn_detach(device_t dev) 1141{ 1142 struct bwn_softc *sc = device_get_softc(dev); 1143 struct bwn_mac *mac = sc->sc_curmac; 1144 struct ifnet *ifp = sc->sc_ifp; 1145 struct ieee80211com *ic = ifp->if_l2com; 1146 int i; 1147 1148 sc->sc_flags |= BWN_FLAG_INVALID; 1149 1150 if (device_is_attached(sc->sc_dev)) { 1151 bwn_stop(sc, 1); 1152 bwn_dma_free(mac); 1153 callout_drain(&sc->sc_led_blink_ch); 1154 callout_drain(&sc->sc_rfswitch_ch); 1155 callout_drain(&sc->sc_task_ch); 1156 callout_drain(&sc->sc_watchdog_ch); 1157 bwn_phy_detach(mac); 1158 if (ifp != NULL) { 1159 ieee80211_draintask(ic, &mac->mac_hwreset); 1160 ieee80211_draintask(ic, &mac->mac_txpower); 1161 ieee80211_ifdetach(ic); 1162 if_free(ifp); 1163 } 1164 } 1165 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1166 taskqueue_free(sc->sc_tq); 1167 1168 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1169 if (mac->mac_intrhand[i] != NULL) { 1170 bus_teardown_intr(dev, mac->mac_res_irq[i], 1171 mac->mac_intrhand[i]); 1172 mac->mac_intrhand[i] = NULL; 1173 } 1174 } 1175 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1176 if (mac->mac_msi != 0) 1177 pci_release_msi(dev); 1178 1179 BWN_LOCK_DESTROY(sc); 1180 return (0); 1181} 1182 1183static int 1184bwn_attach_pre(struct bwn_softc *sc) 1185{ 1186 struct ifnet *ifp; 1187 int error = 0; 1188 1189 BWN_LOCK_INIT(sc); 1190 TAILQ_INIT(&sc->sc_maclist); 1191 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1192 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1193 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1194 1195 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1196 taskqueue_thread_enqueue, &sc->sc_tq); 1197 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1198 "%s taskq", device_get_nameunit(sc->sc_dev)); 1199 1200 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1201 if (ifp == NULL) { 1202 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1203 error = ENOSPC; 1204 goto fail; 1205 } 1206 1207 /* set these up early for if_printf use */ 1208 if_initname(ifp, device_get_name(sc->sc_dev), 1209 device_get_unit(sc->sc_dev)); 1210 1211 ifp->if_softc = sc; 1212 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1213 ifp->if_init = bwn_init; 1214 ifp->if_ioctl = bwn_ioctl; 1215 ifp->if_start = bwn_start; 1216 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 1217 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 1218 IFQ_SET_READY(&ifp->if_snd); 1219 1220 return (0); 1221 1222fail: BWN_LOCK_DESTROY(sc); 1223 return (error); 1224} 1225 1226static void 1227bwn_sprom_bugfixes(struct siba_softc *siba) 1228{ 1229#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1230 ((siba->siba_pci_vid == PCI_VENDOR_##_vendor) && \ 1231 (siba->siba_pci_did == _device) && \ 1232 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) && \ 1233 (siba->siba_pci_subdid == _subdevice)) 1234 1235 if (siba->siba_board_vendor == PCI_VENDOR_APPLE && 1236 siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40) 1237 siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL; 1238 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL && 1239 siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74) 1240 siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST; 1241 if (siba->siba_type == SIBA_TYPE_PCI) { 1242 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1243 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1244 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1245 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1246 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1247 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1248 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1249 siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST; 1250 } 1251#undef BWN_ISDEV 1252} 1253 1254static int 1255bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1256{ 1257#define IS_RUNNING(ifp) \ 1258 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1259 struct bwn_softc *sc = ifp->if_softc; 1260 struct ieee80211com *ic = ifp->if_l2com; 1261 struct ifreq *ifr = (struct ifreq *)data; 1262 int error = 0, startall; 1263 1264 switch (cmd) { 1265 case SIOCSIFFLAGS: 1266 startall = 0; 1267 if (IS_RUNNING(ifp)) { 1268 bwn_update_promisc(ifp); 1269 } else if (ifp->if_flags & IFF_UP) { 1270 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1271 bwn_init(sc); 1272 startall = 1; 1273 } 1274 } else 1275 bwn_stop(sc, 1); 1276 if (startall) 1277 ieee80211_start_all(ic); 1278 break; 1279 case SIOCGIFMEDIA: 1280 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1281 break; 1282 case SIOCGIFADDR: 1283 error = ether_ioctl(ifp, cmd, data); 1284 break; 1285 default: 1286 error = EINVAL; 1287 break; 1288 } 1289 return (error); 1290} 1291 1292static void 1293bwn_start(struct ifnet *ifp) 1294{ 1295 struct bwn_softc *sc = ifp->if_softc; 1296 1297 BWN_LOCK(sc); 1298 bwn_start_locked(ifp); 1299 BWN_UNLOCK(sc); 1300} 1301 1302static void 1303bwn_start_locked(struct ifnet *ifp) 1304{ 1305 struct bwn_softc *sc = ifp->if_softc; 1306 struct bwn_mac *mac = sc->sc_curmac; 1307 struct ieee80211_frame *wh; 1308 struct ieee80211_node *ni; 1309 struct ieee80211_key *k; 1310 struct mbuf *m; 1311 1312 BWN_ASSERT_LOCKED(sc); 1313 1314 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1315 mac->mac_status < BWN_MAC_STATUS_STARTED) 1316 return; 1317 1318 for (;;) { 1319 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1320 if (m == NULL) 1321 break; 1322 1323 if (bwn_tx_isfull(sc, m)) 1324 break; 1325 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1326 if (ni == NULL) { 1327 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1328 m_freem(m); 1329 ifp->if_oerrors++; 1330 continue; 1331 } 1332 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1333 wh = mtod(m, struct ieee80211_frame *); 1334 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1335 k = ieee80211_crypto_encap(ni, m); 1336 if (k == NULL) { 1337 ieee80211_free_node(ni); 1338 m_freem(m); 1339 ifp->if_oerrors++; 1340 continue; 1341 } 1342 } 1343 wh = NULL; /* Catch any invalid use */ 1344 1345 if (bwn_tx_start(sc, ni, m) != 0) { 1346 if (ni != NULL) 1347 ieee80211_free_node(ni); 1348 ifp->if_oerrors++; 1349 continue; 1350 } 1351 1352 sc->sc_watchdog_timer = 5; 1353 } 1354} 1355 1356static int 1357bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1358{ 1359 struct bwn_dma_ring *dr; 1360 struct bwn_mac *mac = sc->sc_curmac; 1361 struct bwn_pio_txqueue *tq; 1362 struct ifnet *ifp = sc->sc_ifp; 1363 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1364 1365 BWN_ASSERT_LOCKED(sc); 1366 1367 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1368 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1369 if (dr->dr_stop == 1 || 1370 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1371 dr->dr_stop = 1; 1372 goto full; 1373 } 1374 } else { 1375 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1376 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1377 pktlen > (tq->tq_size - tq->tq_used)) { 1378 tq->tq_stop = 1; 1379 goto full; 1380 } 1381 } 1382 return (0); 1383full: 1384 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1385 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1386 return (1); 1387} 1388 1389static int 1390bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1391{ 1392 struct bwn_mac *mac = sc->sc_curmac; 1393 int error; 1394 1395 BWN_ASSERT_LOCKED(sc); 1396 1397 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1398 m_freem(m); 1399 return (ENXIO); 1400 } 1401 1402 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1403 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1404 if (error) { 1405 m_freem(m); 1406 return (error); 1407 } 1408 return (0); 1409} 1410 1411static int 1412bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1413{ 1414 struct bwn_pio_txpkt *tp; 1415 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1416 struct bwn_softc *sc = mac->mac_sc; 1417 struct bwn_txhdr txhdr; 1418 struct mbuf *m_new; 1419 uint32_t ctl32; 1420 int error; 1421 uint16_t ctl16; 1422 1423 BWN_ASSERT_LOCKED(sc); 1424 1425 /* XXX TODO send packets after DTIM */ 1426 1427 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1428 tp = TAILQ_FIRST(&tq->tq_pktlist); 1429 tp->tp_ni = ni; 1430 tp->tp_m = m; 1431 1432 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1433 if (error) { 1434 device_printf(sc->sc_dev, "tx fail\n"); 1435 return (error); 1436 } 1437 1438 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1439 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1440 tq->tq_free--; 1441 1442 if (mac->mac_sd->sd_id.sd_rev >= 8) { 1443 /* 1444 * XXX please removes m_defrag(9) 1445 */ 1446 m_new = m_defrag(m, M_DONTWAIT); 1447 if (m_new == NULL) { 1448 device_printf(sc->sc_dev, 1449 "%s: can't defrag TX buffer\n", 1450 __func__); 1451 return (ENOBUFS); 1452 } 1453 if (m_new->m_next != NULL) 1454 device_printf(sc->sc_dev, 1455 "TODO: fragmented packets for PIO\n"); 1456 tp->tp_m = m_new; 1457 1458 /* send HEADER */ 1459 ctl32 = bwn_pio_write_multi_4(mac, tq, 1460 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1461 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1462 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1463 /* send BODY */ 1464 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1465 mtod(m_new, const void *), m_new->m_pkthdr.len); 1466 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1467 ctl32 | BWN_PIO8_TXCTL_EOF); 1468 } else { 1469 ctl16 = bwn_pio_write_multi_2(mac, tq, 1470 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1471 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1472 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1473 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1474 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1475 ctl16 | BWN_PIO_TXCTL_EOF); 1476 } 1477 1478 return (0); 1479} 1480 1481static struct bwn_pio_txqueue * 1482bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1483{ 1484 1485 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1486 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1487 1488 switch (prio) { 1489 case 0: 1490 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1491 case 1: 1492 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1493 case 2: 1494 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1495 case 3: 1496 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1497 } 1498 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1499 return (NULL); 1500} 1501 1502static int 1503bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1504{ 1505#define BWN_GET_TXHDRCACHE(slot) \ 1506 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1507 struct bwn_dma *dma = &mac->mac_method.dma; 1508 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1509 struct bwn_dmadesc_generic *desc; 1510 struct bwn_dmadesc_meta *mt; 1511 struct bwn_softc *sc = mac->mac_sc; 1512 struct ifnet *ifp = sc->sc_ifp; 1513 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1514 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1515 1516 BWN_ASSERT_LOCKED(sc); 1517 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1518 1519 /* XXX send after DTIM */ 1520 1521 slot = bwn_dma_getslot(dr); 1522 dr->getdesc(dr, slot, &desc, &mt); 1523 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1524 ("%s:%d: fail", __func__, __LINE__)); 1525 1526 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1527 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1528 BWN_DMA_COOKIE(dr, slot)); 1529 if (error) 1530 goto fail; 1531 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1532 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1533 &mt->mt_paddr, BUS_DMA_NOWAIT); 1534 if (error) { 1535 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1536 __func__, error); 1537 goto fail; 1538 } 1539 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1540 BUS_DMASYNC_PREWRITE); 1541 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1542 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1543 BUS_DMASYNC_PREWRITE); 1544 1545 slot = bwn_dma_getslot(dr); 1546 dr->getdesc(dr, slot, &desc, &mt); 1547 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1548 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1549 mt->mt_m = m; 1550 mt->mt_ni = ni; 1551 1552 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1553 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1554 if (error && error != EFBIG) { 1555 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1556 __func__, error); 1557 goto fail; 1558 } 1559 if (error) { /* error == EFBIG */ 1560 struct mbuf *m_new; 1561 1562 m_new = m_defrag(m, M_DONTWAIT); 1563 if (m_new == NULL) { 1564 if_printf(ifp, "%s: can't defrag TX buffer\n", 1565 __func__); 1566 error = ENOBUFS; 1567 goto fail; 1568 } else { 1569 m = m_new; 1570 } 1571 1572 mt->mt_m = m; 1573 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1574 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1575 if (error) { 1576 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1577 __func__, error); 1578 goto fail; 1579 } 1580 } 1581 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1582 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1583 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1584 BUS_DMASYNC_PREWRITE); 1585 1586 /* XXX send after DTIM */ 1587 1588 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1589 return (0); 1590fail: 1591 dr->dr_curslot = backup[0]; 1592 dr->dr_usedslot = backup[1]; 1593 return (error); 1594#undef BWN_GET_TXHDRCACHE 1595} 1596 1597static void 1598bwn_watchdog(void *arg) 1599{ 1600 struct bwn_softc *sc = arg; 1601 struct ifnet *ifp = sc->sc_ifp; 1602 1603 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1604 if_printf(ifp, "device timeout\n"); 1605 ifp->if_oerrors++; 1606 } 1607 callout_schedule(&sc->sc_watchdog_ch, hz); 1608} 1609 1610static int 1611bwn_attach_core(struct bwn_mac *mac) 1612{ 1613 struct bwn_softc *sc = mac->mac_sc; 1614 struct siba_dev_softc *sd = mac->mac_sd; 1615 struct siba_softc *siba = sd->sd_bus; 1616 int error, have_bg = 0, have_a = 0; 1617 uint32_t high; 1618 1619 KASSERT(sd->sd_id.sd_rev >= 5, 1620 ("unsupported revision %d", sd->sd_id.sd_rev)); 1621 1622 siba_powerup(siba, 0); 1623 1624 high = siba_read_4(sd, SIBA_TGSHIGH); 1625 bwn_reset_core(mac, 1626 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1627 error = bwn_phy_getinfo(mac, high); 1628 if (error) 1629 goto fail; 1630 1631 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1632 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1633 if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 && 1634 siba->siba_pci_did != 0x4324) { 1635 have_a = have_bg = 0; 1636 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1637 have_a = 1; 1638 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1639 mac->mac_phy.type == BWN_PHYTYPE_N || 1640 mac->mac_phy.type == BWN_PHYTYPE_LP) 1641 have_bg = 1; 1642 else 1643 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1644 mac->mac_phy.type)); 1645 } 1646 /* XXX turns off PHY A because it's not supported */ 1647 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1648 mac->mac_phy.type != BWN_PHYTYPE_N) { 1649 have_a = 0; 1650 have_bg = 1; 1651 } 1652 1653 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1654 mac->mac_phy.attach = bwn_phy_g_attach; 1655 mac->mac_phy.detach = bwn_phy_g_detach; 1656 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1657 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1658 mac->mac_phy.init = bwn_phy_g_init; 1659 mac->mac_phy.exit = bwn_phy_g_exit; 1660 mac->mac_phy.phy_read = bwn_phy_g_read; 1661 mac->mac_phy.phy_write = bwn_phy_g_write; 1662 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1663 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1664 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1665 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1666 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1667 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1668 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1669 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1670 mac->mac_phy.set_im = bwn_phy_g_im; 1671 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1672 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1673 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1674 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1675 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1676 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1677 mac->mac_phy.init = bwn_phy_lp_init; 1678 mac->mac_phy.phy_read = bwn_phy_lp_read; 1679 mac->mac_phy.phy_write = bwn_phy_lp_write; 1680 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1681 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1682 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1683 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1684 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1685 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1686 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1687 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1688 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1689 } else { 1690 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1691 mac->mac_phy.type); 1692 error = ENXIO; 1693 goto fail; 1694 } 1695 1696 mac->mac_phy.gmode = have_bg; 1697 if (mac->mac_phy.attach != NULL) { 1698 error = mac->mac_phy.attach(mac); 1699 if (error) { 1700 device_printf(sc->sc_dev, "failed\n"); 1701 goto fail; 1702 } 1703 } 1704 1705 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1706 1707 error = bwn_chiptest(mac); 1708 if (error) 1709 goto fail; 1710 error = bwn_setup_channels(mac, have_bg, have_a); 1711 if (error) { 1712 device_printf(sc->sc_dev, "failed to setup channels\n"); 1713 goto fail; 1714 } 1715 1716 if (sc->sc_curmac == NULL) 1717 sc->sc_curmac = mac; 1718 1719 error = bwn_dma_attach(mac); 1720 if (error != 0) { 1721 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1722 goto fail; 1723 } 1724 1725 mac->mac_phy.switch_analog(mac, 0); 1726 1727 siba_dev_down(sd, 0); 1728fail: 1729 siba_powerdown(siba); 1730 return (error); 1731} 1732 1733static void 1734bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1735{ 1736 struct siba_dev_softc *sd = mac->mac_sd; 1737 uint32_t low, ctl; 1738 1739 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1740 1741 siba_dev_up(sd, flags); 1742 DELAY(2000); 1743 1744 low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1745 ~BWN_TGSLOW_PHYRESET; 1746 siba_write_4(sd, SIBA_TGSLOW, low); 1747 siba_read_4(sd, SIBA_TGSLOW); 1748 DELAY(1000); 1749 siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1750 siba_read_4(sd, SIBA_TGSLOW); 1751 DELAY(1000); 1752 1753 if (mac->mac_phy.switch_analog != NULL) 1754 mac->mac_phy.switch_analog(mac, 1); 1755 1756 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1757 if (flags & BWN_TGSLOW_SUPPORT_G) 1758 ctl |= BWN_MACCTL_GMODE; 1759 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1760} 1761 1762static int 1763bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1764{ 1765 struct bwn_phy *phy = &mac->mac_phy; 1766 struct bwn_softc *sc = mac->mac_sc; 1767 struct siba_dev_softc *sd = mac->mac_sd; 1768 struct siba_softc *siba = sd->sd_bus; 1769 uint32_t tmp; 1770 1771 /* PHY */ 1772 tmp = BWN_READ_2(mac, BWN_PHYVER); 1773 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1774 phy->rf_on = 1; 1775 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1776 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1777 phy->rev = (tmp & BWN_PHYVER_VERSION); 1778 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1779 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1780 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1781 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1782 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1783 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1784 goto unsupphy; 1785 1786 /* RADIO */ 1787 if (siba->siba_chipid == 0x4317) { 1788 if (siba->siba_chiprev == 0) 1789 tmp = 0x3205017f; 1790 else if (siba->siba_chiprev == 1) 1791 tmp = 0x4205017f; 1792 else 1793 tmp = 0x5205017f; 1794 } else { 1795 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1796 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1797 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1798 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1799 } 1800 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1801 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1802 phy->rf_manuf = (tmp & 0x00000fff); 1803 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1804 goto unsupradio; 1805 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1806 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1807 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1808 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1809 (phy->type == BWN_PHYTYPE_N && 1810 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1811 (phy->type == BWN_PHYTYPE_LP && 1812 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1813 goto unsupradio; 1814 1815 return (0); 1816unsupphy: 1817 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1818 "analog %#x)\n", 1819 phy->type, phy->rev, phy->analog); 1820 return (ENXIO); 1821unsupradio: 1822 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1823 "rev %#x)\n", 1824 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1825 return (ENXIO); 1826} 1827 1828static int 1829bwn_chiptest(struct bwn_mac *mac) 1830{ 1831#define TESTVAL0 0x55aaaa55 1832#define TESTVAL1 0xaa5555aa 1833 struct bwn_softc *sc = mac->mac_sc; 1834 struct siba_dev_softc *sd = mac->mac_sd; 1835 uint32_t v, backup; 1836 1837 BWN_LOCK(sc); 1838 1839 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1840 1841 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1842 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1843 goto error; 1844 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1845 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1846 goto error; 1847 1848 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1849 1850 if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) { 1851 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1852 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1853 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1854 goto error; 1855 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1856 goto error; 1857 } 1858 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1859 1860 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1861 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1862 goto error; 1863 1864 BWN_UNLOCK(sc); 1865 return (0); 1866error: 1867 BWN_UNLOCK(sc); 1868 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1869 return (ENODEV); 1870} 1871 1872#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1873#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1874 1875static int 1876bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1877{ 1878 struct bwn_softc *sc = mac->mac_sc; 1879 struct ifnet *ifp = sc->sc_ifp; 1880 struct ieee80211com *ic = ifp->if_l2com; 1881 1882 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1883 ic->ic_nchans = 0; 1884 1885 if (have_bg) 1886 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1887 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1888 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1889 if (have_a) 1890 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1891 &ic->ic_nchans, &bwn_chantable_n, 1892 IEEE80211_CHAN_HTA); 1893 } else { 1894 if (have_a) 1895 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1896 &ic->ic_nchans, &bwn_chantable_a, 1897 IEEE80211_CHAN_A); 1898 } 1899 1900 mac->mac_phy.supports_2ghz = have_bg; 1901 mac->mac_phy.supports_5ghz = have_a; 1902 1903 return (ic->ic_nchans == 0 ? ENXIO : 0); 1904} 1905 1906static uint32_t 1907bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1908{ 1909 uint32_t ret; 1910 1911 BWN_ASSERT_LOCKED(mac->mac_sc); 1912 1913 if (way == BWN_SHARED) { 1914 KASSERT((offset & 0x0001) == 0, 1915 ("%s:%d warn", __func__, __LINE__)); 1916 if (offset & 0x0003) { 1917 bwn_shm_ctlword(mac, way, offset >> 2); 1918 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1919 ret <<= 16; 1920 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1921 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1922 goto out; 1923 } 1924 offset >>= 2; 1925 } 1926 bwn_shm_ctlword(mac, way, offset); 1927 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1928out: 1929 return (ret); 1930} 1931 1932static uint16_t 1933bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1934{ 1935 uint16_t ret; 1936 1937 BWN_ASSERT_LOCKED(mac->mac_sc); 1938 1939 if (way == BWN_SHARED) { 1940 KASSERT((offset & 0x0001) == 0, 1941 ("%s:%d warn", __func__, __LINE__)); 1942 if (offset & 0x0003) { 1943 bwn_shm_ctlword(mac, way, offset >> 2); 1944 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1945 goto out; 1946 } 1947 offset >>= 2; 1948 } 1949 bwn_shm_ctlword(mac, way, offset); 1950 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1951out: 1952 1953 return (ret); 1954} 1955 1956static void 1957bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1958 uint16_t offset) 1959{ 1960 uint32_t control; 1961 1962 control = way; 1963 control <<= 16; 1964 control |= offset; 1965 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1966} 1967 1968static void 1969bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1970 uint32_t value) 1971{ 1972 BWN_ASSERT_LOCKED(mac->mac_sc); 1973 1974 if (way == BWN_SHARED) { 1975 KASSERT((offset & 0x0001) == 0, 1976 ("%s:%d warn", __func__, __LINE__)); 1977 if (offset & 0x0003) { 1978 bwn_shm_ctlword(mac, way, offset >> 2); 1979 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1980 (value >> 16) & 0xffff); 1981 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1982 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1983 return; 1984 } 1985 offset >>= 2; 1986 } 1987 bwn_shm_ctlword(mac, way, offset); 1988 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1989} 1990 1991static void 1992bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1993 uint16_t value) 1994{ 1995 BWN_ASSERT_LOCKED(mac->mac_sc); 1996 1997 if (way == BWN_SHARED) { 1998 KASSERT((offset & 0x0001) == 0, 1999 ("%s:%d warn", __func__, __LINE__)); 2000 if (offset & 0x0003) { 2001 bwn_shm_ctlword(mac, way, offset >> 2); 2002 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 2003 return; 2004 } 2005 offset >>= 2; 2006 } 2007 bwn_shm_ctlword(mac, way, offset); 2008 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 2009} 2010 2011static void 2012bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 2013 int txpow) 2014{ 2015 2016 c->ic_freq = freq; 2017 c->ic_flags = flags; 2018 c->ic_ieee = ieee; 2019 c->ic_minpower = 0; 2020 c->ic_maxpower = 2 * txpow; 2021 c->ic_maxregpower = txpow; 2022} 2023 2024static void 2025bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2026 const struct bwn_channelinfo *ci, int flags) 2027{ 2028 struct ieee80211_channel *c; 2029 int i; 2030 2031 c = &chans[*nchans]; 2032 2033 for (i = 0; i < ci->nchannels; i++) { 2034 const struct bwn_channel *hc; 2035 2036 hc = &ci->channels[i]; 2037 if (*nchans >= maxchans) 2038 break; 2039 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2040 c++, (*nchans)++; 2041 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2042 /* g channel have a separate b-only entry */ 2043 if (*nchans >= maxchans) 2044 break; 2045 c[0] = c[-1]; 2046 c[-1].ic_flags = IEEE80211_CHAN_B; 2047 c++, (*nchans)++; 2048 } 2049 if (flags == IEEE80211_CHAN_HTG) { 2050 /* HT g channel have a separate g-only entry */ 2051 if (*nchans >= maxchans) 2052 break; 2053 c[-1].ic_flags = IEEE80211_CHAN_G; 2054 c[0] = c[-1]; 2055 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2056 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2057 c++, (*nchans)++; 2058 } 2059 if (flags == IEEE80211_CHAN_HTA) { 2060 /* HT a channel have a separate a-only entry */ 2061 if (*nchans >= maxchans) 2062 break; 2063 c[-1].ic_flags = IEEE80211_CHAN_A; 2064 c[0] = c[-1]; 2065 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2066 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2067 c++, (*nchans)++; 2068 } 2069 } 2070} 2071 2072static int 2073bwn_phy_g_attach(struct bwn_mac *mac) 2074{ 2075 struct bwn_softc *sc = mac->mac_sc; 2076 struct bwn_phy *phy = &mac->mac_phy; 2077 struct bwn_phy_g *pg = &phy->phy_g; 2078 struct siba_dev_softc *sd = mac->mac_sd; 2079 struct siba_sprom *sprom = &sd->sd_bus->siba_sprom; 2080 unsigned int i; 2081 int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1), 2082 pab2 = (int16_t)(sprom->pa0b2); 2083 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2084 int8_t bg = (int8_t)sprom->tssi_bg; 2085 2086 if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050)) 2087 device_printf(sc->sc_dev, "not supported anymore\n"); 2088 2089 pg->pg_flags = 0; 2090 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2091 pab2 == -1) { 2092 pg->pg_idletssi = 52; 2093 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2094 return (0); 2095 } 2096 2097 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2098 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2099 if (pg->pg_tssi2dbm == NULL) { 2100 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2101 return (ENOMEM); 2102 } 2103 for (i = 0; i < 64; i++) { 2104 int32_t m1, m2, f, q, delta; 2105 int8_t j = 0; 2106 2107 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2108 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2109 f = 256; 2110 2111 do { 2112 if (j > 15) { 2113 device_printf(sc->sc_dev, 2114 "failed to generate tssi2dBm\n"); 2115 free(pg->pg_tssi2dbm, M_DEVBUF); 2116 return (ENOMEM); 2117 } 2118 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2119 f, 2048); 2120 delta = abs(q - f); 2121 f = q; 2122 j++; 2123 } while (delta >= 2); 2124 2125 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2126 128); 2127 } 2128 2129 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2130 return (0); 2131} 2132 2133static void 2134bwn_phy_g_detach(struct bwn_mac *mac) 2135{ 2136 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2137 2138 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2139 free(pg->pg_tssi2dbm, M_DEVBUF); 2140 pg->pg_tssi2dbm = NULL; 2141 } 2142 pg->pg_flags = 0; 2143} 2144 2145static void 2146bwn_phy_g_init_pre(struct bwn_mac *mac) 2147{ 2148 struct bwn_phy *phy = &mac->mac_phy; 2149 struct bwn_phy_g *pg = &phy->phy_g; 2150 void *tssi2dbm; 2151 int idletssi; 2152 unsigned int i; 2153 2154 tssi2dbm = pg->pg_tssi2dbm; 2155 idletssi = pg->pg_idletssi; 2156 2157 memset(pg, 0, sizeof(*pg)); 2158 2159 pg->pg_tssi2dbm = tssi2dbm; 2160 pg->pg_idletssi = idletssi; 2161 2162 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2163 2164 for (i = 0; i < N(pg->pg_nrssi); i++) 2165 pg->pg_nrssi[i] = -1000; 2166 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2167 pg->pg_nrssi_lt[i] = i; 2168 pg->pg_lofcal = 0xffff; 2169 pg->pg_initval = 0xffff; 2170 pg->pg_immode = BWN_IMMODE_NONE; 2171 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2172 pg->pg_avgtssi = 0xff; 2173 2174 pg->pg_loctl.tx_bias = 0xff; 2175 TAILQ_INIT(&pg->pg_loctl.calib_list); 2176} 2177 2178static int 2179bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2180{ 2181 struct bwn_phy *phy = &mac->mac_phy; 2182 struct bwn_phy_g *pg = &phy->phy_g; 2183 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2184 struct siba_softc *bus = mac->mac_sd->sd_bus; 2185 static const struct bwn_rfatt rfatt0[] = { 2186 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2187 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2188 { 3, 1 }, { 4, 1 } 2189 }; 2190 static const struct bwn_rfatt rfatt1[] = { 2191 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2192 { 14, 1 } 2193 }; 2194 static const struct bwn_rfatt rfatt2[] = { 2195 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2196 { 9, 1 } 2197 }; 2198 static const struct bwn_bbatt bbatt_0[] = { 2199 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2200 }; 2201 2202 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2203 2204 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2205 pg->pg_bbatt.att = 0; 2206 else 2207 pg->pg_bbatt.att = 2; 2208 2209 /* prepare Radio Attenuation */ 2210 pg->pg_rfatt.padmix = 0; 2211 2212 if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 2213 bus->siba_board_type == SIBA_BOARD_BCM4309G) { 2214 if (bus->siba_board_rev < 0x43) { 2215 pg->pg_rfatt.att = 2; 2216 goto done; 2217 } else if (bus->siba_board_rev < 0x51) { 2218 pg->pg_rfatt.att = 3; 2219 goto done; 2220 } 2221 } 2222 2223 if (phy->type == BWN_PHYTYPE_A) { 2224 pg->pg_rfatt.att = 0x60; 2225 goto done; 2226 } 2227 2228 switch (phy->rf_ver) { 2229 case 0x2050: 2230 switch (phy->rf_rev) { 2231 case 0: 2232 pg->pg_rfatt.att = 5; 2233 goto done; 2234 case 1: 2235 if (phy->type == BWN_PHYTYPE_G) { 2236 if (bus->siba_board_vendor == 2237 SIBA_BOARDVENDOR_BCM && 2238 bus->siba_board_type == 2239 SIBA_BOARD_BCM4309G && 2240 bus->siba_board_rev >= 30) 2241 pg->pg_rfatt.att = 3; 2242 else if (bus->siba_board_vendor == 2243 SIBA_BOARDVENDOR_BCM && 2244 bus->siba_board_type == SIBA_BOARD_BU4306) 2245 pg->pg_rfatt.att = 3; 2246 else 2247 pg->pg_rfatt.att = 1; 2248 } else { 2249 if (bus->siba_board_vendor == 2250 SIBA_BOARDVENDOR_BCM && 2251 bus->siba_board_type == 2252 SIBA_BOARD_BCM4309G && 2253 bus->siba_board_rev >= 30) 2254 pg->pg_rfatt.att = 7; 2255 else 2256 pg->pg_rfatt.att = 6; 2257 } 2258 goto done; 2259 case 2: 2260 if (phy->type == BWN_PHYTYPE_G) { 2261 if (bus->siba_board_vendor == 2262 SIBA_BOARDVENDOR_BCM && 2263 bus->siba_board_type == 2264 SIBA_BOARD_BCM4309G && 2265 bus->siba_board_rev >= 30) 2266 pg->pg_rfatt.att = 3; 2267 else if (bus->siba_board_vendor == 2268 SIBA_BOARDVENDOR_BCM && 2269 bus->siba_board_type == SIBA_BOARD_BU4306) 2270 pg->pg_rfatt.att = 5; 2271 else if (bus->siba_chipid == 0x4320) 2272 pg->pg_rfatt.att = 4; 2273 else 2274 pg->pg_rfatt.att = 3; 2275 } else 2276 pg->pg_rfatt.att = 6; 2277 goto done; 2278 case 3: 2279 pg->pg_rfatt.att = 5; 2280 goto done; 2281 case 4: 2282 case 5: 2283 pg->pg_rfatt.att = 1; 2284 goto done; 2285 case 6: 2286 case 7: 2287 pg->pg_rfatt.att = 5; 2288 goto done; 2289 case 8: 2290 pg->pg_rfatt.att = 0xa; 2291 pg->pg_rfatt.padmix = 1; 2292 goto done; 2293 case 9: 2294 default: 2295 pg->pg_rfatt.att = 5; 2296 goto done; 2297 } 2298 break; 2299 case 0x2053: 2300 switch (phy->rf_rev) { 2301 case 1: 2302 pg->pg_rfatt.att = 6; 2303 goto done; 2304 } 2305 break; 2306 } 2307 pg->pg_rfatt.att = 5; 2308done: 2309 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2310 2311 if (!bwn_has_hwpctl(mac)) { 2312 lo->rfatt.array = rfatt0; 2313 lo->rfatt.len = N(rfatt0); 2314 lo->rfatt.min = 0; 2315 lo->rfatt.max = 9; 2316 goto genbbatt; 2317 } 2318 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2319 lo->rfatt.array = rfatt1; 2320 lo->rfatt.len = N(rfatt1); 2321 lo->rfatt.min = 0; 2322 lo->rfatt.max = 14; 2323 goto genbbatt; 2324 } 2325 lo->rfatt.array = rfatt2; 2326 lo->rfatt.len = N(rfatt2); 2327 lo->rfatt.min = 0; 2328 lo->rfatt.max = 9; 2329genbbatt: 2330 lo->bbatt.array = bbatt_0; 2331 lo->bbatt.len = N(bbatt_0); 2332 lo->bbatt.min = 0; 2333 lo->bbatt.max = 8; 2334 2335 BWN_READ_4(mac, BWN_MACCTL); 2336 if (phy->rev == 1) { 2337 phy->gmode = 0; 2338 bwn_reset_core(mac, 0); 2339 bwn_phy_g_init_sub(mac); 2340 phy->gmode = 1; 2341 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2342 } 2343 return (0); 2344} 2345 2346static uint16_t 2347bwn_phy_g_txctl(struct bwn_mac *mac) 2348{ 2349 struct bwn_phy *phy = &mac->mac_phy; 2350 2351 if (phy->rf_ver != 0x2050) 2352 return (0); 2353 if (phy->rf_rev == 1) 2354 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2355 if (phy->rf_rev < 6) 2356 return (BWN_TXCTL_PA2DB); 2357 if (phy->rf_rev == 8) 2358 return (BWN_TXCTL_TXMIX); 2359 return (0); 2360} 2361 2362static int 2363bwn_phy_g_init(struct bwn_mac *mac) 2364{ 2365 2366 bwn_phy_g_init_sub(mac); 2367 return (0); 2368} 2369 2370static void 2371bwn_phy_g_exit(struct bwn_mac *mac) 2372{ 2373 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2374 struct bwn_lo_calib *cal, *tmp; 2375 2376 if (lo == NULL) 2377 return; 2378 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2379 TAILQ_REMOVE(&lo->calib_list, cal, list); 2380 free(cal, M_DEVBUF); 2381 } 2382} 2383 2384static uint16_t 2385bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2386{ 2387 2388 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2389 return (BWN_READ_2(mac, BWN_PHYDATA)); 2390} 2391 2392static void 2393bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2394{ 2395 2396 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2397 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2398} 2399 2400static uint16_t 2401bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2402{ 2403 2404 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2405 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2406 return (BWN_READ_2(mac, BWN_RFDATALO)); 2407} 2408 2409static void 2410bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2411{ 2412 2413 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2414 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2415 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2416} 2417 2418static int 2419bwn_phy_g_hwpctl(struct bwn_mac *mac) 2420{ 2421 2422 return (mac->mac_phy.rev >= 6); 2423} 2424 2425static void 2426bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2427{ 2428 struct bwn_phy *phy = &mac->mac_phy; 2429 struct bwn_phy_g *pg = &phy->phy_g; 2430 unsigned int channel; 2431 uint16_t rfover, rfoverval; 2432 2433 if (on) { 2434 if (phy->rf_on) 2435 return; 2436 2437 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2438 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2439 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2440 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2441 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2442 pg->pg_radioctx_over); 2443 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2444 pg->pg_radioctx_overval); 2445 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2446 } 2447 channel = phy->chan; 2448 bwn_phy_g_switch_chan(mac, 6, 1); 2449 bwn_phy_g_switch_chan(mac, channel, 0); 2450 return; 2451 } 2452 2453 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2454 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2455 pg->pg_radioctx_over = rfover; 2456 pg->pg_radioctx_overval = rfoverval; 2457 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2458 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2459 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2460} 2461 2462static int 2463bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2464{ 2465 2466 if ((newchan < 1) || (newchan > 14)) 2467 return (EINVAL); 2468 bwn_phy_g_switch_chan(mac, newchan, 0); 2469 2470 return (0); 2471} 2472 2473static uint32_t 2474bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2475{ 2476 2477 return (1); 2478} 2479 2480static void 2481bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2482{ 2483 struct bwn_phy *phy = &mac->mac_phy; 2484 uint64_t hf; 2485 int autodiv = 0; 2486 uint16_t tmp; 2487 2488 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2489 autodiv = 1; 2490 2491 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2492 bwn_hf_write(mac, hf); 2493 2494 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2495 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2496 ((autodiv ? BWN_ANTAUTO1 : antenna) 2497 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2498 2499 if (autodiv) { 2500 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2501 if (antenna == BWN_ANTAUTO1) 2502 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2503 else 2504 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2505 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2506 } 2507 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2508 if (autodiv) 2509 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2510 else 2511 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2512 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2513 if (phy->rev >= 2) { 2514 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2515 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2516 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2517 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2518 0x15); 2519 if (phy->rev == 2) 2520 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2521 else 2522 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2523 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2524 8); 2525 } 2526 if (phy->rev >= 6) 2527 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2528 2529 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2530 bwn_hf_write(mac, hf); 2531} 2532 2533static int 2534bwn_phy_g_im(struct bwn_mac *mac, int mode) 2535{ 2536 struct bwn_phy *phy = &mac->mac_phy; 2537 struct bwn_phy_g *pg = &phy->phy_g; 2538 2539 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2540 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2541 2542 if (phy->rev == 0 || !phy->gmode) 2543 return (ENODEV); 2544 2545 pg->pg_aci_wlan_automatic = 0; 2546 return (0); 2547} 2548 2549static int 2550bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2551{ 2552 struct bwn_phy *phy = &mac->mac_phy; 2553 struct bwn_phy_g *pg = &phy->phy_g; 2554 struct bwn_softc *sc = mac->mac_sc; 2555 struct siba_softc *siba = mac->mac_sd->sd_bus; 2556 unsigned int tssi; 2557 int cck, ofdm; 2558 int power; 2559 int rfatt, bbatt; 2560 unsigned int max; 2561 2562 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2563 2564 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2565 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2566 if (cck < 0 && ofdm < 0) { 2567 if (ignore_tssi == 0) 2568 return (BWN_TXPWR_RES_DONE); 2569 cck = 0; 2570 ofdm = 0; 2571 } 2572 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2573 if (pg->pg_avgtssi != 0xff) 2574 tssi = (tssi + pg->pg_avgtssi) / 2; 2575 pg->pg_avgtssi = tssi; 2576 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2577 2578 max = siba->siba_sprom.maxpwr_bg; 2579 if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL) 2580 max -= 3; 2581 if (max >= 120) { 2582 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2583 siba->siba_sprom.maxpwr_bg = max = 80; 2584 } 2585 2586 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2587 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2588 tssi, 0x00), 0x3f)]); 2589 if (power == 0) 2590 return (BWN_TXPWR_RES_DONE); 2591 2592 rfatt = -((power + 7) / 8); 2593 bbatt = (-(power / 2)) - (4 * rfatt); 2594 if ((rfatt == 0) && (bbatt == 0)) 2595 return (BWN_TXPWR_RES_DONE); 2596 pg->pg_bbatt_delta = bbatt; 2597 pg->pg_rfatt_delta = rfatt; 2598 return (BWN_TXPWR_RES_NEED_ADJUST); 2599} 2600 2601static void 2602bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2603{ 2604 struct bwn_phy *phy = &mac->mac_phy; 2605 struct bwn_phy_g *pg = &phy->phy_g; 2606 struct bwn_softc *sc = mac->mac_sc; 2607 int rfatt, bbatt; 2608 uint8_t txctl; 2609 2610 bwn_mac_suspend(mac); 2611 2612 BWN_ASSERT_LOCKED(sc); 2613 2614 bbatt = pg->pg_bbatt.att; 2615 bbatt += pg->pg_bbatt_delta; 2616 rfatt = pg->pg_rfatt.att; 2617 rfatt += pg->pg_rfatt_delta; 2618 2619 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2620 txctl = pg->pg_txctl; 2621 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2622 if (rfatt <= 1) { 2623 if (txctl == 0) { 2624 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2625 rfatt += 2; 2626 bbatt += 2; 2627 } else if (mac->mac_sd->sd_bus->siba_sprom. 2628 bf_lo & 2629 BWN_BFL_PACTRL) { 2630 bbatt += 4 * (rfatt - 2); 2631 rfatt = 2; 2632 } 2633 } else if (rfatt > 4 && txctl) { 2634 txctl = 0; 2635 if (bbatt < 3) { 2636 rfatt -= 3; 2637 bbatt += 2; 2638 } else { 2639 rfatt -= 2; 2640 bbatt -= 2; 2641 } 2642 } 2643 } 2644 pg->pg_txctl = txctl; 2645 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2646 pg->pg_rfatt.att = rfatt; 2647 pg->pg_bbatt.att = bbatt; 2648 2649 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2650 2651 bwn_phy_lock(mac); 2652 bwn_rf_lock(mac); 2653 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2654 pg->pg_txctl); 2655 bwn_rf_unlock(mac); 2656 bwn_phy_unlock(mac); 2657 2658 bwn_mac_enable(mac); 2659} 2660 2661static void 2662bwn_phy_g_task_15s(struct bwn_mac *mac) 2663{ 2664 struct bwn_phy *phy = &mac->mac_phy; 2665 struct bwn_phy_g *pg = &phy->phy_g; 2666 struct bwn_softc *sc = mac->mac_sc; 2667 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2668 unsigned long expire, now; 2669 struct bwn_lo_calib *cal, *tmp; 2670 uint8_t expired = 0; 2671 2672 bwn_mac_suspend(mac); 2673 2674 if (lo == NULL) 2675 goto fail; 2676 2677 BWN_GETTIME(now); 2678 if (bwn_has_hwpctl(mac)) { 2679 expire = now - BWN_LO_PWRVEC_EXPIRE; 2680 if (time_before(lo->pwr_vec_read_time, expire)) { 2681 bwn_lo_get_powervector(mac); 2682 bwn_phy_g_dc_lookup_init(mac, 0); 2683 } 2684 goto fail; 2685 } 2686 2687 expire = now - BWN_LO_CALIB_EXPIRE; 2688 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2689 if (!time_before(cal->calib_time, expire)) 2690 continue; 2691 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2692 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2693 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2694 expired = 1; 2695 } 2696 2697 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2698 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2699 cal->ctl.i, cal->ctl.q); 2700 2701 TAILQ_REMOVE(&lo->calib_list, cal, list); 2702 free(cal, M_DEVBUF); 2703 } 2704 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2705 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2706 &pg->pg_rfatt); 2707 if (cal == NULL) { 2708 device_printf(sc->sc_dev, 2709 "failed to recalibrate LO\n"); 2710 goto fail; 2711 } 2712 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2713 bwn_lo_write(mac, &cal->ctl); 2714 } 2715 2716fail: 2717 bwn_mac_enable(mac); 2718} 2719 2720static void 2721bwn_phy_g_task_60s(struct bwn_mac *mac) 2722{ 2723 struct bwn_phy *phy = &mac->mac_phy; 2724 uint8_t old = phy->chan; 2725 2726 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) 2727 return; 2728 2729 bwn_mac_suspend(mac); 2730 bwn_nrssi_slope_11g(mac); 2731 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2732 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2733 bwn_switch_channel(mac, old); 2734 } 2735 bwn_mac_enable(mac); 2736} 2737 2738static void 2739bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2740{ 2741 2742 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2743} 2744 2745static int 2746bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2747 const struct ieee80211_bpf_params *params) 2748{ 2749 struct ieee80211com *ic = ni->ni_ic; 2750 struct ifnet *ifp = ic->ic_ifp; 2751 struct bwn_softc *sc = ifp->if_softc; 2752 struct bwn_mac *mac = sc->sc_curmac; 2753 2754 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2755 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2756 ieee80211_free_node(ni); 2757 m_freem(m); 2758 return (ENETDOWN); 2759 } 2760 2761 BWN_LOCK(sc); 2762 if (bwn_tx_isfull(sc, m)) { 2763 ieee80211_free_node(ni); 2764 m_freem(m); 2765 ifp->if_oerrors++; 2766 BWN_UNLOCK(sc); 2767 return (ENOBUFS); 2768 } 2769 2770 if (bwn_tx_start(sc, ni, m) != 0) { 2771 if (ni != NULL) 2772 ieee80211_free_node(ni); 2773 ifp->if_oerrors++; 2774 } 2775 sc->sc_watchdog_timer = 5; 2776 BWN_UNLOCK(sc); 2777 return (0); 2778} 2779 2780/* 2781 * Setup driver-specific state for a newly associated node. 2782 * Note that we're called also on a re-associate, the isnew 2783 * param tells us if this is the first time or not. 2784 */ 2785static void 2786bwn_newassoc(struct ieee80211_node *ni, int isnew) 2787{ 2788 struct ieee80211vap *vap = ni->ni_vap; 2789 2790 ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr, 2791 &BWN_NODE(ni)->bn_amn, ni); 2792} 2793 2794/* 2795 * Callback from the 802.11 layer to update the slot time 2796 * based on the current setting. We use it to notify the 2797 * firmware of ERP changes and the f/w takes care of things 2798 * like slot time and preamble. 2799 */ 2800static void 2801bwn_updateslot(struct ifnet *ifp) 2802{ 2803 struct bwn_softc *sc = ifp->if_softc; 2804 struct ieee80211com *ic = ifp->if_l2com; 2805 struct bwn_mac *mac; 2806 2807 BWN_LOCK(sc); 2808 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2809 mac = (struct bwn_mac *)sc->sc_curmac; 2810 bwn_set_slot_time(mac, 2811 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2812 } 2813 BWN_UNLOCK(sc); 2814} 2815 2816/* 2817 * Callback from the 802.11 layer after a promiscuous mode change. 2818 * Note this interface does not check the operating mode as this 2819 * is an internal callback and we are expected to honor the current 2820 * state (e.g. this is used for setting the interface in promiscuous 2821 * mode when operating in hostap mode to do ACS). 2822 */ 2823static void 2824bwn_update_promisc(struct ifnet *ifp) 2825{ 2826 struct bwn_softc *sc = ifp->if_softc; 2827 struct bwn_mac *mac = sc->sc_curmac; 2828 2829 BWN_LOCK(sc); 2830 mac = sc->sc_curmac; 2831 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2832 if (ifp->if_flags & IFF_PROMISC) 2833 sc->sc_filters |= BWN_MACCTL_PROMISC; 2834 else 2835 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2836 bwn_set_opmode(mac); 2837 } 2838 BWN_UNLOCK(sc); 2839} 2840 2841/* 2842 * Callback from the 802.11 layer to update WME parameters. 2843 */ 2844static int 2845bwn_wme_update(struct ieee80211com *ic) 2846{ 2847 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2848 struct bwn_mac *mac = sc->sc_curmac; 2849 struct wmeParams *wmep; 2850 int i; 2851 2852 BWN_LOCK(sc); 2853 mac = sc->sc_curmac; 2854 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2855 bwn_mac_suspend(mac); 2856 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2857 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2858 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2859 } 2860 bwn_mac_enable(mac); 2861 } 2862 BWN_UNLOCK(sc); 2863 return (0); 2864} 2865 2866static struct ieee80211_node * 2867bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2868{ 2869 struct ieee80211com *ic = vap->iv_ic; 2870 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2871 const size_t space = sizeof(struct bwn_node); 2872 struct bwn_node *bn; 2873 2874 bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO); 2875 if (bn == NULL) { 2876 /* XXX stat+msg */ 2877 return (NULL); 2878 } 2879 DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn); 2880 return (&bn->bn_node); 2881} 2882 2883static void 2884bwn_node_cleanup(struct ieee80211_node *ni) 2885{ 2886 struct ieee80211com *ic = ni->ni_ic; 2887 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2888 2889 sc->sc_node_cleanup(ni); 2890} 2891 2892static void 2893bwn_scan_start(struct ieee80211com *ic) 2894{ 2895 struct ifnet *ifp = ic->ic_ifp; 2896 struct bwn_softc *sc = ifp->if_softc; 2897 struct bwn_mac *mac; 2898 2899 BWN_LOCK(sc); 2900 mac = sc->sc_curmac; 2901 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2902 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2903 bwn_set_opmode(mac); 2904 /* disable CFP update during scan */ 2905 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2906 } 2907 BWN_UNLOCK(sc); 2908} 2909 2910static void 2911bwn_scan_end(struct ieee80211com *ic) 2912{ 2913 struct ifnet *ifp = ic->ic_ifp; 2914 struct bwn_softc *sc = ifp->if_softc; 2915 struct bwn_mac *mac; 2916 2917 BWN_LOCK(sc); 2918 mac = sc->sc_curmac; 2919 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2920 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2921 bwn_set_opmode(mac); 2922 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2923 } 2924 BWN_UNLOCK(sc); 2925} 2926 2927static void 2928bwn_set_channel(struct ieee80211com *ic) 2929{ 2930 struct ifnet *ifp = ic->ic_ifp; 2931 struct bwn_softc *sc = ifp->if_softc; 2932 struct bwn_mac *mac = sc->sc_curmac; 2933 struct bwn_phy *phy = &mac->mac_phy; 2934 int chan, error; 2935 2936 BWN_LOCK(sc); 2937 2938 error = bwn_switch_band(sc, ic->ic_curchan); 2939 if (error) 2940 goto fail;; 2941 bwn_mac_suspend(mac); 2942 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2943 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2944 if (chan != phy->chan) 2945 bwn_switch_channel(mac, chan); 2946 2947 /* TX power level */ 2948 if (ic->ic_curchan->ic_maxpower != 0 && 2949 ic->ic_curchan->ic_maxpower != phy->txpower) { 2950 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2951 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2952 BWN_TXPWR_IGNORE_TSSI); 2953 } 2954 2955 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2956 if (phy->set_antenna) 2957 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2958 2959 if (sc->sc_rf_enabled != phy->rf_on) { 2960 if (sc->sc_rf_enabled) { 2961 bwn_rf_turnon(mac); 2962 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2963 device_printf(sc->sc_dev, 2964 "please turns on the RF switch\n"); 2965 } else 2966 bwn_rf_turnoff(mac); 2967 } 2968 2969 bwn_mac_enable(mac); 2970 2971fail: 2972 /* 2973 * Setup radio tap channel freq and flags 2974 */ 2975 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2976 htole16(ic->ic_curchan->ic_freq); 2977 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2978 htole16(ic->ic_curchan->ic_flags & 0xffff); 2979 2980 BWN_UNLOCK(sc); 2981} 2982 2983static struct ieee80211vap * 2984bwn_vap_create(struct ieee80211com *ic, 2985 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2986 const uint8_t bssid[IEEE80211_ADDR_LEN], 2987 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2988{ 2989 struct ifnet *ifp = ic->ic_ifp; 2990 struct bwn_softc *sc = ifp->if_softc; 2991 struct ieee80211vap *vap; 2992 struct bwn_vap *bvp; 2993 uint8_t mac[IEEE80211_ADDR_LEN]; 2994 2995 IEEE80211_ADDR_COPY(mac, mac0); 2996 switch (opmode) { 2997 case IEEE80211_M_HOSTAP: 2998 case IEEE80211_M_MBSS: 2999 case IEEE80211_M_STA: 3000 case IEEE80211_M_WDS: 3001 case IEEE80211_M_MONITOR: 3002 case IEEE80211_M_IBSS: 3003 case IEEE80211_M_AHDEMO: 3004 break; 3005 default: 3006 return (NULL); 3007 } 3008 3009 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 3010 3011 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 3012 M_80211_VAP, M_NOWAIT | M_ZERO); 3013 if (bvp == NULL) { 3014 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 3015 return (NULL); 3016 } 3017 vap = &bvp->bv_vap; 3018 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 3019 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 3020 /* override with driver methods */ 3021 bvp->bv_newstate = vap->iv_newstate; 3022 vap->iv_newstate = bwn_newstate; 3023 3024 /* override max aid so sta's cannot assoc when we're out of sta id's */ 3025 vap->iv_max_aid = BWN_STAID_MAX; 3026 3027 ieee80211_amrr_init(&bvp->bv_amrr, vap, 3028 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 3029 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 3030 500 /*ms*/); 3031 3032 /* complete setup */ 3033 ieee80211_vap_attach(vap, ieee80211_media_change, 3034 ieee80211_media_status); 3035 return (vap); 3036} 3037 3038static void 3039bwn_vap_delete(struct ieee80211vap *vap) 3040{ 3041 struct bwn_vap *bvp = BWN_VAP(vap); 3042 3043 ieee80211_amrr_cleanup(&bvp->bv_amrr); 3044 ieee80211_vap_detach(vap); 3045 free(bvp, M_80211_VAP); 3046} 3047 3048static void 3049bwn_init(void *arg) 3050{ 3051 struct bwn_softc *sc = arg; 3052 struct ifnet *ifp = sc->sc_ifp; 3053 struct ieee80211com *ic = ifp->if_l2com; 3054 int error = 0; 3055 3056 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3057 __func__, ifp->if_flags); 3058 3059 BWN_LOCK(sc); 3060 error = bwn_init_locked(sc); 3061 BWN_UNLOCK(sc); 3062 3063 if (error == 0) 3064 ieee80211_start_all(ic); /* start all vap's */ 3065} 3066 3067static int 3068bwn_init_locked(struct bwn_softc *sc) 3069{ 3070 struct bwn_mac *mac; 3071 struct ifnet *ifp = sc->sc_ifp; 3072 int error; 3073 3074 BWN_ASSERT_LOCKED(sc); 3075 3076 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3077 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3078 sc->sc_filters = 0; 3079 bwn_wme_clear(sc); 3080 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3081 sc->sc_rf_enabled = 1; 3082 3083 mac = sc->sc_curmac; 3084 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3085 error = bwn_core_init(mac); 3086 if (error != 0) 3087 return (error); 3088 } 3089 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3090 bwn_core_start(mac); 3091 3092 bwn_set_opmode(mac); 3093 bwn_set_pretbtt(mac); 3094 bwn_spu_setdelay(mac, 0); 3095 bwn_set_macaddr(mac); 3096 3097 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3098 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3099 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3100 3101 return (0); 3102} 3103 3104static void 3105bwn_stop(struct bwn_softc *sc, int statechg) 3106{ 3107 3108 BWN_LOCK(sc); 3109 bwn_stop_locked(sc, statechg); 3110 BWN_UNLOCK(sc); 3111} 3112 3113static void 3114bwn_stop_locked(struct bwn_softc *sc, int statechg) 3115{ 3116 struct bwn_mac *mac = sc->sc_curmac; 3117 struct ifnet *ifp = sc->sc_ifp; 3118 3119 BWN_ASSERT_LOCKED(sc); 3120 3121 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3122 /* XXX FIXME opmode not based on VAP */ 3123 bwn_set_opmode(mac); 3124 bwn_set_macaddr(mac); 3125 } 3126 3127 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3128 bwn_core_stop(mac); 3129 3130 callout_stop(&sc->sc_led_blink_ch); 3131 sc->sc_led_blinking = 0; 3132 3133 bwn_core_exit(mac); 3134 sc->sc_rf_enabled = 0; 3135 3136 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3137} 3138 3139static void 3140bwn_wme_clear(struct bwn_softc *sc) 3141{ 3142#define MS(_v, _f) (((_v) & _f) >> _f##_S) 3143 struct wmeParams *p; 3144 unsigned int i; 3145 3146 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3147 ("%s:%d: fail", __func__, __LINE__)); 3148 3149 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3150 p = &(sc->sc_wmeParams[i]); 3151 3152 switch (bwn_wme_shm_offsets[i]) { 3153 case BWN_WME_VOICE: 3154 p->wmep_txopLimit = 0; 3155 p->wmep_aifsn = 2; 3156 /* XXX FIXME: log2(cwmin) */ 3157 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3158 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3159 break; 3160 case BWN_WME_VIDEO: 3161 p->wmep_txopLimit = 0; 3162 p->wmep_aifsn = 2; 3163 /* XXX FIXME: log2(cwmin) */ 3164 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3165 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3166 break; 3167 case BWN_WME_BESTEFFORT: 3168 p->wmep_txopLimit = 0; 3169 p->wmep_aifsn = 3; 3170 /* XXX FIXME: log2(cwmin) */ 3171 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3172 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3173 break; 3174 case BWN_WME_BACKGROUND: 3175 p->wmep_txopLimit = 0; 3176 p->wmep_aifsn = 7; 3177 /* XXX FIXME: log2(cwmin) */ 3178 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3179 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3180 break; 3181 default: 3182 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3183 } 3184 } 3185} 3186 3187static int 3188bwn_core_init(struct bwn_mac *mac) 3189{ 3190#ifdef BWN_DEBUG 3191 struct bwn_softc *sc = mac->mac_sc; 3192#endif 3193 struct siba_dev_softc *sd = mac->mac_sd; 3194 struct siba_softc *siba = sd->sd_bus; 3195 struct siba_sprom *sprom = &siba->siba_sprom; 3196 uint64_t hf; 3197 int error; 3198 3199 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3200 ("%s:%d: fail", __func__, __LINE__)); 3201 3202 siba_powerup(siba, 0); 3203 if (!siba_dev_isup(sd)) 3204 bwn_reset_core(mac, 3205 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3206 3207 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3208 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3209 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3210 BWN_GETTIME(mac->mac_phy.nexttime); 3211 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3212 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3213 mac->mac_stats.link_noise = -95; 3214 mac->mac_reason_intr = 0; 3215 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3216 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3217#ifdef BWN_DEBUG 3218 if (sc->sc_debug & BWN_DEBUG_XMIT) 3219 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3220#endif 3221 mac->mac_suspended = 1; 3222 mac->mac_task_state = 0; 3223 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3224 3225 mac->mac_phy.init_pre(mac); 3226 3227 siba_pcicore_intr(&siba->siba_pci, sd); 3228 3229 bwn_fix_imcfglobug(mac); 3230 bwn_bt_disable(mac); 3231 if (mac->mac_phy.prepare_hw) { 3232 error = mac->mac_phy.prepare_hw(mac); 3233 if (error) 3234 goto fail0; 3235 } 3236 error = bwn_chip_init(mac); 3237 if (error) 3238 goto fail0; 3239 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3240 mac->mac_sd->sd_id.sd_rev); 3241 hf = bwn_hf_read(mac); 3242 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3243 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3244 if (sprom->bf_lo & BWN_BFL_PACTRL) 3245 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3246 if (mac->mac_phy.rev == 1) 3247 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3248 } 3249 if (mac->mac_phy.rf_ver == 0x2050) { 3250 if (mac->mac_phy.rf_rev < 6) 3251 hf |= BWN_HF_FORCE_VCO_RECALC; 3252 if (mac->mac_phy.rf_rev == 6) 3253 hf |= BWN_HF_4318_TSSI; 3254 } 3255 if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW) 3256 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3257 if ((siba->siba_type == SIBA_TYPE_PCI) && 3258 (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10)) 3259 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3260 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3261 bwn_hf_write(mac, hf); 3262 3263 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3264 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3265 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3266 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3267 3268 bwn_rate_init(mac); 3269 bwn_set_phytxctl(mac); 3270 3271 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3272 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3273 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3274 3275 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3276 bwn_pio_init(mac); 3277 else 3278 bwn_dma_init(mac); 3279 if (error) 3280 goto fail1; 3281 bwn_wme_init(mac); 3282 bwn_spu_setdelay(mac, 1); 3283 bwn_bt_enable(mac); 3284 3285 siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)); 3286 bwn_set_macaddr(mac); 3287 bwn_crypt_init(mac); 3288 3289 /* XXX LED initializatin */ 3290 3291 mac->mac_status = BWN_MAC_STATUS_INITED; 3292 3293 return (error); 3294 3295fail1: 3296 bwn_chip_exit(mac); 3297fail0: 3298 siba_powerdown(siba); 3299 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3300 ("%s:%d: fail", __func__, __LINE__)); 3301 return (error); 3302} 3303 3304static void 3305bwn_core_start(struct bwn_mac *mac) 3306{ 3307 struct bwn_softc *sc = mac->mac_sc; 3308 uint32_t tmp; 3309 3310 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3311 ("%s:%d: fail", __func__, __LINE__)); 3312 3313 if (mac->mac_sd->sd_id.sd_rev < 5) 3314 return; 3315 3316 while (1) { 3317 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3318 if (!(tmp & 0x00000001)) 3319 break; 3320 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3321 } 3322 3323 bwn_mac_enable(mac); 3324 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3325 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3326 3327 mac->mac_status = BWN_MAC_STATUS_STARTED; 3328} 3329 3330static void 3331bwn_core_exit(struct bwn_mac *mac) 3332{ 3333 uint32_t macctl; 3334 3335 BWN_ASSERT_LOCKED(mac->mac_sc); 3336 3337 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3338 ("%s:%d: fail", __func__, __LINE__)); 3339 3340 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3341 return; 3342 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3343 3344 macctl = BWN_READ_4(mac, BWN_MACCTL); 3345 macctl &= ~BWN_MACCTL_MCODE_RUN; 3346 macctl |= BWN_MACCTL_MCODE_JMP0; 3347 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3348 3349 bwn_dma_stop(mac); 3350 bwn_pio_stop(mac); 3351 bwn_chip_exit(mac); 3352 mac->mac_phy.switch_analog(mac, 0); 3353 siba_dev_down(mac->mac_sd, 0); 3354 siba_powerdown(mac->mac_sd->sd_bus); 3355} 3356 3357static void 3358bwn_fix_imcfglobug(struct bwn_mac *mac) 3359{ 3360 struct siba_dev_softc *sd = mac->mac_sd; 3361 struct siba_softc *siba = sd->sd_bus; 3362 uint32_t tmp; 3363 3364 if (siba->siba_pci.spc_dev == NULL) 3365 return; 3366 if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI || 3367 siba->siba_pci.spc_dev->sd_id.sd_rev > 5) 3368 return; 3369 3370 tmp = siba_read_4(sd, SIBA_IMCFGLO) & 3371 ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO); 3372 switch (siba->siba_type) { 3373 case SIBA_TYPE_PCI: 3374 case SIBA_TYPE_PCMCIA: 3375 tmp |= 0x32; 3376 break; 3377 case SIBA_TYPE_SSB: 3378 tmp |= 0x53; 3379 break; 3380 } 3381 siba_write_4(sd, SIBA_IMCFGLO, tmp); 3382} 3383 3384static void 3385bwn_bt_disable(struct bwn_mac *mac) 3386{ 3387 struct bwn_softc *sc = mac->mac_sc; 3388 3389 (void)sc; 3390 /* XXX do nothing yet */ 3391} 3392 3393static int 3394bwn_chip_init(struct bwn_mac *mac) 3395{ 3396 struct bwn_phy *phy = &mac->mac_phy; 3397 uint32_t macctl; 3398 int error; 3399 3400 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3401 if (phy->gmode) 3402 macctl |= BWN_MACCTL_GMODE; 3403 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3404 3405 error = bwn_fw_fillinfo(mac); 3406 if (error) 3407 return (error); 3408 error = bwn_fw_loaducode(mac); 3409 if (error) 3410 return (error); 3411 3412 error = bwn_gpio_init(mac); 3413 if (error) 3414 return (error); 3415 3416 error = bwn_fw_loadinitvals(mac); 3417 if (error) { 3418 bwn_gpio_cleanup(mac); 3419 return (error); 3420 } 3421 phy->switch_analog(mac, 1); 3422 error = bwn_phy_init(mac); 3423 if (error) { 3424 bwn_gpio_cleanup(mac); 3425 return (error); 3426 } 3427 if (phy->set_im) 3428 phy->set_im(mac, BWN_IMMODE_NONE); 3429 if (phy->set_antenna) 3430 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3431 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3432 3433 if (phy->type == BWN_PHYTYPE_B) 3434 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3435 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3436 if (mac->mac_sd->sd_id.sd_rev < 5) 3437 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3438 3439 BWN_WRITE_4(mac, BWN_MACCTL, 3440 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3441 BWN_WRITE_4(mac, BWN_MACCTL, 3442 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3443 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3444 3445 bwn_set_opmode(mac); 3446 if (mac->mac_sd->sd_id.sd_rev < 3) { 3447 BWN_WRITE_2(mac, 0x060e, 0x0000); 3448 BWN_WRITE_2(mac, 0x0610, 0x8000); 3449 BWN_WRITE_2(mac, 0x0604, 0x0000); 3450 BWN_WRITE_2(mac, 0x0606, 0x0200); 3451 } else { 3452 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3453 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3454 } 3455 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3456 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3457 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3458 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3459 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3460 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3461 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3462 siba_write_4(mac->mac_sd, SIBA_TGSLOW, 3463 siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000); 3464 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, 3465 mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay); 3466 return (error); 3467} 3468 3469/* read hostflags */ 3470static uint64_t 3471bwn_hf_read(struct bwn_mac *mac) 3472{ 3473 uint64_t ret; 3474 3475 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3476 ret <<= 16; 3477 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3478 ret <<= 16; 3479 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3480 return (ret); 3481} 3482 3483static void 3484bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3485{ 3486 3487 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3488 (value & 0x00000000ffffull)); 3489 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3490 (value & 0x0000ffff0000ull) >> 16); 3491 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3492 (value & 0xffff00000000ULL) >> 32); 3493} 3494 3495static void 3496bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3497{ 3498 3499 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3500 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3501} 3502 3503static void 3504bwn_rate_init(struct bwn_mac *mac) 3505{ 3506 3507 switch (mac->mac_phy.type) { 3508 case BWN_PHYTYPE_A: 3509 case BWN_PHYTYPE_G: 3510 case BWN_PHYTYPE_LP: 3511 case BWN_PHYTYPE_N: 3512 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3513 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3514 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3515 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3516 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3517 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3518 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3519 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3520 break; 3521 /* FALLTHROUGH */ 3522 case BWN_PHYTYPE_B: 3523 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3524 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3525 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3526 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3527 break; 3528 default: 3529 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3530 } 3531} 3532 3533static void 3534bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3535{ 3536 uint16_t offset; 3537 3538 if (ofdm) { 3539 offset = 0x480; 3540 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3541 } else { 3542 offset = 0x4c0; 3543 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3544 } 3545 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3546 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3547} 3548 3549static uint8_t 3550bwn_plcp_getcck(const uint8_t bitrate) 3551{ 3552 3553 switch (bitrate) { 3554 case BWN_CCK_RATE_1MB: 3555 return (0x0a); 3556 case BWN_CCK_RATE_2MB: 3557 return (0x14); 3558 case BWN_CCK_RATE_5MB: 3559 return (0x37); 3560 case BWN_CCK_RATE_11MB: 3561 return (0x6e); 3562 } 3563 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3564 return (0); 3565} 3566 3567static uint8_t 3568bwn_plcp_getofdm(const uint8_t bitrate) 3569{ 3570 3571 switch (bitrate) { 3572 case BWN_OFDM_RATE_6MB: 3573 return (0xb); 3574 case BWN_OFDM_RATE_9MB: 3575 return (0xf); 3576 case BWN_OFDM_RATE_12MB: 3577 return (0xa); 3578 case BWN_OFDM_RATE_18MB: 3579 return (0xe); 3580 case BWN_OFDM_RATE_24MB: 3581 return (0x9); 3582 case BWN_OFDM_RATE_36MB: 3583 return (0xd); 3584 case BWN_OFDM_RATE_48MB: 3585 return (0x8); 3586 case BWN_OFDM_RATE_54MB: 3587 return (0xc); 3588 } 3589 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3590 return (0); 3591} 3592 3593static void 3594bwn_set_phytxctl(struct bwn_mac *mac) 3595{ 3596 uint16_t ctl; 3597 3598 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3599 BWN_TX_PHY_TXPWR); 3600 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3601 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3602 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3603} 3604 3605static void 3606bwn_pio_init(struct bwn_mac *mac) 3607{ 3608 struct bwn_pio *pio = &mac->mac_method.pio; 3609 3610 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3611 & ~BWN_MACCTL_BIGENDIAN); 3612 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3613 3614 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3615 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3616 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3617 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3618 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3619 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3620} 3621 3622static void 3623bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3624 int index) 3625{ 3626 struct bwn_pio_txpkt *tp; 3627 unsigned int i; 3628 3629 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3630 tq->tq_index = index; 3631 3632 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3633 if (mac->mac_sd->sd_id.sd_rev >= 8) 3634 tq->tq_size = 1920; 3635 else { 3636 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3637 tq->tq_size -= 80; 3638 } 3639 3640 TAILQ_INIT(&tq->tq_pktlist); 3641 for (i = 0; i < N(tq->tq_pkts); i++) { 3642 tp = &(tq->tq_pkts[i]); 3643 tp->tp_index = i; 3644 tp->tp_queue = tq; 3645 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3646 } 3647} 3648 3649static uint16_t 3650bwn_pio_idx2base(struct bwn_mac *mac, int index) 3651{ 3652 struct bwn_softc *sc = mac->mac_sc; 3653 static const uint16_t bases[] = { 3654 BWN_PIO_BASE0, 3655 BWN_PIO_BASE1, 3656 BWN_PIO_BASE2, 3657 BWN_PIO_BASE3, 3658 BWN_PIO_BASE4, 3659 BWN_PIO_BASE5, 3660 BWN_PIO_BASE6, 3661 BWN_PIO_BASE7, 3662 }; 3663 static const uint16_t bases_rev11[] = { 3664 BWN_PIO11_BASE0, 3665 BWN_PIO11_BASE1, 3666 BWN_PIO11_BASE2, 3667 BWN_PIO11_BASE3, 3668 BWN_PIO11_BASE4, 3669 BWN_PIO11_BASE5, 3670 }; 3671 3672 if (mac->mac_sd->sd_id.sd_rev >= 11) { 3673 if (index >= N(bases_rev11)) 3674 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3675 return (bases_rev11[index]); 3676 } 3677 if (index >= N(bases)) 3678 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3679 return (bases[index]); 3680} 3681 3682static void 3683bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3684 int index) 3685{ 3686 3687 prq->prq_mac = mac; 3688 prq->prq_rev = mac->mac_sd->sd_id.sd_rev; 3689 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3690 bwn_dma_rxdirectfifo(mac, index, 1); 3691} 3692 3693static void 3694bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3695{ 3696 if (tq == NULL) 3697 return; 3698 bwn_pio_cancel_tx_packets(tq); 3699} 3700 3701static void 3702bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3703{ 3704 3705 bwn_destroy_pioqueue_tx(pio); 3706} 3707 3708static uint16_t 3709bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3710 uint16_t offset) 3711{ 3712 3713 return (BWN_READ_2(mac, tq->tq_base + offset)); 3714} 3715 3716static void 3717bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3718{ 3719 uint32_t ctl; 3720 int type; 3721 uint16_t base; 3722 3723 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3724 base = bwn_dma_base(type, idx); 3725 if (type == BWN_DMA_64BIT) { 3726 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3727 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3728 if (enable) 3729 ctl |= BWN_DMA64_RXDIRECTFIFO; 3730 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3731 } else { 3732 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3733 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3734 if (enable) 3735 ctl |= BWN_DMA32_RXDIRECTFIFO; 3736 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3737 } 3738} 3739 3740static uint64_t 3741bwn_dma_mask(struct bwn_mac *mac) 3742{ 3743 uint32_t tmp; 3744 uint16_t base; 3745 3746 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3747 if (tmp & SIBA_TGSHIGH_DMA64) 3748 return (BWN_DMA_BIT_MASK(64)); 3749 base = bwn_dma_base(0, 0); 3750 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3751 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3752 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3753 return (BWN_DMA_BIT_MASK(32)); 3754 3755 return (BWN_DMA_BIT_MASK(30)); 3756} 3757 3758static int 3759bwn_dma_mask2type(uint64_t dmamask) 3760{ 3761 3762 if (dmamask == BWN_DMA_BIT_MASK(30)) 3763 return (BWN_DMA_30BIT); 3764 if (dmamask == BWN_DMA_BIT_MASK(32)) 3765 return (BWN_DMA_32BIT); 3766 if (dmamask == BWN_DMA_BIT_MASK(64)) 3767 return (BWN_DMA_64BIT); 3768 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3769 return (BWN_DMA_30BIT); 3770} 3771 3772static void 3773bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3774{ 3775 struct bwn_pio_txpkt *tp; 3776 unsigned int i; 3777 3778 for (i = 0; i < N(tq->tq_pkts); i++) { 3779 tp = &(tq->tq_pkts[i]); 3780 if (tp->tp_m) { 3781 m_freem(tp->tp_m); 3782 tp->tp_m = NULL; 3783 } 3784 } 3785} 3786 3787static uint16_t 3788bwn_dma_base(int type, int controller_idx) 3789{ 3790 static const uint16_t map64[] = { 3791 BWN_DMA64_BASE0, 3792 BWN_DMA64_BASE1, 3793 BWN_DMA64_BASE2, 3794 BWN_DMA64_BASE3, 3795 BWN_DMA64_BASE4, 3796 BWN_DMA64_BASE5, 3797 }; 3798 static const uint16_t map32[] = { 3799 BWN_DMA32_BASE0, 3800 BWN_DMA32_BASE1, 3801 BWN_DMA32_BASE2, 3802 BWN_DMA32_BASE3, 3803 BWN_DMA32_BASE4, 3804 BWN_DMA32_BASE5, 3805 }; 3806 3807 if (type == BWN_DMA_64BIT) { 3808 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3809 ("%s:%d: fail", __func__, __LINE__)); 3810 return (map64[controller_idx]); 3811 } 3812 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3813 ("%s:%d: fail", __func__, __LINE__)); 3814 return (map32[controller_idx]); 3815} 3816 3817static void 3818bwn_dma_init(struct bwn_mac *mac) 3819{ 3820 struct bwn_dma *dma = &mac->mac_method.dma; 3821 3822 /* setup TX DMA channels. */ 3823 bwn_dma_setup(dma->wme[WME_AC_BK]); 3824 bwn_dma_setup(dma->wme[WME_AC_BE]); 3825 bwn_dma_setup(dma->wme[WME_AC_VI]); 3826 bwn_dma_setup(dma->wme[WME_AC_VO]); 3827 bwn_dma_setup(dma->mcast); 3828 /* setup RX DMA channel. */ 3829 bwn_dma_setup(dma->rx); 3830} 3831 3832static struct bwn_dma_ring * 3833bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3834 int for_tx, int type) 3835{ 3836 struct bwn_dma *dma = &mac->mac_method.dma; 3837 struct bwn_dma_ring *dr; 3838 struct bwn_dmadesc_generic *desc; 3839 struct bwn_dmadesc_meta *mt; 3840 struct bwn_softc *sc = mac->mac_sc; 3841 int error, i; 3842 3843 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3844 if (dr == NULL) 3845 goto out; 3846 dr->dr_numslots = BWN_RXRING_SLOTS; 3847 if (for_tx) 3848 dr->dr_numslots = BWN_TXRING_SLOTS; 3849 3850 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3851 M_DEVBUF, M_NOWAIT | M_ZERO); 3852 if (dr->dr_meta == NULL) 3853 goto fail0; 3854 3855 dr->dr_type = type; 3856 dr->dr_mac = mac; 3857 dr->dr_base = bwn_dma_base(type, controller_index); 3858 dr->dr_index = controller_index; 3859 if (type == BWN_DMA_64BIT) { 3860 dr->getdesc = bwn_dma_64_getdesc; 3861 dr->setdesc = bwn_dma_64_setdesc; 3862 dr->start_transfer = bwn_dma_64_start_transfer; 3863 dr->suspend = bwn_dma_64_suspend; 3864 dr->resume = bwn_dma_64_resume; 3865 dr->get_curslot = bwn_dma_64_get_curslot; 3866 dr->set_curslot = bwn_dma_64_set_curslot; 3867 } else { 3868 dr->getdesc = bwn_dma_32_getdesc; 3869 dr->setdesc = bwn_dma_32_setdesc; 3870 dr->start_transfer = bwn_dma_32_start_transfer; 3871 dr->suspend = bwn_dma_32_suspend; 3872 dr->resume = bwn_dma_32_resume; 3873 dr->get_curslot = bwn_dma_32_get_curslot; 3874 dr->set_curslot = bwn_dma_32_set_curslot; 3875 } 3876 if (for_tx) { 3877 dr->dr_tx = 1; 3878 dr->dr_curslot = -1; 3879 } else { 3880 if (dr->dr_index == 0) { 3881 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3882 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3883 } else 3884 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3885 } 3886 3887 error = bwn_dma_allocringmemory(dr); 3888 if (error) 3889 goto fail2; 3890 3891 if (for_tx) { 3892 /* 3893 * Assumption: BWN_TXRING_SLOTS can be divided by 3894 * BWN_TX_SLOTS_PER_FRAME 3895 */ 3896 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3897 ("%s:%d: fail", __func__, __LINE__)); 3898 3899 dr->dr_txhdr_cache = 3900 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3901 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3902 KASSERT(dr->dr_txhdr_cache != NULL, 3903 ("%s:%d: fail", __func__, __LINE__)); 3904 3905 /* 3906 * Create TX ring DMA stuffs 3907 */ 3908 error = bus_dma_tag_create(dma->parent_dtag, 3909 BWN_ALIGN, 0, 3910 BUS_SPACE_MAXADDR, 3911 BUS_SPACE_MAXADDR, 3912 NULL, NULL, 3913 BWN_HDRSIZE(mac), 3914 1, 3915 BUS_SPACE_MAXSIZE_32BIT, 3916 0, 3917 NULL, NULL, 3918 &dr->dr_txring_dtag); 3919 if (error) { 3920 device_printf(sc->sc_dev, 3921 "can't create TX ring DMA tag: TODO frees\n"); 3922 goto fail1; 3923 } 3924 3925 for (i = 0; i < dr->dr_numslots; i += 2) { 3926 dr->getdesc(dr, i, &desc, &mt); 3927 3928 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3929 mt->mt_m = NULL; 3930 mt->mt_ni = NULL; 3931 mt->mt_islast = 0; 3932 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3933 &mt->mt_dmap); 3934 if (error) { 3935 device_printf(sc->sc_dev, 3936 "can't create RX buf DMA map\n"); 3937 goto fail1; 3938 } 3939 3940 dr->getdesc(dr, i + 1, &desc, &mt); 3941 3942 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3943 mt->mt_m = NULL; 3944 mt->mt_ni = NULL; 3945 mt->mt_islast = 1; 3946 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3947 &mt->mt_dmap); 3948 if (error) { 3949 device_printf(sc->sc_dev, 3950 "can't create RX buf DMA map\n"); 3951 goto fail1; 3952 } 3953 } 3954 } else { 3955 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3956 &dr->dr_spare_dmap); 3957 if (error) { 3958 device_printf(sc->sc_dev, 3959 "can't create RX buf DMA map\n"); 3960 goto out; /* XXX wrong! */ 3961 } 3962 3963 for (i = 0; i < dr->dr_numslots; i++) { 3964 dr->getdesc(dr, i, &desc, &mt); 3965 3966 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3967 &mt->mt_dmap); 3968 if (error) { 3969 device_printf(sc->sc_dev, 3970 "can't create RX buf DMA map\n"); 3971 goto out; /* XXX wrong! */ 3972 } 3973 error = bwn_dma_newbuf(dr, desc, mt, 1); 3974 if (error) { 3975 device_printf(sc->sc_dev, 3976 "failed to allocate RX buf\n"); 3977 goto out; /* XXX wrong! */ 3978 } 3979 } 3980 3981 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3982 BUS_DMASYNC_PREWRITE); 3983 3984 dr->dr_usedslot = dr->dr_numslots; 3985 } 3986 3987 out: 3988 return (dr); 3989 3990fail2: 3991 free(dr->dr_txhdr_cache, M_DEVBUF); 3992fail1: 3993 free(dr->dr_meta, M_DEVBUF); 3994fail0: 3995 free(dr, M_DEVBUF); 3996 return (NULL); 3997} 3998 3999static void 4000bwn_dma_ringfree(struct bwn_dma_ring **dr) 4001{ 4002 4003 if (dr == NULL) 4004 return; 4005 4006 bwn_dma_free_descbufs(*dr); 4007 bwn_dma_free_ringmemory(*dr); 4008 4009 free((*dr)->dr_txhdr_cache, M_DEVBUF); 4010 free((*dr)->dr_meta, M_DEVBUF); 4011 free(*dr, M_DEVBUF); 4012 4013 *dr = NULL; 4014} 4015 4016static void 4017bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 4018 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4019{ 4020 struct bwn_dmadesc32 *desc; 4021 4022 *meta = &(dr->dr_meta[slot]); 4023 desc = dr->dr_ring_descbase; 4024 desc = &(desc[slot]); 4025 4026 *gdesc = (struct bwn_dmadesc_generic *)desc; 4027} 4028 4029static void 4030bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 4031 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4032 int start, int end, int irq) 4033{ 4034 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 4035 uint32_t addr, addrext, ctl; 4036 int slot; 4037 4038 slot = (int)(&(desc->dma.dma32) - descbase); 4039 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4040 ("%s:%d: fail", __func__, __LINE__)); 4041 4042 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 4043 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 4044 addr |= siba_dma_translation(dr->dr_mac->mac_sd); 4045 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 4046 if (slot == dr->dr_numslots - 1) 4047 ctl |= BWN_DMA32_DCTL_DTABLEEND; 4048 if (start) 4049 ctl |= BWN_DMA32_DCTL_FRAMESTART; 4050 if (end) 4051 ctl |= BWN_DMA32_DCTL_FRAMEEND; 4052 if (irq) 4053 ctl |= BWN_DMA32_DCTL_IRQ; 4054 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 4055 & BWN_DMA32_DCTL_ADDREXT_MASK; 4056 4057 desc->dma.dma32.control = htole32(ctl); 4058 desc->dma.dma32.address = htole32(addr); 4059} 4060 4061static void 4062bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 4063{ 4064 4065 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 4066 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 4067} 4068 4069static void 4070bwn_dma_32_suspend(struct bwn_dma_ring *dr) 4071{ 4072 4073 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4074 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 4075} 4076 4077static void 4078bwn_dma_32_resume(struct bwn_dma_ring *dr) 4079{ 4080 4081 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 4082 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 4083} 4084 4085static int 4086bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4087{ 4088 uint32_t val; 4089 4090 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4091 val &= BWN_DMA32_RXDPTR; 4092 4093 return (val / sizeof(struct bwn_dmadesc32)); 4094} 4095 4096static void 4097bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4098{ 4099 4100 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4101 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4102} 4103 4104static void 4105bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4106 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4107{ 4108 struct bwn_dmadesc64 *desc; 4109 4110 *meta = &(dr->dr_meta[slot]); 4111 desc = dr->dr_ring_descbase; 4112 desc = &(desc[slot]); 4113 4114 *gdesc = (struct bwn_dmadesc_generic *)desc; 4115} 4116 4117static void 4118bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4119 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4120 int start, int end, int irq) 4121{ 4122 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4123 int slot; 4124 uint32_t ctl0 = 0, ctl1 = 0; 4125 uint32_t addrlo, addrhi; 4126 uint32_t addrext; 4127 4128 slot = (int)(&(desc->dma.dma64) - descbase); 4129 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4130 ("%s:%d: fail", __func__, __LINE__)); 4131 4132 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4133 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4134 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4135 30; 4136 addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1); 4137 if (slot == dr->dr_numslots - 1) 4138 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4139 if (start) 4140 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4141 if (end) 4142 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4143 if (irq) 4144 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4145 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4146 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4147 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4148 4149 desc->dma.dma64.control0 = htole32(ctl0); 4150 desc->dma.dma64.control1 = htole32(ctl1); 4151 desc->dma.dma64.address_low = htole32(addrlo); 4152 desc->dma.dma64.address_high = htole32(addrhi); 4153} 4154 4155static void 4156bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4157{ 4158 4159 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4160 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4161} 4162 4163static void 4164bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4165{ 4166 4167 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4168 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4169} 4170 4171static void 4172bwn_dma_64_resume(struct bwn_dma_ring *dr) 4173{ 4174 4175 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4176 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4177} 4178 4179static int 4180bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4181{ 4182 uint32_t val; 4183 4184 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4185 val &= BWN_DMA64_RXSTATDPTR; 4186 4187 return (val / sizeof(struct bwn_dmadesc64)); 4188} 4189 4190static void 4191bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4192{ 4193 4194 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4195 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4196} 4197 4198static int 4199bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4200{ 4201 struct bwn_mac *mac = dr->dr_mac; 4202 struct bwn_dma *dma = &mac->mac_method.dma; 4203 struct bwn_softc *sc = mac->mac_sc; 4204 int error; 4205 4206 error = bus_dma_tag_create(dma->parent_dtag, 4207 BWN_ALIGN, 0, 4208 BUS_SPACE_MAXADDR, 4209 BUS_SPACE_MAXADDR, 4210 NULL, NULL, 4211 BWN_DMA_RINGMEMSIZE, 4212 1, 4213 BUS_SPACE_MAXSIZE_32BIT, 4214 0, 4215 NULL, NULL, 4216 &dr->dr_ring_dtag); 4217 if (error) { 4218 device_printf(sc->sc_dev, 4219 "can't create TX ring DMA tag: TODO frees\n"); 4220 return (-1); 4221 } 4222 4223 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4224 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4225 &dr->dr_ring_dmap); 4226 if (error) { 4227 device_printf(sc->sc_dev, 4228 "can't allocate DMA mem: TODO frees\n"); 4229 return (-1); 4230 } 4231 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4232 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4233 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4234 if (error) { 4235 device_printf(sc->sc_dev, 4236 "can't load DMA mem: TODO free\n"); 4237 return (-1); 4238 } 4239 4240 return (0); 4241} 4242 4243static void 4244bwn_dma_setup(struct bwn_dma_ring *dr) 4245{ 4246 uint64_t ring64; 4247 uint32_t addrext, ring32, value; 4248 uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd); 4249 4250 if (dr->dr_tx) { 4251 dr->dr_curslot = -1; 4252 4253 if (dr->dr_type == BWN_DMA_64BIT) { 4254 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4255 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4256 >> 30; 4257 value = BWN_DMA64_TXENABLE; 4258 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4259 & BWN_DMA64_TXADDREXT_MASK; 4260 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4261 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4262 (ring64 & 0xffffffff)); 4263 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4264 ((ring64 >> 32) & 4265 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4266 } else { 4267 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4268 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4269 value = BWN_DMA32_TXENABLE; 4270 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4271 & BWN_DMA32_TXADDREXT_MASK; 4272 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4273 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4274 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4275 } 4276 return; 4277 } 4278 4279 /* 4280 * set for RX 4281 */ 4282 dr->dr_usedslot = dr->dr_numslots; 4283 4284 if (dr->dr_type == BWN_DMA_64BIT) { 4285 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4286 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4287 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4288 value |= BWN_DMA64_RXENABLE; 4289 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4290 & BWN_DMA64_RXADDREXT_MASK; 4291 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4292 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4293 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4294 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4295 | (trans << 1)); 4296 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4297 sizeof(struct bwn_dmadesc64)); 4298 } else { 4299 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4300 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4301 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4302 value |= BWN_DMA32_RXENABLE; 4303 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4304 & BWN_DMA32_RXADDREXT_MASK; 4305 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4306 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4307 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4308 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4309 sizeof(struct bwn_dmadesc32)); 4310 } 4311} 4312 4313static void 4314bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4315{ 4316 4317 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4318 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4319 dr->dr_ring_dmap); 4320} 4321 4322static void 4323bwn_dma_cleanup(struct bwn_dma_ring *dr) 4324{ 4325 4326 if (dr->dr_tx) { 4327 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4328 if (dr->dr_type == BWN_DMA_64BIT) { 4329 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4330 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4331 } else 4332 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4333 } else { 4334 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4335 if (dr->dr_type == BWN_DMA_64BIT) { 4336 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4337 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4338 } else 4339 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4340 } 4341} 4342 4343static void 4344bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4345{ 4346 struct bwn_dmadesc_generic *desc; 4347 struct bwn_dmadesc_meta *meta; 4348 struct bwn_mac *mac = dr->dr_mac; 4349 struct bwn_dma *dma = &mac->mac_method.dma; 4350 struct bwn_softc *sc = mac->mac_sc; 4351 int i; 4352 4353 if (!dr->dr_usedslot) 4354 return; 4355 for (i = 0; i < dr->dr_numslots; i++) { 4356 dr->getdesc(dr, i, &desc, &meta); 4357 4358 if (meta->mt_m == NULL) { 4359 if (!dr->dr_tx) 4360 device_printf(sc->sc_dev, "%s: not TX?\n", 4361 __func__); 4362 continue; 4363 } 4364 if (dr->dr_tx) { 4365 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4366 bus_dmamap_unload(dr->dr_txring_dtag, 4367 meta->mt_dmap); 4368 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4369 bus_dmamap_unload(dma->txbuf_dtag, 4370 meta->mt_dmap); 4371 } else 4372 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4373 bwn_dma_free_descbuf(dr, meta); 4374 } 4375} 4376 4377static int 4378bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4379 int type) 4380{ 4381 struct bwn_softc *sc = mac->mac_sc; 4382 uint32_t value; 4383 int i; 4384 uint16_t offset; 4385 4386 for (i = 0; i < 10; i++) { 4387 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4388 BWN_DMA32_TXSTATUS; 4389 value = BWN_READ_4(mac, base + offset); 4390 if (type == BWN_DMA_64BIT) { 4391 value &= BWN_DMA64_TXSTAT; 4392 if (value == BWN_DMA64_TXSTAT_DISABLED || 4393 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4394 value == BWN_DMA64_TXSTAT_STOPPED) 4395 break; 4396 } else { 4397 value &= BWN_DMA32_TXSTATE; 4398 if (value == BWN_DMA32_TXSTAT_DISABLED || 4399 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4400 value == BWN_DMA32_TXSTAT_STOPPED) 4401 break; 4402 } 4403 DELAY(1000); 4404 } 4405 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4406 BWN_WRITE_4(mac, base + offset, 0); 4407 for (i = 0; i < 10; i++) { 4408 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4409 BWN_DMA32_TXSTATUS; 4410 value = BWN_READ_4(mac, base + offset); 4411 if (type == BWN_DMA_64BIT) { 4412 value &= BWN_DMA64_TXSTAT; 4413 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4414 i = -1; 4415 break; 4416 } 4417 } else { 4418 value &= BWN_DMA32_TXSTATE; 4419 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4420 i = -1; 4421 break; 4422 } 4423 } 4424 DELAY(1000); 4425 } 4426 if (i != -1) { 4427 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4428 return (ENODEV); 4429 } 4430 DELAY(1000); 4431 4432 return (0); 4433} 4434 4435static int 4436bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4437 int type) 4438{ 4439 struct bwn_softc *sc = mac->mac_sc; 4440 uint32_t value; 4441 int i; 4442 uint16_t offset; 4443 4444 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4445 BWN_WRITE_4(mac, base + offset, 0); 4446 for (i = 0; i < 10; i++) { 4447 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4448 BWN_DMA32_RXSTATUS; 4449 value = BWN_READ_4(mac, base + offset); 4450 if (type == BWN_DMA_64BIT) { 4451 value &= BWN_DMA64_RXSTAT; 4452 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4453 i = -1; 4454 break; 4455 } 4456 } else { 4457 value &= BWN_DMA32_RXSTATE; 4458 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4459 i = -1; 4460 break; 4461 } 4462 } 4463 DELAY(1000); 4464 } 4465 if (i != -1) { 4466 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4467 return (ENODEV); 4468 } 4469 4470 return (0); 4471} 4472 4473static void 4474bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4475 struct bwn_dmadesc_meta *meta) 4476{ 4477 4478 if (meta->mt_m != NULL) { 4479 m_freem(meta->mt_m); 4480 meta->mt_m = NULL; 4481 } 4482 if (meta->mt_ni != NULL) { 4483 ieee80211_free_node(meta->mt_ni); 4484 meta->mt_ni = NULL; 4485 } 4486} 4487 4488static void 4489bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4490{ 4491 struct bwn_rxhdr4 *rxhdr; 4492 unsigned char *frame; 4493 4494 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4495 rxhdr->frame_len = 0; 4496 4497 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4498 sizeof(struct bwn_plcp6) + 2, 4499 ("%s:%d: fail", __func__, __LINE__)); 4500 frame = mtod(m, char *) + dr->dr_frameoffset; 4501 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4502} 4503 4504static uint8_t 4505bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4506{ 4507 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4508 4509 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4510 == 0xff); 4511} 4512 4513static void 4514bwn_wme_init(struct bwn_mac *mac) 4515{ 4516 4517 bwn_wme_load(mac); 4518 4519 /* enable WME support. */ 4520 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4521 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4522 BWN_IFSCTL_USE_EDCF); 4523} 4524 4525static void 4526bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4527{ 4528 struct bwn_softc *sc = mac->mac_sc; 4529 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4530 uint16_t delay; /* microsec */ 4531 4532 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4533 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4534 delay = 500; 4535 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4536 delay = max(delay, (uint16_t)2400); 4537 4538 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4539} 4540 4541static void 4542bwn_bt_enable(struct bwn_mac *mac) 4543{ 4544 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 4545 uint64_t hf; 4546 4547 if (bwn_bluetooth == 0) 4548 return; 4549 if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0) 4550 return; 4551 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4552 return; 4553 4554 hf = bwn_hf_read(mac); 4555 if (sprom->bf_lo & BWN_BFL_BTCMOD) 4556 hf |= BWN_HF_BT_COEXISTALT; 4557 else 4558 hf |= BWN_HF_BT_COEXIST; 4559 bwn_hf_write(mac, hf); 4560} 4561 4562static void 4563bwn_set_macaddr(struct bwn_mac *mac) 4564{ 4565 4566 bwn_mac_write_bssid(mac); 4567 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4568} 4569 4570static void 4571bwn_clear_keys(struct bwn_mac *mac) 4572{ 4573 int i; 4574 4575 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4576 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4577 ("%s:%d: fail", __func__, __LINE__)); 4578 4579 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4580 NULL, BWN_SEC_KEYSIZE, NULL); 4581 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4582 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4583 NULL, BWN_SEC_KEYSIZE, NULL); 4584 } 4585 mac->mac_key[i].keyconf = NULL; 4586 } 4587} 4588 4589static void 4590bwn_crypt_init(struct bwn_mac *mac) 4591{ 4592 4593 mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20; 4594 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4595 ("%s:%d: fail", __func__, __LINE__)); 4596 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4597 mac->mac_ktp *= 2; 4598 if (mac->mac_sd->sd_id.sd_rev >= 5) { 4599 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, 4600 mac->mac_max_nr_keys - 8); 4601 } 4602 bwn_clear_keys(mac); 4603} 4604 4605static void 4606bwn_chip_exit(struct bwn_mac *mac) 4607{ 4608 4609 bwn_phy_exit(mac); 4610 bwn_gpio_cleanup(mac); 4611} 4612 4613static int 4614bwn_fw_fillinfo(struct bwn_mac *mac) 4615{ 4616 int error; 4617 4618 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4619 if (error == 0) 4620 return (0); 4621 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4622 if (error == 0) 4623 return (0); 4624 return (error); 4625} 4626 4627static int 4628bwn_gpio_init(struct bwn_mac *mac) 4629{ 4630 struct siba_softc *bus = mac->mac_sd->sd_bus; 4631 struct siba_dev_softc *sd; 4632 uint32_t mask = 0x0000001f, set = 0x0000000f; 4633 4634 BWN_WRITE_4(mac, BWN_MACCTL, 4635 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4636 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4637 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4638 4639 if (bus->siba_chipid == 0x4301) { 4640 mask |= 0x0060; 4641 set |= 0x0060; 4642 } 4643 if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) { 4644 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4645 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4646 mask |= 0x0200; 4647 set |= 0x0200; 4648 } 4649 if (mac->mac_sd->sd_id.sd_rev >= 2) 4650 mask |= 0x0010; 4651 sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev : 4652 bus->siba_pci.spc_dev; 4653 if (sd == NULL) 4654 return (0); 4655 siba_write_4(sd, BWN_GPIOCTL, 4656 (siba_read_4(sd, BWN_GPIOCTL) & mask) | set); 4657 4658 return (0); 4659} 4660 4661static int 4662bwn_fw_loadinitvals(struct bwn_mac *mac) 4663{ 4664#define GETFWOFFSET(fwp, offset) \ 4665 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4666 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4667 const struct bwn_fwhdr *hdr; 4668 struct bwn_fw *fw = &mac->mac_fw; 4669 int error; 4670 4671 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4672 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4673 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4674 if (error) 4675 return (error); 4676 if (fw->initvals_band.fw) { 4677 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4678 error = bwn_fwinitvals_write(mac, 4679 GETFWOFFSET(fw->initvals_band, hdr_len), 4680 be32toh(hdr->size), 4681 fw->initvals_band.fw->datasize - hdr_len); 4682 } 4683 return (error); 4684#undef GETFWOFFSET 4685} 4686 4687static int 4688bwn_phy_init(struct bwn_mac *mac) 4689{ 4690 struct bwn_softc *sc = mac->mac_sc; 4691 int error; 4692 4693 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4694 mac->mac_phy.rf_onoff(mac, 1); 4695 error = mac->mac_phy.init(mac); 4696 if (error) { 4697 device_printf(sc->sc_dev, "PHY init failed\n"); 4698 goto fail0; 4699 } 4700 error = bwn_switch_channel(mac, 4701 mac->mac_phy.get_default_chan(mac)); 4702 if (error) { 4703 device_printf(sc->sc_dev, 4704 "failed to switch default channel\n"); 4705 goto fail1; 4706 } 4707 return (0); 4708fail1: 4709 if (mac->mac_phy.exit) 4710 mac->mac_phy.exit(mac); 4711fail0: 4712 mac->mac_phy.rf_onoff(mac, 0); 4713 4714 return (error); 4715} 4716 4717static void 4718bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4719{ 4720 uint16_t ant; 4721 uint16_t tmp; 4722 4723 ant = bwn_ant2phy(antenna); 4724 4725 /* For ACK/CTS */ 4726 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4727 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4728 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4729 /* For Probe Resposes */ 4730 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4731 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4732 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4733} 4734 4735static void 4736bwn_set_opmode(struct bwn_mac *mac) 4737{ 4738 struct bwn_softc *sc = mac->mac_sc; 4739 struct ifnet *ifp = sc->sc_ifp; 4740 struct ieee80211com *ic = ifp->if_l2com; 4741 uint32_t ctl; 4742 uint16_t cfp_pretbtt; 4743 4744 ctl = BWN_READ_4(mac, BWN_MACCTL); 4745 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4746 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4747 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4748 ctl |= BWN_MACCTL_STA; 4749 4750 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4751 ic->ic_opmode == IEEE80211_M_MBSS) 4752 ctl |= BWN_MACCTL_HOSTAP; 4753 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4754 ctl &= ~BWN_MACCTL_STA; 4755 ctl |= sc->sc_filters; 4756 4757 if (mac->mac_sd->sd_id.sd_rev <= 4) 4758 ctl |= BWN_MACCTL_PROMISC; 4759 4760 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4761 4762 cfp_pretbtt = 2; 4763 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4764 if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 && 4765 mac->mac_sd->sd_bus->siba_chiprev == 3) 4766 cfp_pretbtt = 100; 4767 else 4768 cfp_pretbtt = 50; 4769 } 4770 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4771} 4772 4773static void 4774bwn_gpio_cleanup(struct bwn_mac *mac) 4775{ 4776 struct siba_softc *bus = mac->mac_sd->sd_bus; 4777 struct siba_dev_softc *gpiodev, *pcidev = NULL; 4778 4779 pcidev = bus->siba_pci.spc_dev; 4780 gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev; 4781 if (!gpiodev) 4782 return; 4783 siba_write_4(gpiodev, BWN_GPIOCTL, 0); 4784} 4785 4786static int 4787bwn_dma_gettype(struct bwn_mac *mac) 4788{ 4789 uint32_t tmp; 4790 uint16_t base; 4791 4792 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4793 if (tmp & SIBA_TGSHIGH_DMA64) 4794 return (BWN_DMA_64BIT); 4795 base = bwn_dma_base(0, 0); 4796 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4797 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4798 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4799 return (BWN_DMA_32BIT); 4800 4801 return (BWN_DMA_30BIT); 4802} 4803 4804static void 4805bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4806{ 4807 if (!error) { 4808 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4809 *((bus_addr_t *)arg) = seg->ds_addr; 4810 } 4811} 4812 4813static void 4814bwn_phy_g_init_sub(struct bwn_mac *mac) 4815{ 4816 struct bwn_phy *phy = &mac->mac_phy; 4817 struct bwn_phy_g *pg = &phy->phy_g; 4818 uint16_t i, tmp; 4819 4820 if (phy->rev == 1) 4821 bwn_phy_init_b5(mac); 4822 else 4823 bwn_phy_init_b6(mac); 4824 4825 if (phy->rev >= 2 || phy->gmode) 4826 bwn_phy_init_a(mac); 4827 4828 if (phy->rev >= 2) { 4829 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4830 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4831 } 4832 if (phy->rev == 2) { 4833 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4834 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4835 } 4836 if (phy->rev > 5) { 4837 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4838 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4839 } 4840 if (phy->gmode || phy->rev >= 2) { 4841 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4842 tmp &= BWN_PHYVER_VERSION; 4843 if (tmp == 3 || tmp == 5) { 4844 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4845 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4846 } 4847 if (tmp == 5) { 4848 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4849 0x1f00); 4850 } 4851 } 4852 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4853 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4854 if (phy->rf_rev == 8) { 4855 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4856 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4857 } 4858 if (BWN_HAS_LOOPBACK(phy)) 4859 bwn_loopback_calcgain(mac); 4860 4861 if (phy->rf_rev != 8) { 4862 if (pg->pg_initval == 0xffff) 4863 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4864 else 4865 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4866 } 4867 bwn_lo_g_init(mac); 4868 if (BWN_HAS_TXMAG(phy)) { 4869 BWN_RF_WRITE(mac, 0x52, 4870 (BWN_RF_READ(mac, 0x52) & 0xff00) 4871 | pg->pg_loctl.tx_bias | 4872 pg->pg_loctl.tx_magn); 4873 } else { 4874 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4875 } 4876 if (phy->rev >= 6) { 4877 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4878 (pg->pg_loctl.tx_bias << 12)); 4879 } 4880 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) 4881 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4882 else 4883 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4884 if (phy->rev < 2) 4885 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4886 else 4887 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4888 if (phy->gmode || phy->rev >= 2) { 4889 bwn_lo_g_adjust(mac); 4890 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4891 } 4892 4893 if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 4894 for (i = 0; i < 64; i++) { 4895 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4896 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4897 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4898 -32), 31)); 4899 } 4900 bwn_nrssi_threshold(mac); 4901 } else if (phy->gmode || phy->rev >= 2) { 4902 if (pg->pg_nrssi[0] == -1000) { 4903 KASSERT(pg->pg_nrssi[1] == -1000, 4904 ("%s:%d: fail", __func__, __LINE__)); 4905 bwn_nrssi_slope_11g(mac); 4906 } else 4907 bwn_nrssi_threshold(mac); 4908 } 4909 if (phy->rf_rev == 8) 4910 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4911 bwn_phy_hwpctl_init(mac); 4912 if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306 4913 && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) { 4914 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4915 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4916 } 4917} 4918 4919static uint8_t 4920bwn_has_hwpctl(struct bwn_mac *mac) 4921{ 4922 4923 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4924 return (0); 4925 return (mac->mac_phy.use_hwpctl(mac)); 4926} 4927 4928static void 4929bwn_phy_init_b5(struct bwn_mac *mac) 4930{ 4931 struct siba_softc *bus = mac->mac_sd->sd_bus; 4932 struct bwn_phy *phy = &mac->mac_phy; 4933 struct bwn_phy_g *pg = &phy->phy_g; 4934 uint16_t offset, value; 4935 uint8_t old_channel; 4936 4937 if (phy->analog == 1) 4938 BWN_RF_SET(mac, 0x007a, 0x0050); 4939 if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) && 4940 (bus->siba_board_type != SIBA_BOARD_BU4306)) { 4941 value = 0x2120; 4942 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4943 BWN_PHY_WRITE(mac, offset, value); 4944 value += 0x202; 4945 } 4946 } 4947 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4948 if (phy->rf_ver == 0x2050) 4949 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4950 4951 if (phy->gmode || phy->rev >= 2) { 4952 if (phy->rf_ver == 0x2050) { 4953 BWN_RF_SET(mac, 0x007a, 0x0020); 4954 BWN_RF_SET(mac, 0x0051, 0x0004); 4955 } 4956 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4957 4958 BWN_PHY_SET(mac, 0x0802, 0x0100); 4959 BWN_PHY_SET(mac, 0x042b, 0x2000); 4960 4961 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4962 4963 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4964 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4965 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4966 } 4967 4968 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4969 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4970 4971 if (phy->analog == 1) { 4972 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4973 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4974 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4975 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4976 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4977 } else 4978 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4979 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4980 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4981 4982 if (phy->analog == 1) 4983 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4984 else 4985 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4986 4987 if (phy->analog == 0) 4988 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4989 4990 old_channel = phy->chan; 4991 bwn_phy_g_switch_chan(mac, 7, 0); 4992 4993 if (phy->rf_ver != 0x2050) { 4994 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4995 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4996 } 4997 4998 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4999 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5000 5001 if (phy->rf_ver == 0x2050) { 5002 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5003 BWN_RF_WRITE(mac, 0x005a, 0x0070); 5004 } 5005 5006 BWN_RF_WRITE(mac, 0x005b, 0x007b); 5007 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 5008 BWN_RF_SET(mac, 0x007a, 0x0007); 5009 5010 bwn_phy_g_switch_chan(mac, old_channel, 0); 5011 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 5012 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 5013 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 5014 5015 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5016 pg->pg_txctl); 5017 5018 if (phy->rf_ver == 0x2050) 5019 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5020 5021 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 5022} 5023 5024static void 5025bwn_loopback_calcgain(struct bwn_mac *mac) 5026{ 5027 struct bwn_phy *phy = &mac->mac_phy; 5028 struct bwn_phy_g *pg = &phy->phy_g; 5029 uint16_t backup_phy[16] = { 0 }; 5030 uint16_t backup_radio[3]; 5031 uint16_t backup_bband; 5032 uint16_t i, j, loop_i_max; 5033 uint16_t trsw_rx; 5034 uint16_t loop1_outer_done, loop1_inner_done; 5035 5036 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5037 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 5038 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5039 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5040 if (phy->rev != 1) { 5041 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5042 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5043 } 5044 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5045 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5046 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5047 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 5048 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 5049 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5050 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5051 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 5052 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5053 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5054 backup_bband = pg->pg_bbatt.att; 5055 backup_radio[0] = BWN_RF_READ(mac, 0x52); 5056 backup_radio[1] = BWN_RF_READ(mac, 0x43); 5057 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 5058 5059 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 5060 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 5061 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 5062 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 5063 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 5064 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 5065 if (phy->rev != 1) { 5066 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 5067 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 5068 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 5069 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 5070 } 5071 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 5072 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 5073 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 5074 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 5075 5076 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 5077 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5078 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5079 5080 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 5081 if (phy->rev != 1) { 5082 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 5083 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 5084 } 5085 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 5086 5087 if (phy->rf_rev == 8) 5088 BWN_RF_WRITE(mac, 0x43, 0x000f); 5089 else { 5090 BWN_RF_WRITE(mac, 0x52, 0); 5091 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 5092 } 5093 bwn_phy_g_set_bbatt(mac, 11); 5094 5095 if (phy->rev >= 3) 5096 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5097 else 5098 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5099 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5100 5101 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5102 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5103 5104 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5105 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5106 5107 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) { 5108 if (phy->rev >= 7) { 5109 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5110 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5111 } 5112 } 5113 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5114 5115 j = 0; 5116 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5117 for (i = 0; i < loop_i_max; i++) { 5118 for (j = 0; j < 16; j++) { 5119 BWN_RF_WRITE(mac, 0x43, i); 5120 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5121 (j << 8)); 5122 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5123 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5124 DELAY(20); 5125 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5126 goto done0; 5127 } 5128 } 5129done0: 5130 loop1_outer_done = i; 5131 loop1_inner_done = j; 5132 if (j >= 8) { 5133 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5134 trsw_rx = 0x1b; 5135 for (j = j - 8; j < 16; j++) { 5136 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5137 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5138 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5139 DELAY(20); 5140 trsw_rx -= 3; 5141 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5142 goto done1; 5143 } 5144 } else 5145 trsw_rx = 0x18; 5146done1: 5147 5148 if (phy->rev != 1) { 5149 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5150 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5151 } 5152 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5153 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5154 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5155 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5156 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5157 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5158 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5159 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5160 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5161 5162 bwn_phy_g_set_bbatt(mac, backup_bband); 5163 5164 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5165 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5166 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5167 5168 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5169 DELAY(10); 5170 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5171 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5172 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5173 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5174 5175 pg->pg_max_lb_gain = 5176 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5177 pg->pg_trsw_rx_gain = trsw_rx * 2; 5178} 5179 5180static uint16_t 5181bwn_rf_init_bcm2050(struct bwn_mac *mac) 5182{ 5183 struct bwn_phy *phy = &mac->mac_phy; 5184 uint32_t tmp1 = 0, tmp2 = 0; 5185 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5186 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5187 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5188 static const uint8_t rcc_table[] = { 5189 0x02, 0x03, 0x01, 0x0f, 5190 0x06, 0x07, 0x05, 0x0f, 5191 0x0a, 0x0b, 0x09, 0x0f, 5192 0x0e, 0x0f, 0x0d, 0x0f, 5193 }; 5194 5195 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5196 rfoverval = rfover = cck3 = 0; 5197 radio0 = BWN_RF_READ(mac, 0x43); 5198 radio1 = BWN_RF_READ(mac, 0x51); 5199 radio2 = BWN_RF_READ(mac, 0x52); 5200 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5201 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5202 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5203 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5204 5205 if (phy->type == BWN_PHYTYPE_B) { 5206 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5207 reg0 = BWN_READ_2(mac, 0x3ec); 5208 5209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5210 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5211 } else if (phy->gmode || phy->rev >= 2) { 5212 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5213 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5214 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5215 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5216 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5217 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5218 5219 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5220 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5221 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5222 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5223 if (BWN_HAS_LOOPBACK(phy)) { 5224 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5225 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5226 if (phy->rev >= 3) 5227 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5228 else 5229 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5230 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5231 } 5232 5233 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5234 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5235 BWN_LPD(0, 1, 1))); 5236 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5237 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5238 } 5239 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5240 5241 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5242 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5243 reg1 = BWN_READ_2(mac, 0x3e6); 5244 reg2 = BWN_READ_2(mac, 0x3f4); 5245 5246 if (phy->analog == 0) 5247 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5248 else { 5249 if (phy->analog >= 2) 5250 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5251 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5252 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5253 } 5254 5255 reg = BWN_RF_READ(mac, 0x60); 5256 index = (reg & 0x001e) >> 1; 5257 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5258 5259 if (phy->type == BWN_PHYTYPE_B) 5260 BWN_RF_WRITE(mac, 0x78, 0x26); 5261 if (phy->gmode || phy->rev >= 2) { 5262 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5263 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5264 BWN_LPD(0, 1, 1))); 5265 } 5266 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5267 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5268 if (phy->gmode || phy->rev >= 2) { 5269 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5270 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5271 BWN_LPD(0, 0, 1))); 5272 } 5273 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5274 BWN_RF_SET(mac, 0x51, 0x0004); 5275 if (phy->rf_rev == 8) 5276 BWN_RF_WRITE(mac, 0x43, 0x1f); 5277 else { 5278 BWN_RF_WRITE(mac, 0x52, 0); 5279 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5280 } 5281 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5282 5283 for (i = 0; i < 16; i++) { 5284 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5285 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5286 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5287 if (phy->gmode || phy->rev >= 2) { 5288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5289 bwn_rf_2050_rfoverval(mac, 5290 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5291 } 5292 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5293 DELAY(10); 5294 if (phy->gmode || phy->rev >= 2) { 5295 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5296 bwn_rf_2050_rfoverval(mac, 5297 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5298 } 5299 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5300 DELAY(10); 5301 if (phy->gmode || phy->rev >= 2) { 5302 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5303 bwn_rf_2050_rfoverval(mac, 5304 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5305 } 5306 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5307 DELAY(20); 5308 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5309 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5310 if (phy->gmode || phy->rev >= 2) { 5311 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5312 bwn_rf_2050_rfoverval(mac, 5313 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5314 } 5315 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5316 } 5317 DELAY(10); 5318 5319 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5320 tmp1++; 5321 tmp1 >>= 9; 5322 5323 for (i = 0; i < 16; i++) { 5324 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5325 BWN_RF_WRITE(mac, 0x78, radio78); 5326 DELAY(10); 5327 for (j = 0; j < 16; j++) { 5328 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5329 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5330 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5331 if (phy->gmode || phy->rev >= 2) { 5332 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5333 bwn_rf_2050_rfoverval(mac, 5334 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5335 } 5336 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5337 DELAY(10); 5338 if (phy->gmode || phy->rev >= 2) { 5339 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5340 bwn_rf_2050_rfoverval(mac, 5341 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5342 } 5343 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5344 DELAY(10); 5345 if (phy->gmode || phy->rev >= 2) { 5346 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5347 bwn_rf_2050_rfoverval(mac, 5348 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5349 } 5350 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5351 DELAY(10); 5352 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5353 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5354 if (phy->gmode || phy->rev >= 2) { 5355 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5356 bwn_rf_2050_rfoverval(mac, 5357 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5358 } 5359 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5360 } 5361 tmp2++; 5362 tmp2 >>= 8; 5363 if (tmp1 < tmp2) 5364 break; 5365 } 5366 5367 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5368 BWN_RF_WRITE(mac, 0x51, radio1); 5369 BWN_RF_WRITE(mac, 0x52, radio2); 5370 BWN_RF_WRITE(mac, 0x43, radio0); 5371 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5372 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5373 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5374 BWN_WRITE_2(mac, 0x3e6, reg1); 5375 if (phy->analog != 0) 5376 BWN_WRITE_2(mac, 0x3f4, reg2); 5377 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5378 bwn_spu_workaround(mac, phy->chan); 5379 if (phy->type == BWN_PHYTYPE_B) { 5380 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5381 BWN_WRITE_2(mac, 0x3ec, reg0); 5382 } else if (phy->gmode) { 5383 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5384 BWN_READ_2(mac, BWN_PHY_RADIO) 5385 & 0x7fff); 5386 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5387 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5388 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5389 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5390 analogoverval); 5391 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5392 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5393 if (BWN_HAS_LOOPBACK(phy)) { 5394 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5395 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5396 } 5397 } 5398 5399 return ((i > 15) ? radio78 : rcc); 5400} 5401 5402static void 5403bwn_phy_init_b6(struct bwn_mac *mac) 5404{ 5405 struct bwn_phy *phy = &mac->mac_phy; 5406 struct bwn_phy_g *pg = &phy->phy_g; 5407 uint16_t offset, val; 5408 uint8_t old_channel; 5409 5410 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5411 ("%s:%d: fail", __func__, __LINE__)); 5412 5413 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5414 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5415 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5416 BWN_RF_WRITE(mac, 0x51, 0x37); 5417 BWN_RF_WRITE(mac, 0x52, 0x70); 5418 BWN_RF_WRITE(mac, 0x53, 0xb3); 5419 BWN_RF_WRITE(mac, 0x54, 0x9b); 5420 BWN_RF_WRITE(mac, 0x5a, 0x88); 5421 BWN_RF_WRITE(mac, 0x5b, 0x88); 5422 BWN_RF_WRITE(mac, 0x5d, 0x88); 5423 BWN_RF_WRITE(mac, 0x5e, 0x88); 5424 BWN_RF_WRITE(mac, 0x7d, 0x88); 5425 bwn_hf_write(mac, 5426 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5427 } 5428 if (phy->rf_rev == 8) { 5429 BWN_RF_WRITE(mac, 0x51, 0); 5430 BWN_RF_WRITE(mac, 0x52, 0x40); 5431 BWN_RF_WRITE(mac, 0x53, 0xb7); 5432 BWN_RF_WRITE(mac, 0x54, 0x98); 5433 BWN_RF_WRITE(mac, 0x5a, 0x88); 5434 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5435 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5436 if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) { 5437 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5438 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5439 } else { 5440 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5441 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5442 } 5443 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5444 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5445 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5446 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5447 } 5448 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5449 BWN_PHY_WRITE(mac, offset, val); 5450 val -= 0x0202; 5451 } 5452 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5453 BWN_PHY_WRITE(mac, offset, val); 5454 val -= 0x0202; 5455 } 5456 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5457 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5458 val += 0x0202; 5459 } 5460 if (phy->type == BWN_PHYTYPE_G) { 5461 BWN_RF_SET(mac, 0x007a, 0x0020); 5462 BWN_RF_SET(mac, 0x0051, 0x0004); 5463 BWN_PHY_SET(mac, 0x0802, 0x0100); 5464 BWN_PHY_SET(mac, 0x042b, 0x2000); 5465 BWN_PHY_WRITE(mac, 0x5b, 0); 5466 BWN_PHY_WRITE(mac, 0x5c, 0); 5467 } 5468 5469 old_channel = phy->chan; 5470 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5471 5472 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5473 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5474 DELAY(40); 5475 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5476 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5477 BWN_RF_WRITE(mac, 0x50, 0x20); 5478 } 5479 if (phy->rf_rev <= 2) { 5480 BWN_RF_WRITE(mac, 0x7c, 0x20); 5481 BWN_RF_WRITE(mac, 0x5a, 0x70); 5482 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5483 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5484 } 5485 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5486 5487 bwn_phy_g_switch_chan(mac, old_channel, 0); 5488 5489 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5490 if (phy->rf_rev >= 6) 5491 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5492 else 5493 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5494 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5495 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5496 pg->pg_txctl); 5497 if (phy->rf_rev <= 5) 5498 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5499 if (phy->rf_rev <= 2) 5500 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5501 5502 if (phy->analog == 4) { 5503 BWN_WRITE_2(mac, 0x3e4, 9); 5504 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5505 } else 5506 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5507 if (phy->type == BWN_PHYTYPE_B) 5508 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5509 else if (phy->type == BWN_PHYTYPE_G) 5510 BWN_WRITE_2(mac, 0x03e6, 0x0); 5511} 5512 5513static void 5514bwn_phy_init_a(struct bwn_mac *mac) 5515{ 5516 struct bwn_phy *phy = &mac->mac_phy; 5517 5518 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5519 ("%s:%d: fail", __func__, __LINE__)); 5520 5521 if (phy->rev >= 6) { 5522 if (phy->type == BWN_PHYTYPE_A) 5523 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5524 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5525 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5526 else 5527 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5528 } 5529 5530 bwn_wa_init(mac); 5531 5532 if (phy->type == BWN_PHYTYPE_G && 5533 (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)) 5534 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5535} 5536 5537static void 5538bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5539{ 5540 int i; 5541 5542 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5543 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5544} 5545 5546static void 5547bwn_wa_agc(struct bwn_mac *mac) 5548{ 5549 struct bwn_phy *phy = &mac->mac_phy; 5550 5551 if (phy->rev == 1) { 5552 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5554 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5555 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5556 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5557 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5560 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5561 } else { 5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5563 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5564 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5566 } 5567 5568 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5569 0x5700); 5570 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5571 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5572 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5573 BWN_RF_SET(mac, 0x7a, 0x0008); 5574 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5575 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5576 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5577 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5578 if (phy->rev == 1) 5579 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5580 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5581 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5582 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5583 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5584 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5585 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5586 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5587 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5588 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5589 if (phy->rev == 1) { 5590 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5591 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5592 } else { 5593 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5594 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5595 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5596 if (phy->rev >= 6) { 5597 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5598 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5599 (uint16_t)~0xf000, 0x3000); 5600 } 5601 } 5602 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5603 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5604 if (phy->rev == 1) { 5605 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5606 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5607 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5608 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5609 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5610 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5611 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5613 } else { 5614 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5615 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5616 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5617 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5618 } 5619 if (phy->rev >= 6) { 5620 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5621 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5622 } 5623 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5624} 5625 5626static void 5627bwn_wa_grev1(struct bwn_mac *mac) 5628{ 5629 struct bwn_phy *phy = &mac->mac_phy; 5630 int i; 5631 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5632 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5633 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5634 5635 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5636 5637 /* init CRSTHRES and ANTDWELL */ 5638 if (phy->rev == 1) { 5639 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5640 } else if (phy->rev == 2) { 5641 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5642 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5643 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5644 } else { 5645 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5646 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5647 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5648 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5649 } 5650 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5651 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5652 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5653 5654 /* XXX support PHY-A??? */ 5655 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5656 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5657 bwn_tab_finefreqg[i]); 5658 5659 /* XXX support PHY-A??? */ 5660 if (phy->rev == 1) 5661 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5662 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5663 bwn_tab_noise_g1[i]); 5664 else 5665 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5666 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5667 bwn_tab_noise_g2[i]); 5668 5669 5670 for (i = 0; i < N(bwn_tab_rotor); i++) 5671 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5672 bwn_tab_rotor[i]); 5673 5674 /* XXX support PHY-A??? */ 5675 if (phy->rev >= 6) { 5676 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5677 BWN_PHY_ENCORE_EN) 5678 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5679 else 5680 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5681 } else 5682 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5683 5684 for (i = 0; i < N(bwn_tab_retard); i++) 5685 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5686 bwn_tab_retard[i]); 5687 5688 if (phy->rev == 1) { 5689 for (i = 0; i < 16; i++) 5690 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5691 i, 0x0020); 5692 } else { 5693 for (i = 0; i < 32; i++) 5694 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5695 } 5696 5697 bwn_wa_agc(mac); 5698} 5699 5700static void 5701bwn_wa_grev26789(struct bwn_mac *mac) 5702{ 5703 struct bwn_phy *phy = &mac->mac_phy; 5704 int i; 5705 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5706 uint16_t ofdmrev; 5707 5708 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5709 5710 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5711 5712 /* init CRSTHRES and ANTDWELL */ 5713 if (phy->rev == 1) 5714 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5715 else if (phy->rev == 2) { 5716 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5717 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5718 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5719 } else { 5720 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5721 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5722 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5723 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5724 } 5725 5726 for (i = 0; i < 64; i++) 5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5728 5729 /* XXX support PHY-A??? */ 5730 if (phy->rev == 1) 5731 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5733 bwn_tab_noise_g1[i]); 5734 else 5735 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5736 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5737 bwn_tab_noise_g2[i]); 5738 5739 /* XXX support PHY-A??? */ 5740 if (phy->rev >= 6) { 5741 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5742 BWN_PHY_ENCORE_EN) 5743 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5744 else 5745 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5746 } else 5747 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5748 5749 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5750 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5751 bwn_tab_sigmasqr2[i]); 5752 5753 if (phy->rev == 1) { 5754 for (i = 0; i < 16; i++) 5755 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5756 0x0020); 5757 } else { 5758 for (i = 0; i < 32; i++) 5759 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5760 } 5761 5762 bwn_wa_agc(mac); 5763 5764 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5765 if (ofdmrev > 2) { 5766 if (phy->type == BWN_PHYTYPE_A) 5767 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5768 else 5769 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5770 } else { 5771 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5772 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5773 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5774 } 5775 5776 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5777 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5778} 5779 5780static void 5781bwn_wa_init(struct bwn_mac *mac) 5782{ 5783 struct bwn_phy *phy = &mac->mac_phy; 5784 struct siba_softc *bus = mac->mac_sd->sd_bus; 5785 5786 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5787 5788 switch (phy->rev) { 5789 case 1: 5790 bwn_wa_grev1(mac); 5791 break; 5792 case 2: 5793 case 6: 5794 case 7: 5795 case 8: 5796 case 9: 5797 bwn_wa_grev26789(mac); 5798 break; 5799 default: 5800 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5801 } 5802 5803 if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM || 5804 bus->siba_board_type != SIBA_BOARD_BU4306 || 5805 bus->siba_board_rev != 0x17) { 5806 if (phy->rev < 2) { 5807 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5808 0x0002); 5809 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5810 0x0001); 5811 } else { 5812 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5813 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5814 if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) && 5815 (phy->rev >= 7)) { 5816 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5817 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5818 0x0020, 0x0001); 5819 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5820 0x0021, 0x0001); 5821 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5822 0x0022, 0x0001); 5823 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5824 0x0023, 0x0000); 5825 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5826 0x0000, 0x0000); 5827 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5828 0x0003, 0x0002); 5829 } 5830 } 5831 } 5832 if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) { 5833 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5834 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5835 } 5836 5837 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5838 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5839} 5840 5841static void 5842bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5843 uint16_t value) 5844{ 5845 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5846 uint16_t addr; 5847 5848 addr = table + offset; 5849 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5850 (addr - 1 != pg->pg_ofdmtab_addr)) { 5851 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5852 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5853 } 5854 pg->pg_ofdmtab_addr = addr; 5855 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5856} 5857 5858static void 5859bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5860 uint32_t value) 5861{ 5862 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5863 uint16_t addr; 5864 5865 addr = table + offset; 5866 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5867 (addr - 1 != pg->pg_ofdmtab_addr)) { 5868 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5869 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5870 } 5871 pg->pg_ofdmtab_addr = addr; 5872 5873 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5874 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5875} 5876 5877static void 5878bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5879 uint16_t value) 5880{ 5881 5882 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5883 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5884} 5885 5886static void 5887bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5888{ 5889 struct bwn_phy *phy = &mac->mac_phy; 5890 unsigned int i, max_loop; 5891 uint16_t value; 5892 uint32_t buffer[5] = { 5893 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5894 }; 5895 5896 if (ofdm) { 5897 max_loop = 0x1e; 5898 buffer[0] = 0x000201cc; 5899 } else { 5900 max_loop = 0xfa; 5901 buffer[0] = 0x000b846e; 5902 } 5903 5904 BWN_ASSERT_LOCKED(mac->mac_sc); 5905 5906 for (i = 0; i < 5; i++) 5907 bwn_ram_write(mac, i * 4, buffer[i]); 5908 5909 BWN_WRITE_2(mac, 0x0568, 0x0000); 5910 BWN_WRITE_2(mac, 0x07c0, 5911 (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100); 5912 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5913 BWN_WRITE_2(mac, 0x050c, value); 5914 if (phy->type == BWN_PHYTYPE_LP) 5915 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5916 BWN_WRITE_2(mac, 0x0508, 0x0000); 5917 BWN_WRITE_2(mac, 0x050a, 0x0000); 5918 BWN_WRITE_2(mac, 0x054c, 0x0000); 5919 BWN_WRITE_2(mac, 0x056a, 0x0014); 5920 BWN_WRITE_2(mac, 0x0568, 0x0826); 5921 BWN_WRITE_2(mac, 0x0500, 0x0000); 5922 if (phy->type == BWN_PHYTYPE_LP) 5923 BWN_WRITE_2(mac, 0x0502, 0x0050); 5924 else 5925 BWN_WRITE_2(mac, 0x0502, 0x0030); 5926 5927 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5928 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5929 for (i = 0x00; i < max_loop; i++) { 5930 value = BWN_READ_2(mac, 0x050e); 5931 if (value & 0x0080) 5932 break; 5933 DELAY(10); 5934 } 5935 for (i = 0x00; i < 0x0a; i++) { 5936 value = BWN_READ_2(mac, 0x050e); 5937 if (value & 0x0400) 5938 break; 5939 DELAY(10); 5940 } 5941 for (i = 0x00; i < 0x19; i++) { 5942 value = BWN_READ_2(mac, 0x0690); 5943 if (!(value & 0x0100)) 5944 break; 5945 DELAY(10); 5946 } 5947 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5948 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5949} 5950 5951static void 5952bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5953{ 5954 uint32_t macctl; 5955 5956 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5957 5958 macctl = BWN_READ_4(mac, BWN_MACCTL); 5959 if (macctl & BWN_MACCTL_BIGENDIAN) 5960 printf("TODO: need swap\n"); 5961 5962 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5963 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5964 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5965} 5966 5967static void 5968bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5969{ 5970 uint16_t value; 5971 5972 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5973 ("%s:%d: fail", __func__, __LINE__)); 5974 5975 value = (uint8_t) (ctl->q); 5976 value |= ((uint8_t) (ctl->i)) << 8; 5977 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5978} 5979 5980static uint16_t 5981bwn_lo_calcfeed(struct bwn_mac *mac, 5982 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5983{ 5984 struct bwn_phy *phy = &mac->mac_phy; 5985 uint16_t rfover; 5986 uint16_t feedthrough; 5987 5988 if (phy->gmode) { 5989 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5990 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5991 5992 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5993 ("%s:%d: fail", __func__, __LINE__)); 5994 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5995 ("%s:%d: fail", __func__, __LINE__)); 5996 5997 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5998 5999 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 6000 if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) 6001 && phy->rev > 6) 6002 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 6003 6004 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6005 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6006 DELAY(10); 6007 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 6008 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6009 DELAY(10); 6010 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 6011 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 6012 DELAY(10); 6013 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 6014 } else { 6015 pga |= BWN_PHY_PGACTL_UNKNOWN; 6016 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6017 DELAY(10); 6018 pga |= BWN_PHY_PGACTL_LOWBANDW; 6019 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6020 DELAY(10); 6021 pga |= BWN_PHY_PGACTL_LPF; 6022 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 6023 } 6024 DELAY(21); 6025 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 6026 6027 return (feedthrough); 6028} 6029 6030static uint16_t 6031bwn_lo_txctl_regtable(struct bwn_mac *mac, 6032 uint16_t *value, uint16_t *pad_mix_gain) 6033{ 6034 struct bwn_phy *phy = &mac->mac_phy; 6035 uint16_t reg, v, padmix; 6036 6037 if (phy->type == BWN_PHYTYPE_B) { 6038 v = 0x30; 6039 if (phy->rf_rev <= 5) { 6040 reg = 0x43; 6041 padmix = 0; 6042 } else { 6043 reg = 0x52; 6044 padmix = 5; 6045 } 6046 } else { 6047 if (phy->rev >= 2 && phy->rf_rev == 8) { 6048 reg = 0x43; 6049 v = 0x10; 6050 padmix = 2; 6051 } else { 6052 reg = 0x52; 6053 v = 0x30; 6054 padmix = 5; 6055 } 6056 } 6057 if (value) 6058 *value = v; 6059 if (pad_mix_gain) 6060 *pad_mix_gain = padmix; 6061 6062 return (reg); 6063} 6064 6065static void 6066bwn_lo_measure_txctl_values(struct bwn_mac *mac) 6067{ 6068 struct bwn_phy *phy = &mac->mac_phy; 6069 struct bwn_phy_g *pg = &phy->phy_g; 6070 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6071 uint16_t reg, mask; 6072 uint16_t trsw_rx, pga; 6073 uint16_t rf_pctl_reg; 6074 6075 static const uint8_t tx_bias_values[] = { 6076 0x09, 0x08, 0x0a, 0x01, 0x00, 6077 0x02, 0x05, 0x04, 0x06, 6078 }; 6079 static const uint8_t tx_magn_values[] = { 6080 0x70, 0x40, 6081 }; 6082 6083 if (!BWN_HAS_LOOPBACK(phy)) { 6084 rf_pctl_reg = 6; 6085 trsw_rx = 2; 6086 pga = 0; 6087 } else { 6088 int lb_gain; 6089 6090 trsw_rx = 0; 6091 lb_gain = pg->pg_max_lb_gain / 2; 6092 if (lb_gain > 10) { 6093 rf_pctl_reg = 0; 6094 pga = abs(10 - lb_gain) / 6; 6095 pga = MIN(MAX(pga, 0), 15); 6096 } else { 6097 int cmp_val; 6098 int tmp; 6099 6100 pga = 0; 6101 cmp_val = 0x24; 6102 if ((phy->rev >= 2) && 6103 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6104 cmp_val = 0x3c; 6105 tmp = lb_gain; 6106 if ((10 - lb_gain) < cmp_val) 6107 tmp = (10 - lb_gain); 6108 if (tmp < 0) 6109 tmp += 6; 6110 else 6111 tmp += 3; 6112 cmp_val /= 4; 6113 tmp /= 4; 6114 if (tmp >= cmp_val) 6115 rf_pctl_reg = cmp_val; 6116 else 6117 rf_pctl_reg = tmp; 6118 } 6119 } 6120 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6121 bwn_phy_g_set_bbatt(mac, 2); 6122 6123 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6124 mask = ~mask; 6125 BWN_RF_MASK(mac, reg, mask); 6126 6127 if (BWN_HAS_TXMAG(phy)) { 6128 int i, j; 6129 int feedthrough; 6130 int min_feedth = 0xffff; 6131 uint8_t tx_magn, tx_bias; 6132 6133 for (i = 0; i < N(tx_magn_values); i++) { 6134 tx_magn = tx_magn_values[i]; 6135 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6136 for (j = 0; j < N(tx_bias_values); j++) { 6137 tx_bias = tx_bias_values[j]; 6138 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6139 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6140 trsw_rx); 6141 if (feedthrough < min_feedth) { 6142 lo->tx_bias = tx_bias; 6143 lo->tx_magn = tx_magn; 6144 min_feedth = feedthrough; 6145 } 6146 if (lo->tx_bias == 0) 6147 break; 6148 } 6149 BWN_RF_WRITE(mac, 0x52, 6150 (BWN_RF_READ(mac, 0x52) 6151 & 0xff00) | lo->tx_bias | lo-> 6152 tx_magn); 6153 } 6154 } else { 6155 lo->tx_magn = 0; 6156 lo->tx_bias = 0; 6157 BWN_RF_MASK(mac, 0x52, 0xfff0); 6158 } 6159 6160 BWN_GETTIME(lo->txctl_measured_time); 6161} 6162 6163static void 6164bwn_lo_get_powervector(struct bwn_mac *mac) 6165{ 6166 struct bwn_phy *phy = &mac->mac_phy; 6167 struct bwn_phy_g *pg = &phy->phy_g; 6168 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6169 int i; 6170 uint64_t tmp; 6171 uint64_t power_vector = 0; 6172 6173 for (i = 0; i < 8; i += 2) { 6174 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6175 power_vector |= (tmp << (i * 8)); 6176 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6177 } 6178 if (power_vector) 6179 lo->power_vector = power_vector; 6180 6181 BWN_GETTIME(lo->pwr_vec_read_time); 6182} 6183 6184static void 6185bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6186 int use_trsw_rx) 6187{ 6188 struct bwn_phy *phy = &mac->mac_phy; 6189 struct bwn_phy_g *pg = &phy->phy_g; 6190 uint16_t tmp; 6191 6192 if (max_rx_gain < 0) 6193 max_rx_gain = 0; 6194 6195 if (BWN_HAS_LOOPBACK(phy)) { 6196 int trsw_rx = 0; 6197 int trsw_rx_gain; 6198 6199 if (use_trsw_rx) { 6200 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6201 if (max_rx_gain >= trsw_rx_gain) { 6202 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6203 trsw_rx = 0x20; 6204 } 6205 } else 6206 trsw_rx_gain = max_rx_gain; 6207 if (trsw_rx_gain < 9) { 6208 pg->pg_lna_lod_gain = 0; 6209 } else { 6210 pg->pg_lna_lod_gain = 1; 6211 trsw_rx_gain -= 8; 6212 } 6213 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6214 pg->pg_pga_gain = trsw_rx_gain / 3; 6215 if (pg->pg_pga_gain >= 5) { 6216 pg->pg_pga_gain -= 5; 6217 pg->pg_lna_gain = 2; 6218 } else 6219 pg->pg_lna_gain = 0; 6220 } else { 6221 pg->pg_lna_gain = 0; 6222 pg->pg_trsw_rx_gain = 0x20; 6223 if (max_rx_gain >= 0x14) { 6224 pg->pg_lna_lod_gain = 1; 6225 pg->pg_pga_gain = 2; 6226 } else if (max_rx_gain >= 0x12) { 6227 pg->pg_lna_lod_gain = 1; 6228 pg->pg_pga_gain = 1; 6229 } else if (max_rx_gain >= 0xf) { 6230 pg->pg_lna_lod_gain = 1; 6231 pg->pg_pga_gain = 0; 6232 } else { 6233 pg->pg_lna_lod_gain = 0; 6234 pg->pg_pga_gain = 0; 6235 } 6236 } 6237 6238 tmp = BWN_RF_READ(mac, 0x7a); 6239 if (pg->pg_lna_lod_gain == 0) 6240 tmp &= ~0x0008; 6241 else 6242 tmp |= 0x0008; 6243 BWN_RF_WRITE(mac, 0x7a, tmp); 6244} 6245 6246static void 6247bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6248{ 6249 struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom; 6250 struct bwn_phy *phy = &mac->mac_phy; 6251 struct bwn_phy_g *pg = &phy->phy_g; 6252 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6253 struct timespec ts; 6254 uint16_t tmp; 6255 6256 if (bwn_has_hwpctl(mac)) { 6257 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6258 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6259 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6260 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6261 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6262 6263 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6264 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6265 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6266 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6267 } 6268 if (phy->type == BWN_PHYTYPE_B && 6269 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6270 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6271 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6272 } 6273 if (phy->rev >= 2) { 6274 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6275 sav->phy_analogoverval = 6276 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6277 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6278 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6279 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6280 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6281 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6282 6283 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6284 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6285 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6286 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6287 if (phy->type == BWN_PHYTYPE_G) { 6288 if ((phy->rev >= 7) && 6289 (sprom->bf_lo & BWN_BFL_EXTLNA)) { 6290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6291 } else { 6292 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6293 } 6294 } else { 6295 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6296 } 6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6298 } 6299 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6300 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6301 sav->rf0 = BWN_RF_READ(mac, 0x43); 6302 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6303 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6304 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6305 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6306 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6307 6308 if (!BWN_HAS_TXMAG(phy)) { 6309 sav->rf2 = BWN_RF_READ(mac, 0x52); 6310 sav->rf2 &= 0x00f0; 6311 } 6312 if (phy->type == BWN_PHYTYPE_B) { 6313 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6314 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6317 } else { 6318 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6319 | 0x8000); 6320 } 6321 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6322 & 0xf000); 6323 6324 tmp = 6325 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6326 BWN_PHY_WRITE(mac, tmp, 0x007f); 6327 6328 tmp = sav->phy_syncctl; 6329 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6330 tmp = sav->rf1; 6331 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6332 6333 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6334 if (phy->type == BWN_PHYTYPE_G || 6335 (phy->type == BWN_PHYTYPE_B && 6336 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6337 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6338 } else 6339 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6340 if (phy->rev >= 2) 6341 bwn_dummy_transmission(mac, 0, 1); 6342 bwn_phy_g_switch_chan(mac, 6, 0); 6343 BWN_RF_READ(mac, 0x51); 6344 if (phy->type == BWN_PHYTYPE_G) 6345 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6346 6347 nanouptime(&ts); 6348 if (time_before(lo->txctl_measured_time, 6349 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6350 bwn_lo_measure_txctl_values(mac); 6351 6352 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6353 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6354 else { 6355 if (phy->type == BWN_PHYTYPE_B) 6356 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6357 else 6358 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6359 } 6360} 6361 6362static void 6363bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6364{ 6365 struct bwn_phy *phy = &mac->mac_phy; 6366 struct bwn_phy_g *pg = &phy->phy_g; 6367 uint16_t tmp; 6368 6369 if (phy->rev >= 2) { 6370 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6371 tmp = (pg->pg_pga_gain << 8); 6372 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6373 DELAY(5); 6374 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6375 DELAY(2); 6376 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6377 } else { 6378 tmp = (pg->pg_pga_gain | 0xefa0); 6379 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6380 } 6381 if (phy->type == BWN_PHYTYPE_G) { 6382 if (phy->rev >= 3) 6383 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6384 else 6385 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6386 if (phy->rev >= 2) 6387 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6388 else 6389 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6390 } 6391 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6392 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6393 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6394 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6395 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6396 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6397 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6398 if (!BWN_HAS_TXMAG(phy)) { 6399 tmp = sav->rf2; 6400 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6401 } 6402 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6403 if (phy->type == BWN_PHYTYPE_B && 6404 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6405 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6406 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6407 } 6408 if (phy->rev >= 2) { 6409 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6410 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6411 sav->phy_analogoverval); 6412 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6413 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6414 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6415 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6416 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6417 } 6418 if (bwn_has_hwpctl(mac)) { 6419 tmp = (sav->phy_lomask & 0xbfff); 6420 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6421 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6422 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6423 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6424 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6425 } 6426 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6427} 6428 6429static int 6430bwn_lo_probe_loctl(struct bwn_mac *mac, 6431 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6432{ 6433 struct bwn_phy *phy = &mac->mac_phy; 6434 struct bwn_phy_g *pg = &phy->phy_g; 6435 struct bwn_loctl orig, test; 6436 struct bwn_loctl prev = { -100, -100 }; 6437 static const struct bwn_loctl modifiers[] = { 6438 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6439 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6440 }; 6441 int begin, end, lower = 0, i; 6442 uint16_t feedth; 6443 6444 if (d->curstate == 0) { 6445 begin = 1; 6446 end = 8; 6447 } else if (d->curstate % 2 == 0) { 6448 begin = d->curstate - 1; 6449 end = d->curstate + 1; 6450 } else { 6451 begin = d->curstate - 2; 6452 end = d->curstate + 2; 6453 } 6454 if (begin < 1) 6455 begin += 8; 6456 if (end > 8) 6457 end -= 8; 6458 6459 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6460 i = begin; 6461 d->curstate = i; 6462 while (1) { 6463 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6464 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6465 test.i += modifiers[i - 1].i * d->multipler; 6466 test.q += modifiers[i - 1].q * d->multipler; 6467 if ((test.i != prev.i || test.q != prev.q) && 6468 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6469 bwn_lo_write(mac, &test); 6470 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6471 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6472 if (feedth < d->feedth) { 6473 memcpy(probe, &test, 6474 sizeof(struct bwn_loctl)); 6475 lower = 1; 6476 d->feedth = feedth; 6477 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6478 break; 6479 } 6480 } 6481 memcpy(&prev, &test, sizeof(prev)); 6482 if (i == end) 6483 break; 6484 if (i == 8) 6485 i = 1; 6486 else 6487 i++; 6488 d->curstate = i; 6489 } 6490 6491 return (lower); 6492} 6493 6494static void 6495bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6496{ 6497 struct bwn_phy *phy = &mac->mac_phy; 6498 struct bwn_phy_g *pg = &phy->phy_g; 6499 struct bwn_lo_g_sm d; 6500 struct bwn_loctl probe; 6501 int lower, repeat, cnt = 0; 6502 uint16_t feedth; 6503 6504 d.nmeasure = 0; 6505 d.multipler = 1; 6506 if (BWN_HAS_LOOPBACK(phy)) 6507 d.multipler = 3; 6508 6509 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6510 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6511 6512 do { 6513 bwn_lo_write(mac, &d.loctl); 6514 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6515 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6516 if (feedth < 0x258) { 6517 if (feedth >= 0x12c) 6518 *rxgain += 6; 6519 else 6520 *rxgain += 3; 6521 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6522 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6523 } 6524 d.feedth = feedth; 6525 d.curstate = 0; 6526 do { 6527 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6528 ("%s:%d: fail", __func__, __LINE__)); 6529 memcpy(&probe, &d.loctl, 6530 sizeof(struct bwn_loctl)); 6531 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6532 if (!lower) 6533 break; 6534 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6535 break; 6536 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6537 d.nmeasure++; 6538 } while (d.nmeasure < 24); 6539 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6540 6541 if (BWN_HAS_LOOPBACK(phy)) { 6542 if (d.feedth > 0x1194) 6543 *rxgain -= 6; 6544 else if (d.feedth < 0x5dc) 6545 *rxgain += 3; 6546 if (cnt == 0) { 6547 if (d.feedth <= 0x5dc) { 6548 d.multipler = 1; 6549 cnt++; 6550 } else 6551 d.multipler = 2; 6552 } else if (cnt == 2) 6553 d.multipler = 1; 6554 } 6555 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6556 } while (++cnt < repeat); 6557} 6558 6559static struct bwn_lo_calib * 6560bwn_lo_calibset(struct bwn_mac *mac, 6561 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6562{ 6563 struct bwn_phy *phy = &mac->mac_phy; 6564 struct bwn_phy_g *pg = &phy->phy_g; 6565 struct bwn_loctl loctl = { 0, 0 }; 6566 struct bwn_lo_calib *cal; 6567 struct bwn_lo_g_value sval = { 0 }; 6568 int rxgain; 6569 uint16_t pad, reg, value; 6570 6571 sval.old_channel = phy->chan; 6572 bwn_mac_suspend(mac); 6573 bwn_lo_save(mac, &sval); 6574 6575 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6576 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6577 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6578 6579 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6580 if (rfatt->padmix) 6581 rxgain -= pad; 6582 if (BWN_HAS_LOOPBACK(phy)) 6583 rxgain += pg->pg_max_lb_gain; 6584 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6585 bwn_phy_g_set_bbatt(mac, bbatt->att); 6586 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6587 6588 bwn_lo_restore(mac, &sval); 6589 bwn_mac_enable(mac); 6590 6591 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6592 if (!cal) { 6593 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6594 return (NULL); 6595 } 6596 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6597 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6598 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6599 6600 BWN_GETTIME(cal->calib_time); 6601 6602 return (cal); 6603} 6604 6605static struct bwn_lo_calib * 6606bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6607 const struct bwn_rfatt *rfatt) 6608{ 6609 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6610 struct bwn_lo_calib *c; 6611 6612 TAILQ_FOREACH(c, &lo->calib_list, list) { 6613 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6614 continue; 6615 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6616 continue; 6617 return (c); 6618 } 6619 6620 c = bwn_lo_calibset(mac, bbatt, rfatt); 6621 if (!c) 6622 return (NULL); 6623 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6624 6625 return (c); 6626} 6627 6628static void 6629bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6630{ 6631 struct bwn_phy *phy = &mac->mac_phy; 6632 struct bwn_phy_g *pg = &phy->phy_g; 6633 struct bwn_softc *sc = mac->mac_sc; 6634 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6635 const struct bwn_rfatt *rfatt; 6636 const struct bwn_bbatt *bbatt; 6637 uint64_t pvector; 6638 int i; 6639 int rf_offset, bb_offset; 6640 uint8_t changed = 0; 6641 6642 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6643 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6644 ("%s:%d: fail", __func__, __LINE__)); 6645 6646 pvector = lo->power_vector; 6647 if (!update && !pvector) 6648 return; 6649 6650 bwn_mac_suspend(mac); 6651 6652 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6653 struct bwn_lo_calib *cal; 6654 int idx; 6655 uint16_t val; 6656 6657 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6658 continue; 6659 bb_offset = i / lo->rfatt.len; 6660 rf_offset = i % lo->rfatt.len; 6661 bbatt = &(lo->bbatt.array[bb_offset]); 6662 rfatt = &(lo->rfatt.array[rf_offset]); 6663 6664 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6665 if (!cal) { 6666 device_printf(sc->sc_dev, "LO: Could not " 6667 "calibrate DC table entry\n"); 6668 continue; 6669 } 6670 val = (uint8_t)(cal->ctl.q); 6671 val |= ((uint8_t)(cal->ctl.i)) << 4; 6672 free(cal, M_DEVBUF); 6673 6674 idx = i / 2; 6675 if (i % 2) 6676 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6677 | ((val & 0x00ff) << 8); 6678 else 6679 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6680 | (val & 0x00ff); 6681 changed = 1; 6682 } 6683 if (changed) { 6684 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6685 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6686 } 6687 bwn_mac_enable(mac); 6688} 6689 6690static void 6691bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6692{ 6693 6694 if (!rf->padmix) 6695 return; 6696 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6697 rf->att = 4; 6698} 6699 6700static void 6701bwn_lo_g_adjust(struct bwn_mac *mac) 6702{ 6703 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6704 struct bwn_lo_calib *cal; 6705 struct bwn_rfatt rf; 6706 6707 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6708 bwn_lo_fixup_rfatt(&rf); 6709 6710 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6711 if (!cal) 6712 return; 6713 bwn_lo_write(mac, &cal->ctl); 6714} 6715 6716static void 6717bwn_lo_g_init(struct bwn_mac *mac) 6718{ 6719 6720 if (!bwn_has_hwpctl(mac)) 6721 return; 6722 6723 bwn_lo_get_powervector(mac); 6724 bwn_phy_g_dc_lookup_init(mac, 1); 6725} 6726 6727static void 6728bwn_mac_suspend(struct bwn_mac *mac) 6729{ 6730 struct bwn_softc *sc = mac->mac_sc; 6731 int i; 6732 uint32_t tmp; 6733 6734 KASSERT(mac->mac_suspended >= 0, 6735 ("%s:%d: fail", __func__, __LINE__)); 6736 6737 if (mac->mac_suspended == 0) { 6738 bwn_psctl(mac, BWN_PS_AWAKE); 6739 BWN_WRITE_4(mac, BWN_MACCTL, 6740 BWN_READ_4(mac, BWN_MACCTL) 6741 & ~BWN_MACCTL_ON); 6742 BWN_READ_4(mac, BWN_MACCTL); 6743 for (i = 35; i; i--) { 6744 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6745 if (tmp & BWN_INTR_MAC_SUSPENDED) 6746 goto out; 6747 DELAY(10); 6748 } 6749 for (i = 40; i; i--) { 6750 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6751 if (tmp & BWN_INTR_MAC_SUSPENDED) 6752 goto out; 6753 DELAY(1000); 6754 } 6755 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6756 } 6757out: 6758 mac->mac_suspended++; 6759} 6760 6761static void 6762bwn_mac_enable(struct bwn_mac *mac) 6763{ 6764 struct bwn_softc *sc = mac->mac_sc; 6765 uint16_t state; 6766 6767 state = bwn_shm_read_2(mac, BWN_SHARED, 6768 BWN_SHARED_UCODESTAT); 6769 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6770 state != BWN_SHARED_UCODESTAT_SLEEP) 6771 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6772 6773 mac->mac_suspended--; 6774 KASSERT(mac->mac_suspended >= 0, 6775 ("%s:%d: fail", __func__, __LINE__)); 6776 if (mac->mac_suspended == 0) { 6777 BWN_WRITE_4(mac, BWN_MACCTL, 6778 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6779 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6780 BWN_READ_4(mac, BWN_MACCTL); 6781 BWN_READ_4(mac, BWN_INTR_REASON); 6782 bwn_psctl(mac, 0); 6783 } 6784} 6785 6786static void 6787bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6788{ 6789 int i; 6790 uint16_t ucstat; 6791 6792 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6793 ("%s:%d: fail", __func__, __LINE__)); 6794 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6795 ("%s:%d: fail", __func__, __LINE__)); 6796 6797 /* XXX forcibly awake and hwps-off */ 6798 6799 BWN_WRITE_4(mac, BWN_MACCTL, 6800 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6801 ~BWN_MACCTL_HWPS); 6802 BWN_READ_4(mac, BWN_MACCTL); 6803 if (mac->mac_sd->sd_id.sd_rev >= 5) { 6804 for (i = 0; i < 100; i++) { 6805 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6806 BWN_SHARED_UCODESTAT); 6807 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6808 break; 6809 DELAY(10); 6810 } 6811 } 6812} 6813 6814static int16_t 6815bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6816{ 6817 6818 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6819 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6820} 6821 6822static void 6823bwn_nrssi_threshold(struct bwn_mac *mac) 6824{ 6825 struct bwn_phy *phy = &mac->mac_phy; 6826 struct bwn_phy_g *pg = &phy->phy_g; 6827 struct siba_softc *siba = mac->mac_sd->sd_bus; 6828 int32_t a, b; 6829 int16_t tmp16; 6830 uint16_t tmpu16; 6831 6832 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6833 6834 if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) { 6835 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6836 a = 0x13; 6837 b = 0x12; 6838 } else { 6839 a = 0xe; 6840 b = 0x11; 6841 } 6842 6843 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6844 a += (pg->pg_nrssi[0] << 6); 6845 a += (a < 32) ? 31 : 32; 6846 a = a >> 6; 6847 a = MIN(MAX(a, -31), 31); 6848 6849 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6850 b += (pg->pg_nrssi[0] << 6); 6851 if (b < 32) 6852 b += 31; 6853 else 6854 b += 32; 6855 b = b >> 6; 6856 b = MIN(MAX(b, -31), 31); 6857 6858 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6859 tmpu16 |= ((uint32_t)b & 0x0000003f); 6860 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6861 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6862 return; 6863 } 6864 6865 tmp16 = bwn_nrssi_read(mac, 0x20); 6866 if (tmp16 >= 0x20) 6867 tmp16 -= 0x40; 6868 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6869} 6870 6871static void 6872bwn_nrssi_slope_11g(struct bwn_mac *mac) 6873{ 6874#define SAVE_RF_MAX 3 6875#define SAVE_PHY_COMM_MAX 4 6876#define SAVE_PHY3_MAX 8 6877 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6878 { 0x7a, 0x52, 0x43 }; 6879 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6880 { 0x15, 0x5a, 0x59, 0x58 }; 6881 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6882 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6883 0x0801, 0x0060, 0x0014, 0x0478 6884 }; 6885 struct bwn_phy *phy = &mac->mac_phy; 6886 struct bwn_phy_g *pg = &phy->phy_g; 6887 int32_t i, tmp32, phy3_idx = 0; 6888 uint16_t delta, tmp; 6889 uint16_t save_rf[SAVE_RF_MAX]; 6890 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6891 uint16_t save_phy3[SAVE_PHY3_MAX]; 6892 uint16_t ant_div, phy0, chan_ex; 6893 int16_t nrssi0, nrssi1; 6894 6895 KASSERT(phy->type == BWN_PHYTYPE_G, 6896 ("%s:%d: fail", __func__, __LINE__)); 6897 6898 if (phy->rf_rev >= 9) 6899 return; 6900 if (phy->rf_rev == 8) 6901 bwn_nrssi_offset(mac); 6902 6903 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6904 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6905 6906 /* 6907 * Save RF/PHY registers for later restoration 6908 */ 6909 ant_div = BWN_READ_2(mac, 0x03e2); 6910 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6911 for (i = 0; i < SAVE_RF_MAX; ++i) 6912 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6913 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6914 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6915 6916 phy0 = BWN_READ_2(mac, BWN_PHY0); 6917 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6918 if (phy->rev >= 3) { 6919 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6920 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6921 BWN_PHY_WRITE(mac, 0x002e, 0); 6922 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6923 switch (phy->rev) { 6924 case 4: 6925 case 6: 6926 case 7: 6927 BWN_PHY_SET(mac, 0x0478, 0x0100); 6928 BWN_PHY_SET(mac, 0x0801, 0x0040); 6929 break; 6930 case 3: 6931 case 5: 6932 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6933 break; 6934 } 6935 BWN_PHY_SET(mac, 0x0060, 0x0040); 6936 BWN_PHY_SET(mac, 0x0014, 0x0200); 6937 } 6938 /* 6939 * Calculate nrssi0 6940 */ 6941 BWN_RF_SET(mac, 0x007a, 0x0070); 6942 bwn_set_all_gains(mac, 0, 8, 0); 6943 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6944 if (phy->rev >= 2) { 6945 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6946 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6947 } 6948 BWN_RF_SET(mac, 0x007a, 0x0080); 6949 DELAY(20); 6950 6951 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6952 if (nrssi0 >= 0x0020) 6953 nrssi0 -= 0x0040; 6954 6955 /* 6956 * Calculate nrssi1 6957 */ 6958 BWN_RF_MASK(mac, 0x007a, 0x007f); 6959 if (phy->rev >= 2) 6960 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6961 6962 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6963 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6964 BWN_RF_SET(mac, 0x007a, 0x000f); 6965 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6966 if (phy->rev >= 2) { 6967 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6968 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6969 } 6970 6971 bwn_set_all_gains(mac, 3, 0, 1); 6972 if (phy->rf_rev == 8) { 6973 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6974 } else { 6975 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6976 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6977 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6978 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6979 } 6980 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6981 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6982 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6983 DELAY(20); 6984 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6985 6986 /* 6987 * Install calculated narrow RSSI values 6988 */ 6989 if (nrssi1 >= 0x0020) 6990 nrssi1 -= 0x0040; 6991 if (nrssi0 == nrssi1) 6992 pg->pg_nrssi_slope = 0x00010000; 6993 else 6994 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6995 if (nrssi0 >= -4) { 6996 pg->pg_nrssi[0] = nrssi1; 6997 pg->pg_nrssi[1] = nrssi0; 6998 } 6999 7000 /* 7001 * Restore saved RF/PHY registers 7002 */ 7003 if (phy->rev >= 3) { 7004 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 7005 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7006 save_phy3[phy3_idx]); 7007 } 7008 } 7009 if (phy->rev >= 2) { 7010 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 7011 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 7012 } 7013 7014 for (i = 0; i < SAVE_RF_MAX; ++i) 7015 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7016 7017 BWN_WRITE_2(mac, 0x03e2, ant_div); 7018 BWN_WRITE_2(mac, 0x03e6, phy0); 7019 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 7020 7021 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7022 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7023 7024 bwn_spu_workaround(mac, phy->chan); 7025 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 7026 bwn_set_original_gains(mac); 7027 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 7028 if (phy->rev >= 3) { 7029 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 7030 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 7031 save_phy3[phy3_idx]); 7032 } 7033 } 7034 7035 delta = 0x1f - pg->pg_nrssi[0]; 7036 for (i = 0; i < 64; i++) { 7037 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 7038 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 7039 pg->pg_nrssi_lt[i] = tmp32; 7040 } 7041 7042 bwn_nrssi_threshold(mac); 7043#undef SAVE_RF_MAX 7044#undef SAVE_PHY_COMM_MAX 7045#undef SAVE_PHY3_MAX 7046} 7047 7048static void 7049bwn_nrssi_offset(struct bwn_mac *mac) 7050{ 7051#define SAVE_RF_MAX 2 7052#define SAVE_PHY_COMM_MAX 10 7053#define SAVE_PHY6_MAX 8 7054 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 7055 { 0x7a, 0x43 }; 7056 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 7057 0x0001, 0x0811, 0x0812, 0x0814, 7058 0x0815, 0x005a, 0x0059, 0x0058, 7059 0x000a, 0x0003 7060 }; 7061 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 7062 0x002e, 0x002f, 0x080f, 0x0810, 7063 0x0801, 0x0060, 0x0014, 0x0478 7064 }; 7065 struct bwn_phy *phy = &mac->mac_phy; 7066 int i, phy6_idx = 0; 7067 uint16_t save_rf[SAVE_RF_MAX]; 7068 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 7069 uint16_t save_phy6[SAVE_PHY6_MAX]; 7070 int16_t nrssi; 7071 uint16_t saved = 0xffff; 7072 7073 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 7074 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 7075 for (i = 0; i < SAVE_RF_MAX; ++i) 7076 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 7077 7078 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 7079 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 7080 BWN_PHY_SET(mac, 0x0811, 0x000c); 7081 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 7082 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 7083 if (phy->rev >= 6) { 7084 for (i = 0; i < SAVE_PHY6_MAX; ++i) 7085 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 7086 7087 BWN_PHY_WRITE(mac, 0x002e, 0); 7088 BWN_PHY_WRITE(mac, 0x002f, 0); 7089 BWN_PHY_WRITE(mac, 0x080f, 0); 7090 BWN_PHY_WRITE(mac, 0x0810, 0); 7091 BWN_PHY_SET(mac, 0x0478, 0x0100); 7092 BWN_PHY_SET(mac, 0x0801, 0x0040); 7093 BWN_PHY_SET(mac, 0x0060, 0x0040); 7094 BWN_PHY_SET(mac, 0x0014, 0x0200); 7095 } 7096 BWN_RF_SET(mac, 0x007a, 0x0070); 7097 BWN_RF_SET(mac, 0x007a, 0x0080); 7098 DELAY(30); 7099 7100 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7101 if (nrssi >= 0x20) 7102 nrssi -= 0x40; 7103 if (nrssi == 31) { 7104 for (i = 7; i >= 4; i--) { 7105 BWN_RF_WRITE(mac, 0x007b, i); 7106 DELAY(20); 7107 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7108 0x003f); 7109 if (nrssi >= 0x20) 7110 nrssi -= 0x40; 7111 if (nrssi < 31 && saved == 0xffff) 7112 saved = i; 7113 } 7114 if (saved == 0xffff) 7115 saved = 4; 7116 } else { 7117 BWN_RF_MASK(mac, 0x007a, 0x007f); 7118 if (phy->rev != 1) { 7119 BWN_PHY_SET(mac, 0x0814, 0x0001); 7120 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7121 } 7122 BWN_PHY_SET(mac, 0x0811, 0x000c); 7123 BWN_PHY_SET(mac, 0x0812, 0x000c); 7124 BWN_PHY_SET(mac, 0x0811, 0x0030); 7125 BWN_PHY_SET(mac, 0x0812, 0x0030); 7126 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7127 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7128 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7129 if (phy->rev == 0) 7130 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7131 else 7132 BWN_PHY_SET(mac, 0x000a, 0x2000); 7133 if (phy->rev != 1) { 7134 BWN_PHY_SET(mac, 0x0814, 0x0004); 7135 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7136 } 7137 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7138 BWN_RF_SET(mac, 0x007a, 0x000f); 7139 bwn_set_all_gains(mac, 3, 0, 1); 7140 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7141 DELAY(30); 7142 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7143 if (nrssi >= 0x20) 7144 nrssi -= 0x40; 7145 if (nrssi == -32) { 7146 for (i = 0; i < 4; i++) { 7147 BWN_RF_WRITE(mac, 0x007b, i); 7148 DELAY(20); 7149 nrssi = (int16_t)((BWN_PHY_READ(mac, 7150 0x047f) >> 8) & 0x003f); 7151 if (nrssi >= 0x20) 7152 nrssi -= 0x40; 7153 if (nrssi > -31 && saved == 0xffff) 7154 saved = i; 7155 } 7156 if (saved == 0xffff) 7157 saved = 3; 7158 } else 7159 saved = 0; 7160 } 7161 BWN_RF_WRITE(mac, 0x007b, saved); 7162 7163 /* 7164 * Restore saved RF/PHY registers 7165 */ 7166 if (phy->rev >= 6) { 7167 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7168 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7169 save_phy6[phy6_idx]); 7170 } 7171 } 7172 if (phy->rev != 1) { 7173 for (i = 3; i < 5; i++) 7174 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7175 save_phy_comm[i]); 7176 } 7177 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7178 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7179 7180 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7181 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7182 7183 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7184 BWN_PHY_SET(mac, 0x0429, 0x8000); 7185 bwn_set_original_gains(mac); 7186 if (phy->rev >= 6) { 7187 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7188 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7189 save_phy6[phy6_idx]); 7190 } 7191 } 7192 7193 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7194 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7195 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7196} 7197 7198static void 7199bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7200 int16_t third) 7201{ 7202 struct bwn_phy *phy = &mac->mac_phy; 7203 uint16_t i; 7204 uint16_t start = 0x08, end = 0x18; 7205 uint16_t tmp; 7206 uint16_t table; 7207 7208 if (phy->rev <= 1) { 7209 start = 0x10; 7210 end = 0x20; 7211 } 7212 7213 table = BWN_OFDMTAB_GAINX; 7214 if (phy->rev <= 1) 7215 table = BWN_OFDMTAB_GAINX_R1; 7216 for (i = 0; i < 4; i++) 7217 bwn_ofdmtab_write_2(mac, table, i, first); 7218 7219 for (i = start; i < end; i++) 7220 bwn_ofdmtab_write_2(mac, table, i, second); 7221 7222 if (third != -1) { 7223 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7224 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7225 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7226 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7227 } 7228 bwn_dummy_transmission(mac, 0, 1); 7229} 7230 7231static void 7232bwn_set_original_gains(struct bwn_mac *mac) 7233{ 7234 struct bwn_phy *phy = &mac->mac_phy; 7235 uint16_t i, tmp; 7236 uint16_t table; 7237 uint16_t start = 0x0008, end = 0x0018; 7238 7239 if (phy->rev <= 1) { 7240 start = 0x0010; 7241 end = 0x0020; 7242 } 7243 7244 table = BWN_OFDMTAB_GAINX; 7245 if (phy->rev <= 1) 7246 table = BWN_OFDMTAB_GAINX_R1; 7247 for (i = 0; i < 4; i++) { 7248 tmp = (i & 0xfffc); 7249 tmp |= (i & 0x0001) << 1; 7250 tmp |= (i & 0x0002) >> 1; 7251 7252 bwn_ofdmtab_write_2(mac, table, i, tmp); 7253 } 7254 7255 for (i = start; i < end; i++) 7256 bwn_ofdmtab_write_2(mac, table, i, i - start); 7257 7258 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7259 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7260 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7261 bwn_dummy_transmission(mac, 0, 1); 7262} 7263 7264static void 7265bwn_phy_hwpctl_init(struct bwn_mac *mac) 7266{ 7267 struct siba_softc *bus = mac->mac_sd->sd_bus; 7268 struct bwn_phy *phy = &mac->mac_phy; 7269 struct bwn_phy_g *pg = &phy->phy_g; 7270 struct bwn_rfatt old_rfatt, rfatt; 7271 struct bwn_bbatt old_bbatt, bbatt; 7272 uint8_t old_txctl = 0; 7273 7274 KASSERT(phy->type == BWN_PHYTYPE_G, 7275 ("%s:%d: fail", __func__, __LINE__)); 7276 7277 if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) && 7278 (bus->siba_board_type == SIBA_BOARD_BU4306)) 7279 return; 7280 7281 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7282 7283 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7284 7285 if (!phy->gmode) 7286 return; 7287 bwn_hwpctl_early_init(mac); 7288 if (pg->pg_curtssi == 0) { 7289 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7290 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7291 } else { 7292 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7293 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7294 old_txctl = pg->pg_txctl; 7295 7296 bbatt.att = 11; 7297 if (phy->rf_rev == 8) { 7298 rfatt.att = 15; 7299 rfatt.padmix = 1; 7300 } else { 7301 rfatt.att = 9; 7302 rfatt.padmix = 0; 7303 } 7304 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7305 } 7306 bwn_dummy_transmission(mac, 0, 1); 7307 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7308 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7309 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7310 else 7311 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7312 &old_rfatt, old_txctl); 7313 } 7314 bwn_hwpctl_init_gphy(mac); 7315 7316 /* clear TSSI */ 7317 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7318 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7319 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7320 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7321} 7322 7323static void 7324bwn_hwpctl_early_init(struct bwn_mac *mac) 7325{ 7326 struct bwn_phy *phy = &mac->mac_phy; 7327 7328 if (!bwn_has_hwpctl(mac)) { 7329 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7330 return; 7331 } 7332 7333 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7334 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7335 BWN_PHY_SET(mac, 0x047c, 0x0002); 7336 BWN_PHY_SET(mac, 0x047a, 0xf000); 7337 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7338 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7339 BWN_PHY_SET(mac, 0x005d, 0x8000); 7340 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7341 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7342 BWN_PHY_SET(mac, 0x0036, 0x0400); 7343 } else { 7344 BWN_PHY_SET(mac, 0x0036, 0x0200); 7345 BWN_PHY_SET(mac, 0x0036, 0x0400); 7346 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7347 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7348 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7349 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7350 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7351 } 7352} 7353 7354static void 7355bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7356{ 7357 struct bwn_phy *phy = &mac->mac_phy; 7358 struct bwn_phy_g *pg = &phy->phy_g; 7359 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7360 int i; 7361 uint16_t nr_written = 0, tmp, value; 7362 uint8_t rf, bb; 7363 7364 if (!bwn_has_hwpctl(mac)) { 7365 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7366 return; 7367 } 7368 7369 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7370 (pg->pg_idletssi - pg->pg_curtssi)); 7371 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7372 (pg->pg_idletssi - pg->pg_curtssi)); 7373 7374 for (i = 0; i < 32; i++) 7375 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7376 for (i = 32; i < 64; i++) 7377 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7378 for (i = 0; i < 64; i += 2) { 7379 value = (uint16_t) pg->pg_tssi2dbm[i]; 7380 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7381 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7382 } 7383 7384 for (rf = 0; rf < lo->rfatt.len; rf++) { 7385 for (bb = 0; bb < lo->bbatt.len; bb++) { 7386 if (nr_written >= 0x40) 7387 return; 7388 tmp = lo->bbatt.array[bb].att; 7389 tmp <<= 8; 7390 if (phy->rf_rev == 8) 7391 tmp |= 0x50; 7392 else 7393 tmp |= 0x40; 7394 tmp |= lo->rfatt.array[rf].att; 7395 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7396 nr_written++; 7397 } 7398 } 7399 7400 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7401 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7402 7403 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7404 BWN_PHY_SET(mac, 0x0478, 0x0800); 7405 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7406 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7407 7408 bwn_phy_g_dc_lookup_init(mac, 1); 7409 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7410} 7411 7412static void 7413bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7414{ 7415 struct siba_softc *siba = mac->mac_sd->sd_bus; 7416 7417 if (spu != 0) 7418 bwn_spu_workaround(mac, channel); 7419 7420 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7421 7422 if (channel == 14) { 7423 if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN) 7424 bwn_hf_write(mac, 7425 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7426 else 7427 bwn_hf_write(mac, 7428 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7429 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7430 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7431 return; 7432 } 7433 7434 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7435 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7436} 7437 7438static uint16_t 7439bwn_phy_g_chan2freq(uint8_t channel) 7440{ 7441 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7442 7443 KASSERT(channel >= 1 && channel <= 14, 7444 ("%s:%d: fail", __func__, __LINE__)); 7445 7446 return (bwn_phy_g_rf_channels[channel - 1]); 7447} 7448 7449static void 7450bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7451 const struct bwn_rfatt *rfatt, uint8_t txctl) 7452{ 7453 struct bwn_phy *phy = &mac->mac_phy; 7454 struct bwn_phy_g *pg = &phy->phy_g; 7455 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7456 uint16_t bb, rf; 7457 uint16_t tx_bias, tx_magn; 7458 7459 bb = bbatt->att; 7460 rf = rfatt->att; 7461 tx_bias = lo->tx_bias; 7462 tx_magn = lo->tx_magn; 7463 if (tx_bias == 0xff) 7464 tx_bias = 0; 7465 7466 pg->pg_txctl = txctl; 7467 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7468 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7469 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7470 bwn_phy_g_set_bbatt(mac, bb); 7471 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7472 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7473 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7474 else { 7475 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7476 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7477 } 7478 if (BWN_HAS_TXMAG(phy)) 7479 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7480 else 7481 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7482 bwn_lo_g_adjust(mac); 7483} 7484 7485static void 7486bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7487 uint16_t bbatt) 7488{ 7489 struct bwn_phy *phy = &mac->mac_phy; 7490 7491 if (phy->analog == 0) { 7492 BWN_WRITE_2(mac, BWN_PHY0, 7493 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7494 return; 7495 } 7496 if (phy->analog > 1) { 7497 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7498 return; 7499 } 7500 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7501} 7502 7503static uint16_t 7504bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7505{ 7506 struct bwn_phy *phy = &mac->mac_phy; 7507 struct bwn_phy_g *pg = &phy->phy_g; 7508 struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom); 7509 int max_lb_gain; 7510 uint16_t extlna; 7511 uint16_t i; 7512 7513 if (phy->gmode == 0) 7514 return (0); 7515 7516 if (BWN_HAS_LOOPBACK(phy)) { 7517 max_lb_gain = pg->pg_max_lb_gain; 7518 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7519 if (max_lb_gain >= 0x46) { 7520 extlna = 0x3000; 7521 max_lb_gain -= 0x46; 7522 } else if (max_lb_gain >= 0x3a) { 7523 extlna = 0x1000; 7524 max_lb_gain -= 0x3a; 7525 } else if (max_lb_gain >= 0x2e) { 7526 extlna = 0x2000; 7527 max_lb_gain -= 0x2e; 7528 } else { 7529 extlna = 0; 7530 max_lb_gain -= 0x10; 7531 } 7532 7533 for (i = 0; i < 16; i++) { 7534 max_lb_gain -= (i * 6); 7535 if (max_lb_gain < 6) 7536 break; 7537 } 7538 7539 if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7540 if (reg == BWN_PHY_RFOVER) { 7541 return (0x1b3); 7542 } else if (reg == BWN_PHY_RFOVERVAL) { 7543 extlna |= (i << 8); 7544 switch (lpd) { 7545 case BWN_LPD(0, 1, 1): 7546 return (0x0f92); 7547 case BWN_LPD(0, 0, 1): 7548 case BWN_LPD(1, 0, 1): 7549 return (0x0092 | extlna); 7550 case BWN_LPD(1, 0, 0): 7551 return (0x0093 | extlna); 7552 } 7553 KASSERT(0 == 1, 7554 ("%s:%d: fail", __func__, __LINE__)); 7555 } 7556 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7557 } else { 7558 if (reg == BWN_PHY_RFOVER) 7559 return (0x9b3); 7560 if (reg == BWN_PHY_RFOVERVAL) { 7561 if (extlna) 7562 extlna |= 0x8000; 7563 extlna |= (i << 8); 7564 switch (lpd) { 7565 case BWN_LPD(0, 1, 1): 7566 return (0x8f92); 7567 case BWN_LPD(0, 0, 1): 7568 return (0x8092 | extlna); 7569 case BWN_LPD(1, 0, 1): 7570 return (0x2092 | extlna); 7571 case BWN_LPD(1, 0, 0): 7572 return (0x2093 | extlna); 7573 } 7574 KASSERT(0 == 1, 7575 ("%s:%d: fail", __func__, __LINE__)); 7576 } 7577 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7578 } 7579 return (0); 7580 } 7581 7582 if ((phy->rev < 7) || 7583 !(sprom->bf_lo & BWN_BFL_EXTLNA)) { 7584 if (reg == BWN_PHY_RFOVER) { 7585 return (0x1b3); 7586 } else if (reg == BWN_PHY_RFOVERVAL) { 7587 switch (lpd) { 7588 case BWN_LPD(0, 1, 1): 7589 return (0x0fb2); 7590 case BWN_LPD(0, 0, 1): 7591 return (0x00b2); 7592 case BWN_LPD(1, 0, 1): 7593 return (0x30b2); 7594 case BWN_LPD(1, 0, 0): 7595 return (0x30b3); 7596 } 7597 KASSERT(0 == 1, 7598 ("%s:%d: fail", __func__, __LINE__)); 7599 } 7600 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7601 } else { 7602 if (reg == BWN_PHY_RFOVER) { 7603 return (0x9b3); 7604 } else if (reg == BWN_PHY_RFOVERVAL) { 7605 switch (lpd) { 7606 case BWN_LPD(0, 1, 1): 7607 return (0x8fb2); 7608 case BWN_LPD(0, 0, 1): 7609 return (0x80b2); 7610 case BWN_LPD(1, 0, 1): 7611 return (0x20b2); 7612 case BWN_LPD(1, 0, 0): 7613 return (0x20b3); 7614 } 7615 KASSERT(0 == 1, 7616 ("%s:%d: fail", __func__, __LINE__)); 7617 } 7618 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7619 } 7620 return (0); 7621} 7622 7623static void 7624bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7625{ 7626 7627 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7628 return; 7629 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7630 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7631 DELAY(1000); 7632 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7633} 7634 7635static int 7636bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7637{ 7638 struct bwn_softc *sc = mac->mac_sc; 7639 struct bwn_fw *fw = &mac->mac_fw; 7640 const uint8_t rev = mac->mac_sd->sd_id.sd_rev; 7641 const char *filename; 7642 uint32_t high; 7643 int error; 7644 7645 /* microcode */ 7646 if (rev >= 5 && rev <= 10) 7647 filename = "ucode5"; 7648 else if (rev >= 11 && rev <= 12) 7649 filename = "ucode11"; 7650 else if (rev == 13) 7651 filename = "ucode13"; 7652 else if (rev == 14) 7653 filename = "ucode14"; 7654 else if (rev >= 15) 7655 filename = "ucode15"; 7656 else { 7657 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7658 bwn_release_firmware(mac); 7659 return (EOPNOTSUPP); 7660 } 7661 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7662 if (error) { 7663 bwn_release_firmware(mac); 7664 return (error); 7665 } 7666 7667 /* PCM */ 7668 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7669 if (rev >= 5 && rev <= 10) { 7670 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7671 if (error == ENOENT) 7672 fw->no_pcmfile = 1; 7673 else if (error) { 7674 bwn_release_firmware(mac); 7675 return (error); 7676 } 7677 } else if (rev < 11) { 7678 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7679 return (EOPNOTSUPP); 7680 } 7681 7682 /* initvals */ 7683 high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH); 7684 switch (mac->mac_phy.type) { 7685 case BWN_PHYTYPE_A: 7686 if (rev < 5 || rev > 10) 7687 goto fail1; 7688 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7689 filename = "a0g1initvals5"; 7690 else 7691 filename = "a0g0initvals5"; 7692 break; 7693 case BWN_PHYTYPE_G: 7694 if (rev >= 5 && rev <= 10) 7695 filename = "b0g0initvals5"; 7696 else if (rev >= 13) 7697 filename = "b0g0initvals13"; 7698 else 7699 goto fail1; 7700 break; 7701 case BWN_PHYTYPE_LP: 7702 if (rev == 13) 7703 filename = "lp0initvals13"; 7704 else if (rev == 14) 7705 filename = "lp0initvals14"; 7706 else if (rev >= 15) 7707 filename = "lp0initvals15"; 7708 else 7709 goto fail1; 7710 break; 7711 case BWN_PHYTYPE_N: 7712 if (rev >= 11 && rev <= 12) 7713 filename = "n0initvals11"; 7714 else 7715 goto fail1; 7716 break; 7717 default: 7718 goto fail1; 7719 } 7720 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7721 if (error) { 7722 bwn_release_firmware(mac); 7723 return (error); 7724 } 7725 7726 /* bandswitch initvals */ 7727 switch (mac->mac_phy.type) { 7728 case BWN_PHYTYPE_A: 7729 if (rev >= 5 && rev <= 10) { 7730 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7731 filename = "a0g1bsinitvals5"; 7732 else 7733 filename = "a0g0bsinitvals5"; 7734 } else if (rev >= 11) 7735 filename = NULL; 7736 else 7737 goto fail1; 7738 break; 7739 case BWN_PHYTYPE_G: 7740 if (rev >= 5 && rev <= 10) 7741 filename = "b0g0bsinitvals5"; 7742 else if (rev >= 11) 7743 filename = NULL; 7744 else 7745 goto fail1; 7746 break; 7747 case BWN_PHYTYPE_LP: 7748 if (rev == 13) 7749 filename = "lp0bsinitvals13"; 7750 else if (rev == 14) 7751 filename = "lp0bsinitvals14"; 7752 else if (rev >= 15) 7753 filename = "lp0bsinitvals15"; 7754 else 7755 goto fail1; 7756 break; 7757 case BWN_PHYTYPE_N: 7758 if (rev >= 11 && rev <= 12) 7759 filename = "n0bsinitvals11"; 7760 else 7761 goto fail1; 7762 break; 7763 default: 7764 goto fail1; 7765 } 7766 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7767 if (error) { 7768 bwn_release_firmware(mac); 7769 return (error); 7770 } 7771 return (0); 7772fail1: 7773 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7774 bwn_release_firmware(mac); 7775 return (EOPNOTSUPP); 7776} 7777 7778static int 7779bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7780 const char *name, struct bwn_fwfile *bfw) 7781{ 7782 const struct bwn_fwhdr *hdr; 7783 struct bwn_softc *sc = mac->mac_sc; 7784 const struct firmware *fw; 7785 char namebuf[64]; 7786 7787 if (name == NULL) { 7788 bwn_do_release_fw(bfw); 7789 return (0); 7790 } 7791 if (bfw->filename != NULL) { 7792 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7793 return (0); 7794 bwn_do_release_fw(bfw); 7795 } 7796 7797 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s", 7798 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name); 7799 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7800 fw = firmware_get(namebuf); 7801 if (fw == NULL) { 7802 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7803 namebuf); 7804 return (ENOENT); 7805 } 7806 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7807 goto fail; 7808 hdr = (const struct bwn_fwhdr *)(fw->data); 7809 switch (hdr->type) { 7810 case BWN_FWTYPE_UCODE: 7811 case BWN_FWTYPE_PCM: 7812 if (be32toh(hdr->size) != 7813 (fw->datasize - sizeof(struct bwn_fwhdr))) 7814 goto fail; 7815 /* FALLTHROUGH */ 7816 case BWN_FWTYPE_IV: 7817 if (hdr->ver != 1) 7818 goto fail; 7819 break; 7820 default: 7821 goto fail; 7822 } 7823 bfw->filename = name; 7824 bfw->fw = fw; 7825 bfw->type = type; 7826 return (0); 7827fail: 7828 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7829 if (fw != NULL) 7830 firmware_put(fw, FIRMWARE_UNLOAD); 7831 return (EPROTO); 7832} 7833 7834static void 7835bwn_release_firmware(struct bwn_mac *mac) 7836{ 7837 7838 bwn_do_release_fw(&mac->mac_fw.ucode); 7839 bwn_do_release_fw(&mac->mac_fw.pcm); 7840 bwn_do_release_fw(&mac->mac_fw.initvals); 7841 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7842} 7843 7844static void 7845bwn_do_release_fw(struct bwn_fwfile *bfw) 7846{ 7847 7848 if (bfw->fw != NULL) 7849 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7850 bfw->fw = NULL; 7851 bfw->filename = NULL; 7852} 7853 7854static int 7855bwn_fw_loaducode(struct bwn_mac *mac) 7856{ 7857#define GETFWOFFSET(fwp, offset) \ 7858 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7859#define GETFWSIZE(fwp, offset) \ 7860 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7861 struct bwn_softc *sc = mac->mac_sc; 7862 const uint32_t *data; 7863 unsigned int i; 7864 uint32_t ctl; 7865 uint16_t date, fwcaps, time; 7866 int error = 0; 7867 7868 ctl = BWN_READ_4(mac, BWN_MACCTL); 7869 ctl |= BWN_MACCTL_MCODE_JMP0; 7870 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7871 __LINE__)); 7872 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7873 for (i = 0; i < 64; i++) 7874 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7875 for (i = 0; i < 4096; i += 2) 7876 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7877 7878 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7879 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7880 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7881 i++) { 7882 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7883 DELAY(10); 7884 } 7885 7886 if (mac->mac_fw.pcm.fw) { 7887 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7888 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7889 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7890 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7891 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7892 sizeof(struct bwn_fwhdr)); i++) { 7893 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7894 DELAY(10); 7895 } 7896 } 7897 7898 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7899 BWN_WRITE_4(mac, BWN_MACCTL, 7900 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7901 BWN_MACCTL_MCODE_RUN); 7902 7903 for (i = 0; i < 21; i++) { 7904 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7905 break; 7906 if (i >= 20) { 7907 device_printf(sc->sc_dev, "ucode timeout\n"); 7908 error = ENXIO; 7909 goto error; 7910 } 7911 DELAY(50000); 7912 } 7913 BWN_READ_4(mac, BWN_INTR_REASON); 7914 7915 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7916 if (mac->mac_fw.rev <= 0x128) { 7917 device_printf(sc->sc_dev, "the firmware is too old\n"); 7918 error = EOPNOTSUPP; 7919 goto error; 7920 } 7921 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7922 BWN_SHARED_UCODE_PATCH); 7923 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7924 mac->mac_fw.opensource = (date == 0xffff); 7925 if (bwn_wme != 0) 7926 mac->mac_flags |= BWN_MAC_FLAG_WME; 7927 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7928 7929 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7930 if (mac->mac_fw.opensource == 0) { 7931 device_printf(sc->sc_dev, 7932 "firmware version (rev %u patch %u date %#x time %#x)\n", 7933 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7934 if (mac->mac_fw.no_pcmfile) 7935 device_printf(sc->sc_dev, 7936 "no HW crypto acceleration due to pcm5\n"); 7937 } else { 7938 mac->mac_fw.patch = time; 7939 fwcaps = bwn_fwcaps_read(mac); 7940 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7941 device_printf(sc->sc_dev, 7942 "disabling HW crypto acceleration\n"); 7943 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7944 } 7945 if (!(fwcaps & BWN_FWCAPS_WME)) { 7946 device_printf(sc->sc_dev, "disabling WME support\n"); 7947 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7948 } 7949 } 7950 7951 if (BWN_ISOLDFMT(mac)) 7952 device_printf(sc->sc_dev, "using old firmware image\n"); 7953 7954 return (0); 7955 7956error: 7957 BWN_WRITE_4(mac, BWN_MACCTL, 7958 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7959 BWN_MACCTL_MCODE_JMP0); 7960 7961 return (error); 7962#undef GETFWSIZE 7963#undef GETFWOFFSET 7964} 7965 7966/* OpenFirmware only */ 7967static uint16_t 7968bwn_fwcaps_read(struct bwn_mac *mac) 7969{ 7970 7971 KASSERT(mac->mac_fw.opensource == 1, 7972 ("%s:%d: fail", __func__, __LINE__)); 7973 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7974} 7975 7976static int 7977bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7978 size_t count, size_t array_size) 7979{ 7980#define GET_NEXTIV16(iv) \ 7981 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7982 sizeof(uint16_t) + sizeof(uint16_t))) 7983#define GET_NEXTIV32(iv) \ 7984 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7985 sizeof(uint16_t) + sizeof(uint32_t))) 7986 struct bwn_softc *sc = mac->mac_sc; 7987 const struct bwn_fwinitvals *iv; 7988 uint16_t offset; 7989 size_t i; 7990 uint8_t bit32; 7991 7992 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7993 ("%s:%d: fail", __func__, __LINE__)); 7994 iv = ivals; 7995 for (i = 0; i < count; i++) { 7996 if (array_size < sizeof(iv->offset_size)) 7997 goto fail; 7998 array_size -= sizeof(iv->offset_size); 7999 offset = be16toh(iv->offset_size); 8000 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 8001 offset &= BWN_FWINITVALS_OFFSET_MASK; 8002 if (offset >= 0x1000) 8003 goto fail; 8004 if (bit32) { 8005 if (array_size < sizeof(iv->data.d32)) 8006 goto fail; 8007 array_size -= sizeof(iv->data.d32); 8008 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 8009 iv = GET_NEXTIV32(iv); 8010 } else { 8011 8012 if (array_size < sizeof(iv->data.d16)) 8013 goto fail; 8014 array_size -= sizeof(iv->data.d16); 8015 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 8016 8017 iv = GET_NEXTIV16(iv); 8018 } 8019 } 8020 if (array_size != 0) 8021 goto fail; 8022 return (0); 8023fail: 8024 device_printf(sc->sc_dev, "initvals: invalid format\n"); 8025 return (EPROTO); 8026#undef GET_NEXTIV16 8027#undef GET_NEXTIV32 8028} 8029 8030static int 8031bwn_switch_channel(struct bwn_mac *mac, int chan) 8032{ 8033 struct bwn_phy *phy = &(mac->mac_phy); 8034 struct bwn_softc *sc = mac->mac_sc; 8035 struct ifnet *ifp = sc->sc_ifp; 8036 struct ieee80211com *ic = ifp->if_l2com; 8037 uint16_t channelcookie, savedcookie; 8038 int error; 8039 8040 if (chan == 0xffff) 8041 chan = phy->get_default_chan(mac); 8042 8043 channelcookie = chan; 8044 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 8045 channelcookie |= 0x100; 8046 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 8047 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 8048 error = phy->switch_channel(mac, chan); 8049 if (error) 8050 goto fail; 8051 8052 mac->mac_phy.chan = chan; 8053 DELAY(8000); 8054 return (0); 8055fail: 8056 device_printf(sc->sc_dev, "failed to switch channel\n"); 8057 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 8058 return (error); 8059} 8060 8061static uint16_t 8062bwn_ant2phy(int antenna) 8063{ 8064 8065 switch (antenna) { 8066 case BWN_ANT0: 8067 return (BWN_TX_PHY_ANT0); 8068 case BWN_ANT1: 8069 return (BWN_TX_PHY_ANT1); 8070 case BWN_ANT2: 8071 return (BWN_TX_PHY_ANT2); 8072 case BWN_ANT3: 8073 return (BWN_TX_PHY_ANT3); 8074 case BWN_ANTAUTO: 8075 return (BWN_TX_PHY_ANT01AUTO); 8076 } 8077 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8078 return (0); 8079} 8080 8081static void 8082bwn_wme_load(struct bwn_mac *mac) 8083{ 8084 struct bwn_softc *sc = mac->mac_sc; 8085 int i; 8086 8087 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8088 ("%s:%d: fail", __func__, __LINE__)); 8089 8090 bwn_mac_suspend(mac); 8091 for (i = 0; i < N(sc->sc_wmeParams); i++) 8092 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8093 bwn_wme_shm_offsets[i]); 8094 bwn_mac_enable(mac); 8095} 8096 8097static void 8098bwn_wme_loadparams(struct bwn_mac *mac, 8099 const struct wmeParams *p, uint16_t shm_offset) 8100{ 8101#define SM(_v, _f) (((_v) << _f##_S) & _f) 8102 struct bwn_softc *sc = mac->mac_sc; 8103 uint16_t params[BWN_NR_WMEPARAMS]; 8104 int slot, tmp; 8105 unsigned int i; 8106 8107 slot = BWN_READ_2(mac, BWN_RNG) & 8108 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8109 8110 memset(¶ms, 0, sizeof(params)); 8111 8112 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8113 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8114 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8115 8116 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8117 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8118 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8119 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8120 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8121 params[BWN_WMEPARAM_BSLOTS] = slot; 8122 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8123 8124 for (i = 0; i < N(params); i++) { 8125 if (i == BWN_WMEPARAM_STATUS) { 8126 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8127 shm_offset + (i * 2)); 8128 tmp |= 0x100; 8129 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8130 tmp); 8131 } else { 8132 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8133 params[i]); 8134 } 8135 } 8136} 8137 8138static void 8139bwn_mac_write_bssid(struct bwn_mac *mac) 8140{ 8141 struct bwn_softc *sc = mac->mac_sc; 8142 uint32_t tmp; 8143 int i; 8144 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8145 8146 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8147 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8148 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8149 IEEE80211_ADDR_LEN); 8150 8151 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8152 tmp = (uint32_t) (mac_bssid[i + 0]); 8153 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8154 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8155 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8156 bwn_ram_write(mac, 0x20 + i, tmp); 8157 } 8158} 8159 8160static void 8161bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8162 const uint8_t *macaddr) 8163{ 8164 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8165 uint16_t data; 8166 8167 if (!mac) 8168 macaddr = zero; 8169 8170 offset |= 0x0020; 8171 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8172 8173 data = macaddr[0]; 8174 data |= macaddr[1] << 8; 8175 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8176 data = macaddr[2]; 8177 data |= macaddr[3] << 8; 8178 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8179 data = macaddr[4]; 8180 data |= macaddr[5] << 8; 8181 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8182} 8183 8184static void 8185bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8186 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8187{ 8188 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8189 uint8_t per_sta_keys_start = 8; 8190 8191 if (BWN_SEC_NEWAPI(mac)) 8192 per_sta_keys_start = 4; 8193 8194 KASSERT(index < mac->mac_max_nr_keys, 8195 ("%s:%d: fail", __func__, __LINE__)); 8196 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8197 ("%s:%d: fail", __func__, __LINE__)); 8198 8199 if (index >= per_sta_keys_start) 8200 bwn_key_macwrite(mac, index, NULL); 8201 if (key) 8202 memcpy(buf, key, key_len); 8203 bwn_key_write(mac, index, algorithm, buf); 8204 if (index >= per_sta_keys_start) 8205 bwn_key_macwrite(mac, index, mac_addr); 8206 8207 mac->mac_key[index].algorithm = algorithm; 8208} 8209 8210static void 8211bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8212{ 8213 uint32_t addrtmp[2] = { 0, 0 }; 8214 uint8_t start = 8; 8215 8216 if (BWN_SEC_NEWAPI(mac)) 8217 start = 4; 8218 8219 KASSERT(index >= start, 8220 ("%s:%d: fail", __func__, __LINE__)); 8221 index -= start; 8222 8223 if (addr) { 8224 addrtmp[0] = addr[0]; 8225 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8226 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8227 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8228 addrtmp[1] = addr[4]; 8229 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8230 } 8231 8232 if (mac->mac_sd->sd_id.sd_rev >= 5) { 8233 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8234 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8235 } else { 8236 if (index >= 8) { 8237 bwn_shm_write_4(mac, BWN_SHARED, 8238 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8239 bwn_shm_write_2(mac, BWN_SHARED, 8240 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8241 } 8242 } 8243} 8244 8245static void 8246bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8247 const uint8_t *key) 8248{ 8249 unsigned int i; 8250 uint32_t offset; 8251 uint16_t kidx, value; 8252 8253 kidx = BWN_SEC_KEY2FW(mac, index); 8254 bwn_shm_write_2(mac, BWN_SHARED, 8255 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8256 8257 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8258 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8259 value = key[i]; 8260 value |= (uint16_t)(key[i + 1]) << 8; 8261 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8262 } 8263} 8264 8265static void 8266bwn_phy_exit(struct bwn_mac *mac) 8267{ 8268 8269 mac->mac_phy.rf_onoff(mac, 0); 8270 if (mac->mac_phy.exit != NULL) 8271 mac->mac_phy.exit(mac); 8272} 8273 8274static void 8275bwn_dma_free(struct bwn_mac *mac) 8276{ 8277 struct bwn_dma *dma; 8278 8279 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8280 return; 8281 dma = &mac->mac_method.dma; 8282 8283 bwn_dma_ringfree(&dma->rx); 8284 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8285 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8286 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8287 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8288 bwn_dma_ringfree(&dma->mcast); 8289} 8290 8291static void 8292bwn_core_stop(struct bwn_mac *mac) 8293{ 8294 struct bwn_softc *sc = mac->mac_sc; 8295 8296 BWN_ASSERT_LOCKED(sc); 8297 8298 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8299 return; 8300 8301 callout_stop(&sc->sc_rfswitch_ch); 8302 callout_stop(&sc->sc_task_ch); 8303 callout_stop(&sc->sc_watchdog_ch); 8304 sc->sc_watchdog_timer = 0; 8305 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8306 BWN_READ_4(mac, BWN_INTR_MASK); 8307 bwn_mac_suspend(mac); 8308 8309 mac->mac_status = BWN_MAC_STATUS_INITED; 8310} 8311 8312static int 8313bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8314{ 8315 struct bwn_mac *up_dev = NULL; 8316 struct bwn_mac *down_dev; 8317 struct bwn_mac *mac; 8318 int err, status; 8319 uint8_t gmode; 8320 8321 BWN_ASSERT_LOCKED(sc); 8322 8323 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8324 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8325 mac->mac_phy.supports_2ghz) { 8326 up_dev = mac; 8327 gmode = 1; 8328 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8329 mac->mac_phy.supports_5ghz) { 8330 up_dev = mac; 8331 gmode = 0; 8332 } else { 8333 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8334 return (EINVAL); 8335 } 8336 if (up_dev != NULL) 8337 break; 8338 } 8339 if (up_dev == NULL) { 8340 device_printf(sc->sc_dev, "Could not find a device\n"); 8341 return (ENODEV); 8342 } 8343 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8344 return (0); 8345 8346 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8347 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8348 8349 down_dev = sc->sc_curmac;; 8350 status = down_dev->mac_status; 8351 if (status >= BWN_MAC_STATUS_STARTED) 8352 bwn_core_stop(down_dev); 8353 if (status >= BWN_MAC_STATUS_INITED) 8354 bwn_core_exit(down_dev); 8355 8356 if (down_dev != up_dev) 8357 bwn_phy_reset(down_dev); 8358 8359 up_dev->mac_phy.gmode = gmode; 8360 if (status >= BWN_MAC_STATUS_INITED) { 8361 err = bwn_core_init(up_dev); 8362 if (err) { 8363 device_printf(sc->sc_dev, 8364 "fatal: failed to initialize for %s-GHz\n", 8365 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8366 goto fail; 8367 } 8368 } 8369 if (status >= BWN_MAC_STATUS_STARTED) 8370 bwn_core_start(up_dev); 8371 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8372 sc->sc_curmac = up_dev; 8373 8374 return (0); 8375fail: 8376 sc->sc_curmac = NULL; 8377 return (err); 8378} 8379 8380static void 8381bwn_rf_turnon(struct bwn_mac *mac) 8382{ 8383 8384 bwn_mac_suspend(mac); 8385 mac->mac_phy.rf_onoff(mac, 1); 8386 mac->mac_phy.rf_on = 1; 8387 bwn_mac_enable(mac); 8388} 8389 8390static void 8391bwn_rf_turnoff(struct bwn_mac *mac) 8392{ 8393 8394 bwn_mac_suspend(mac); 8395 mac->mac_phy.rf_onoff(mac, 0); 8396 mac->mac_phy.rf_on = 0; 8397 bwn_mac_enable(mac); 8398} 8399 8400static void 8401bwn_phy_reset(struct bwn_mac *mac) 8402{ 8403 struct siba_dev_softc *sd = mac->mac_sd; 8404 8405 siba_write_4(sd, SIBA_TGSLOW, 8406 ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8407 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8408 DELAY(1000); 8409 siba_write_4(sd, SIBA_TGSLOW, 8410 (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8411 BWN_TGSLOW_PHYRESET); 8412 DELAY(1000); 8413} 8414 8415static int 8416bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8417{ 8418 struct bwn_vap *bvp = BWN_VAP(vap); 8419 struct ieee80211com *ic= vap->iv_ic; 8420 struct ifnet *ifp = ic->ic_ifp; 8421 enum ieee80211_state ostate = vap->iv_state; 8422 struct bwn_softc *sc = ifp->if_softc; 8423 struct bwn_mac *mac = sc->sc_curmac; 8424 int error; 8425 8426 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8427 ieee80211_state_name[vap->iv_state], 8428 ieee80211_state_name[nstate]); 8429 8430 error = bvp->bv_newstate(vap, nstate, arg); 8431 if (error != 0) 8432 return (error); 8433 8434 BWN_LOCK(sc); 8435 8436 bwn_led_newstate(mac, nstate); 8437 8438 /* 8439 * Clear the BSSID when we stop a STA 8440 */ 8441 if (vap->iv_opmode == IEEE80211_M_STA) { 8442 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8443 /* 8444 * Clear out the BSSID. If we reassociate to 8445 * the same AP, this will reinialize things 8446 * correctly... 8447 */ 8448 if (ic->ic_opmode == IEEE80211_M_STA && 8449 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8450 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8451 bwn_set_macaddr(mac); 8452 } 8453 } 8454 } 8455 8456 if (vap->iv_opmode == IEEE80211_M_MONITOR) { 8457 /* XXX nothing to do? */ 8458 } else if (nstate == IEEE80211_S_RUN) { 8459 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8460 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8461 bwn_set_opmode(mac); 8462 bwn_set_pretbtt(mac); 8463 bwn_spu_setdelay(mac, 0); 8464 bwn_set_macaddr(mac); 8465 } 8466 8467 BWN_UNLOCK(sc); 8468 8469 return (error); 8470} 8471 8472static void 8473bwn_set_pretbtt(struct bwn_mac *mac) 8474{ 8475 struct bwn_softc *sc = mac->mac_sc; 8476 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8477 uint16_t pretbtt; 8478 8479 if (ic->ic_opmode == IEEE80211_M_IBSS) 8480 pretbtt = 2; 8481 else 8482 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8483 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8484 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8485} 8486 8487static int 8488bwn_intr(void *arg) 8489{ 8490 struct bwn_mac *mac = arg; 8491 struct bwn_softc *sc = mac->mac_sc; 8492 struct siba_softc *siba = mac->mac_sd->sd_bus; 8493 uint32_t reason; 8494 8495 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) 8496 return (FILTER_STRAY); 8497 8498 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8499 if (reason == 0xffffffff) /* shared IRQ */ 8500 return (FILTER_STRAY); 8501 reason &= mac->mac_intr_mask; 8502 if (reason == 0) 8503 return (FILTER_HANDLED); 8504 8505 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8506 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8507 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8508 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8509 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8510 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8511 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8512 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8513 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8514 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8515 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8516 8517 /* Disable interrupts. */ 8518 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8519 8520 mac->mac_reason_intr = reason; 8521 8522 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8523 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8524 8525 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8526 return (FILTER_HANDLED); 8527} 8528 8529static void 8530bwn_intrtask(void *arg, int npending) 8531{ 8532 struct bwn_mac *mac = arg; 8533 struct bwn_softc *sc = mac->mac_sc; 8534 struct ifnet *ifp = sc->sc_ifp; 8535 struct siba_softc *siba = mac->mac_sd->sd_bus; 8536 uint32_t merged = 0; 8537 int i, tx = 0, rx = 0; 8538 8539 BWN_LOCK(sc); 8540 if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) { 8541 BWN_UNLOCK(sc); 8542 return; 8543 } 8544 8545 for (i = 0; i < N(mac->mac_reason); i++) 8546 merged |= mac->mac_reason[i]; 8547 8548 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8549 device_printf(sc->sc_dev, "MAC trans error\n"); 8550 8551 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8552 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8553 mac->mac_phy.txerrors--; 8554 if (mac->mac_phy.txerrors == 0) { 8555 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8556 bwn_restart(mac, "PHY TX errors"); 8557 } 8558 } 8559 8560 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8561 if (merged & BWN_DMAINTR_FATALMASK) { 8562 device_printf(sc->sc_dev, 8563 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8564 mac->mac_reason[0], mac->mac_reason[1], 8565 mac->mac_reason[2], mac->mac_reason[3], 8566 mac->mac_reason[4], mac->mac_reason[5]); 8567 bwn_restart(mac, "DMA error"); 8568 BWN_UNLOCK(sc); 8569 return; 8570 } 8571 if (merged & BWN_DMAINTR_NONFATALMASK) { 8572 device_printf(sc->sc_dev, 8573 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8574 mac->mac_reason[0], mac->mac_reason[1], 8575 mac->mac_reason[2], mac->mac_reason[3], 8576 mac->mac_reason[4], mac->mac_reason[5]); 8577 } 8578 } 8579 8580 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8581 bwn_intr_ucode_debug(mac); 8582 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8583 bwn_intr_tbtt_indication(mac); 8584 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8585 bwn_intr_atim_end(mac); 8586 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8587 bwn_intr_beacon(mac); 8588 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8589 bwn_intr_pmq(mac); 8590 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8591 bwn_intr_noise(mac); 8592 8593 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8594 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8595 bwn_dma_rx(mac->mac_method.dma.rx); 8596 rx = 1; 8597 } 8598 } else 8599 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8600 8601 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8602 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8603 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8604 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8605 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8606 8607 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8608 bwn_intr_txeof(mac); 8609 tx = 1; 8610 } 8611 8612 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8613 8614 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8615 int evt = BWN_LED_EVENT_NONE; 8616 8617 if (tx && rx) { 8618 if (sc->sc_rx_rate > sc->sc_tx_rate) 8619 evt = BWN_LED_EVENT_RX; 8620 else 8621 evt = BWN_LED_EVENT_TX; 8622 } else if (tx) { 8623 evt = BWN_LED_EVENT_TX; 8624 } else if (rx) { 8625 evt = BWN_LED_EVENT_RX; 8626 } else if (rx == 0) { 8627 evt = BWN_LED_EVENT_POLL; 8628 } 8629 8630 if (evt != BWN_LED_EVENT_NONE) 8631 bwn_led_event(mac, evt); 8632 } 8633 8634 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8635 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8636 bwn_start_locked(ifp); 8637 } 8638 8639 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8640 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8641 8642 BWN_UNLOCK(sc); 8643} 8644 8645static void 8646bwn_restart(struct bwn_mac *mac, const char *msg) 8647{ 8648 struct bwn_softc *sc = mac->mac_sc; 8649 struct ifnet *ifp = sc->sc_ifp; 8650 struct ieee80211com *ic = ifp->if_l2com; 8651 8652 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8653 return; 8654 8655 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8656 ieee80211_runtask(ic, &mac->mac_hwreset); 8657} 8658 8659static void 8660bwn_intr_ucode_debug(struct bwn_mac *mac) 8661{ 8662 struct bwn_softc *sc = mac->mac_sc; 8663 uint16_t reason; 8664 8665 if (mac->mac_fw.opensource == 0) 8666 return; 8667 8668 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8669 switch (reason) { 8670 case BWN_DEBUGINTR_PANIC: 8671 bwn_handle_fwpanic(mac); 8672 break; 8673 case BWN_DEBUGINTR_DUMP_SHM: 8674 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8675 break; 8676 case BWN_DEBUGINTR_DUMP_REGS: 8677 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8678 break; 8679 case BWN_DEBUGINTR_MARKER: 8680 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8681 break; 8682 default: 8683 device_printf(sc->sc_dev, 8684 "ucode debug unknown reason: %#x\n", reason); 8685 } 8686 8687 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8688 BWN_DEBUGINTR_ACK); 8689} 8690 8691static void 8692bwn_intr_tbtt_indication(struct bwn_mac *mac) 8693{ 8694 struct bwn_softc *sc = mac->mac_sc; 8695 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8696 8697 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8698 bwn_psctl(mac, 0); 8699 if (ic->ic_opmode == IEEE80211_M_IBSS) 8700 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8701} 8702 8703static void 8704bwn_intr_atim_end(struct bwn_mac *mac) 8705{ 8706 8707 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8708 BWN_WRITE_4(mac, BWN_MACCMD, 8709 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8710 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8711 } 8712} 8713 8714static void 8715bwn_intr_beacon(struct bwn_mac *mac) 8716{ 8717 struct bwn_softc *sc = mac->mac_sc; 8718 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8719 uint32_t cmd, beacon0, beacon1; 8720 8721 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8722 ic->ic_opmode == IEEE80211_M_MBSS) 8723 return; 8724 8725 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8726 8727 cmd = BWN_READ_4(mac, BWN_MACCMD); 8728 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8729 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8730 8731 if (beacon0 && beacon1) { 8732 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8733 mac->mac_intr_mask |= BWN_INTR_BEACON; 8734 return; 8735 } 8736 8737 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8738 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8739 bwn_load_beacon0(mac); 8740 bwn_load_beacon1(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 { 8745 if (!beacon0) { 8746 bwn_load_beacon0(mac); 8747 cmd = BWN_READ_4(mac, BWN_MACCMD); 8748 cmd |= BWN_MACCMD_BEACON0_VALID; 8749 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8750 } else if (!beacon1) { 8751 bwn_load_beacon1(mac); 8752 cmd = BWN_READ_4(mac, BWN_MACCMD); 8753 cmd |= BWN_MACCMD_BEACON1_VALID; 8754 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8755 } 8756 } 8757} 8758 8759static void 8760bwn_intr_pmq(struct bwn_mac *mac) 8761{ 8762 uint32_t tmp; 8763 8764 while (1) { 8765 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8766 if (!(tmp & 0x00000008)) 8767 break; 8768 } 8769 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8770} 8771 8772static void 8773bwn_intr_noise(struct bwn_mac *mac) 8774{ 8775 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8776 uint16_t tmp; 8777 uint8_t noise[4]; 8778 uint8_t i, j; 8779 int32_t average; 8780 8781 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8782 return; 8783 8784 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8785 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8786 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8787 noise[3] == 0x7f) 8788 goto new; 8789 8790 KASSERT(mac->mac_noise.noi_nsamples < 8, 8791 ("%s:%d: fail", __func__, __LINE__)); 8792 i = mac->mac_noise.noi_nsamples; 8793 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8794 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8795 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8796 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8797 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8798 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8799 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8800 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8801 mac->mac_noise.noi_nsamples++; 8802 if (mac->mac_noise.noi_nsamples == 8) { 8803 average = 0; 8804 for (i = 0; i < 8; i++) { 8805 for (j = 0; j < 4; j++) 8806 average += mac->mac_noise.noi_samples[i][j]; 8807 } 8808 average = (((average / 32) * 125) + 64) / 128; 8809 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8810 if (tmp >= 8) 8811 average += 2; 8812 else 8813 average -= 25; 8814 average -= (tmp == 8) ? 72 : 48; 8815 8816 mac->mac_stats.link_noise = average; 8817 mac->mac_noise.noi_running = 0; 8818 return; 8819 } 8820new: 8821 bwn_noise_gensample(mac); 8822} 8823 8824static int 8825bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8826{ 8827 struct bwn_mac *mac = prq->prq_mac; 8828 struct bwn_softc *sc = mac->mac_sc; 8829 unsigned int i; 8830 8831 BWN_ASSERT_LOCKED(sc); 8832 8833 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8834 return (0); 8835 8836 for (i = 0; i < 5000; i++) { 8837 if (bwn_pio_rxeof(prq) == 0) 8838 break; 8839 } 8840 if (i >= 5000) 8841 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8842 return ((i > 0) ? 1 : 0); 8843} 8844 8845static void 8846bwn_dma_rx(struct bwn_dma_ring *dr) 8847{ 8848 int slot, curslot; 8849 8850 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8851 curslot = dr->get_curslot(dr); 8852 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8853 ("%s:%d: fail", __func__, __LINE__)); 8854 8855 slot = dr->dr_curslot; 8856 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8857 bwn_dma_rxeof(dr, &slot); 8858 8859 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8860 BUS_DMASYNC_PREWRITE); 8861 8862 dr->set_curslot(dr, slot); 8863 dr->dr_curslot = slot; 8864} 8865 8866static void 8867bwn_intr_txeof(struct bwn_mac *mac) 8868{ 8869 struct bwn_txstatus stat; 8870 uint32_t stat0, stat1; 8871 uint16_t tmp; 8872 8873 BWN_ASSERT_LOCKED(mac->mac_sc); 8874 8875 while (1) { 8876 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8877 if (!(stat0 & 0x00000001)) 8878 break; 8879 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8880 8881 stat.cookie = (stat0 >> 16); 8882 stat.seq = (stat1 & 0x0000ffff); 8883 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8884 tmp = (stat0 & 0x0000ffff); 8885 stat.framecnt = ((tmp & 0xf000) >> 12); 8886 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8887 stat.sreason = ((tmp & 0x001c) >> 2); 8888 stat.pm = (tmp & 0x0080) ? 1 : 0; 8889 stat.im = (tmp & 0x0040) ? 1 : 0; 8890 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8891 stat.ack = (tmp & 0x0002) ? 1 : 0; 8892 8893 bwn_handle_txeof(mac, &stat); 8894 } 8895} 8896 8897static void 8898bwn_hwreset(void *arg, int npending) 8899{ 8900 struct bwn_mac *mac = arg; 8901 struct bwn_softc *sc = mac->mac_sc; 8902 int error = 0; 8903 int prev_status; 8904 8905 BWN_LOCK(sc); 8906 8907 prev_status = mac->mac_status; 8908 if (prev_status >= BWN_MAC_STATUS_STARTED) 8909 bwn_core_stop(mac); 8910 if (prev_status >= BWN_MAC_STATUS_INITED) 8911 bwn_core_exit(mac); 8912 8913 if (prev_status >= BWN_MAC_STATUS_INITED) { 8914 error = bwn_core_init(mac); 8915 if (error) 8916 goto out; 8917 } 8918 if (prev_status >= BWN_MAC_STATUS_STARTED) 8919 bwn_core_start(mac); 8920out: 8921 if (error) { 8922 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8923 sc->sc_curmac = NULL; 8924 } 8925 BWN_UNLOCK(sc); 8926} 8927 8928static void 8929bwn_handle_fwpanic(struct bwn_mac *mac) 8930{ 8931 struct bwn_softc *sc = mac->mac_sc; 8932 uint16_t reason; 8933 8934 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8935 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8936 8937 if (reason == BWN_FWPANIC_RESTART) 8938 bwn_restart(mac, "ucode panic"); 8939} 8940 8941static void 8942bwn_load_beacon0(struct bwn_mac *mac) 8943{ 8944 8945 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8946} 8947 8948static void 8949bwn_load_beacon1(struct bwn_mac *mac) 8950{ 8951 8952 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8953} 8954 8955static uint32_t 8956bwn_jssi_read(struct bwn_mac *mac) 8957{ 8958 uint32_t val = 0; 8959 8960 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8961 val <<= 16; 8962 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8963 8964 return (val); 8965} 8966 8967static void 8968bwn_noise_gensample(struct bwn_mac *mac) 8969{ 8970 uint32_t jssi = 0x7f7f7f7f; 8971 8972 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8973 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8974 BWN_WRITE_4(mac, BWN_MACCMD, 8975 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8976} 8977 8978static int 8979bwn_dma_freeslot(struct bwn_dma_ring *dr) 8980{ 8981 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8982 8983 return (dr->dr_numslots - dr->dr_usedslot); 8984} 8985 8986static int 8987bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8988{ 8989 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8990 8991 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8992 ("%s:%d: fail", __func__, __LINE__)); 8993 if (slot == dr->dr_numslots - 1) 8994 return (0); 8995 return (slot + 1); 8996} 8997 8998static void 8999bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 9000{ 9001 struct bwn_mac *mac = dr->dr_mac; 9002 struct bwn_softc *sc = mac->mac_sc; 9003 struct bwn_dma *dma = &mac->mac_method.dma; 9004 struct bwn_dmadesc_generic *desc; 9005 struct bwn_dmadesc_meta *meta; 9006 struct bwn_rxhdr4 *rxhdr; 9007 struct ifnet *ifp = sc->sc_ifp; 9008 struct mbuf *m; 9009 uint32_t macstat; 9010 int32_t tmp; 9011 int cnt = 0; 9012 uint16_t len; 9013 9014 dr->getdesc(dr, *slot, &desc, &meta); 9015 9016 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 9017 m = meta->mt_m; 9018 9019 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 9020 ifp->if_ierrors++; 9021 return; 9022 } 9023 9024 rxhdr = mtod(m, struct bwn_rxhdr4 *); 9025 len = le16toh(rxhdr->frame_len); 9026 if (len <= 0) { 9027 ifp->if_ierrors++; 9028 return; 9029 } 9030 if (bwn_dma_check_redzone(dr, m)) { 9031 device_printf(sc->sc_dev, "redzone error.\n"); 9032 bwn_dma_set_redzone(dr, m); 9033 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9034 BUS_DMASYNC_PREWRITE); 9035 return; 9036 } 9037 if (len > dr->dr_rx_bufsize) { 9038 tmp = len; 9039 while (1) { 9040 dr->getdesc(dr, *slot, &desc, &meta); 9041 bwn_dma_set_redzone(dr, meta->mt_m); 9042 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9043 BUS_DMASYNC_PREWRITE); 9044 *slot = bwn_dma_nextslot(dr, *slot); 9045 cnt++; 9046 tmp -= dr->dr_rx_bufsize; 9047 if (tmp <= 0) 9048 break; 9049 } 9050 device_printf(sc->sc_dev, "too small buffer " 9051 "(len %u buffer %u dropped %d)\n", 9052 len, dr->dr_rx_bufsize, cnt); 9053 return; 9054 } 9055 macstat = le32toh(rxhdr->mac_status); 9056 if (macstat & BWN_RX_MAC_FCSERR) { 9057 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9058 device_printf(sc->sc_dev, "RX drop\n"); 9059 return; 9060 } 9061 } 9062 9063 m->m_pkthdr.rcvif = ifp; 9064 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 9065 m_adj(m, dr->dr_frameoffset); 9066 9067 bwn_rxeof(dr->dr_mac, m, rxhdr); 9068} 9069 9070static void 9071bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 9072{ 9073 struct bwn_dma_ring *dr; 9074 struct bwn_dmadesc_generic *desc; 9075 struct bwn_dmadesc_meta *meta; 9076 struct bwn_node *bn; 9077 struct bwn_pio_txqueue *tq; 9078 struct bwn_pio_txpkt *tp = NULL; 9079 struct bwn_softc *sc = mac->mac_sc; 9080 struct ieee80211_node *ni; 9081 int slot; 9082 9083 BWN_ASSERT_LOCKED(mac->mac_sc); 9084 9085 if (status->im) 9086 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9087 if (status->ampdu) 9088 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9089 if (status->rtscnt) { 9090 if (status->rtscnt == 0xf) 9091 device_printf(sc->sc_dev, "TODO: RTS fail\n"); 9092 else 9093 device_printf(sc->sc_dev, "TODO: RTS ok\n"); 9094 } 9095 9096 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9097 if (status->ack) { 9098 dr = bwn_dma_parse_cookie(mac, status, 9099 status->cookie, &slot); 9100 if (dr == NULL) { 9101 device_printf(sc->sc_dev, 9102 "failed to parse cookie\n"); 9103 return; 9104 } 9105 while (1) { 9106 dr->getdesc(dr, slot, &desc, &meta); 9107 if (meta->mt_islast) { 9108 ni = meta->mt_ni; 9109 bn = (struct bwn_node *)ni; 9110 ieee80211_amrr_tx_complete(&bn->bn_amn, 9111 status->ack, 0); 9112 break; 9113 } 9114 slot = bwn_dma_nextslot(dr, slot); 9115 } 9116 } 9117 bwn_dma_handle_txeof(mac, status); 9118 } else { 9119 if (status->ack) { 9120 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9121 if (tq == NULL) { 9122 device_printf(sc->sc_dev, 9123 "failed to parse cookie\n"); 9124 return; 9125 } 9126 ni = tp->tp_ni; 9127 bn = (struct bwn_node *)ni; 9128 ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0); 9129 } 9130 bwn_pio_handle_txeof(mac, status); 9131 } 9132 9133 bwn_phy_txpower_check(mac, 0); 9134} 9135 9136static uint8_t 9137bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9138{ 9139 struct bwn_mac *mac = prq->prq_mac; 9140 struct bwn_softc *sc = mac->mac_sc; 9141 struct bwn_rxhdr4 rxhdr; 9142 struct ifnet *ifp = sc->sc_ifp; 9143 struct mbuf *m; 9144 uint32_t ctl32, macstat, v32; 9145 unsigned int i, padding; 9146 uint16_t ctl16, len, v16; 9147 unsigned char *mp; 9148 char *data; 9149 9150 memset(&rxhdr, 0, sizeof(rxhdr)); 9151 9152 if (prq->prq_rev >= 8) { 9153 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9154 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9155 return (0); 9156 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9157 BWN_PIO8_RXCTL_FRAMEREADY); 9158 for (i = 0; i < 10; i++) { 9159 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9160 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9161 goto ready; 9162 DELAY(10); 9163 } 9164 } else { 9165 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9166 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9167 return (0); 9168 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9169 BWN_PIO_RXCTL_FRAMEREADY); 9170 for (i = 0; i < 10; i++) { 9171 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9172 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9173 goto ready; 9174 DELAY(10); 9175 } 9176 } 9177 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9178 return (1); 9179ready: 9180 if (prq->prq_rev >= 8) 9181 siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9182 prq->prq_base + BWN_PIO8_RXDATA); 9183 else 9184 siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr), 9185 prq->prq_base + BWN_PIO_RXDATA); 9186 len = le16toh(rxhdr.frame_len); 9187 if (len > 0x700) { 9188 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9189 goto error; 9190 } 9191 if (len == 0) { 9192 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9193 goto error; 9194 } 9195 9196 macstat = le32toh(rxhdr.mac_status); 9197 if (macstat & BWN_RX_MAC_FCSERR) { 9198 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9199 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9200 goto error; 9201 } 9202 } 9203 9204 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9205 KASSERT(len + padding <= MCLBYTES, ("too big..\n")); 9206 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9207 if (m == NULL) { 9208 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9209 goto error; 9210 } 9211 mp = mtod(m, unsigned char *); 9212 if (prq->prq_rev >= 8) { 9213 siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3), 9214 prq->prq_base + BWN_PIO8_RXDATA); 9215 if (len & 3) { 9216 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9217 data = &(mp[len + padding - 1]); 9218 switch (len & 3) { 9219 case 3: 9220 *data = (v32 >> 16); 9221 data--; 9222 case 2: 9223 *data = (v32 >> 8); 9224 data--; 9225 case 1: 9226 *data = v32; 9227 } 9228 } 9229 } else { 9230 siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1), 9231 prq->prq_base + BWN_PIO_RXDATA); 9232 if (len & 1) { 9233 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9234 mp[len + padding - 1] = v16; 9235 } 9236 } 9237 9238 m->m_pkthdr.rcvif = ifp; 9239 m->m_len = m->m_pkthdr.len = len + padding; 9240 9241 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9242 9243 return (1); 9244error: 9245 if (prq->prq_rev >= 8) 9246 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9247 BWN_PIO8_RXCTL_DATAREADY); 9248 else 9249 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9250 return (1); 9251} 9252 9253static int 9254bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9255 struct bwn_dmadesc_meta *meta, int init) 9256{ 9257 struct bwn_mac *mac = dr->dr_mac; 9258 struct bwn_dma *dma = &mac->mac_method.dma; 9259 struct bwn_rxhdr4 *hdr; 9260 bus_dmamap_t map; 9261 bus_addr_t paddr; 9262 struct mbuf *m; 9263 int error; 9264 9265 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9266 if (m == NULL) { 9267 error = ENOBUFS; 9268 9269 /* 9270 * If the NIC is up and running, we need to: 9271 * - Clear RX buffer's header. 9272 * - Restore RX descriptor settings. 9273 */ 9274 if (init) 9275 return (error); 9276 else 9277 goto back; 9278 } 9279 m->m_len = m->m_pkthdr.len = MCLBYTES; 9280 9281 bwn_dma_set_redzone(dr, m); 9282 9283 /* 9284 * Try to load RX buf into temporary DMA map 9285 */ 9286 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9287 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9288 if (error) { 9289 m_freem(m); 9290 9291 /* 9292 * See the comment above 9293 */ 9294 if (init) 9295 return (error); 9296 else 9297 goto back; 9298 } 9299 9300 if (!init) 9301 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9302 meta->mt_m = m; 9303 meta->mt_paddr = paddr; 9304 9305 /* 9306 * Swap RX buf's DMA map with the loaded temporary one 9307 */ 9308 map = meta->mt_dmap; 9309 meta->mt_dmap = dr->dr_spare_dmap; 9310 dr->dr_spare_dmap = map; 9311 9312back: 9313 /* 9314 * Clear RX buf header 9315 */ 9316 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9317 bzero(hdr, sizeof(*hdr)); 9318 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9319 BUS_DMASYNC_PREWRITE); 9320 9321 /* 9322 * Setup RX buf descriptor 9323 */ 9324 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9325 sizeof(*hdr), 0, 0, 0); 9326 return (error); 9327} 9328 9329static void 9330bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9331 bus_size_t mapsz __unused, int error) 9332{ 9333 9334 if (!error) { 9335 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9336 *((bus_addr_t *)arg) = seg->ds_addr; 9337 } 9338} 9339 9340static int 9341bwn_hwrate2ieeerate(int rate) 9342{ 9343 9344 switch (rate) { 9345 case BWN_CCK_RATE_1MB: 9346 return (2); 9347 case BWN_CCK_RATE_2MB: 9348 return (4); 9349 case BWN_CCK_RATE_5MB: 9350 return (11); 9351 case BWN_CCK_RATE_11MB: 9352 return (22); 9353 case BWN_OFDM_RATE_6MB: 9354 return (12); 9355 case BWN_OFDM_RATE_9MB: 9356 return (18); 9357 case BWN_OFDM_RATE_12MB: 9358 return (24); 9359 case BWN_OFDM_RATE_18MB: 9360 return (36); 9361 case BWN_OFDM_RATE_24MB: 9362 return (48); 9363 case BWN_OFDM_RATE_36MB: 9364 return (72); 9365 case BWN_OFDM_RATE_48MB: 9366 return (96); 9367 case BWN_OFDM_RATE_54MB: 9368 return (108); 9369 default: 9370 printf("Ooops\n"); 9371 return (0); 9372 } 9373} 9374 9375static void 9376bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9377{ 9378 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9379 struct bwn_plcp6 *plcp; 9380 struct bwn_softc *sc = mac->mac_sc; 9381 struct ieee80211_frame_min *wh; 9382 struct ieee80211_node *ni; 9383 struct ifnet *ifp = sc->sc_ifp; 9384 struct ieee80211com *ic = ifp->if_l2com; 9385 uint32_t macstat; 9386 int padding, rate, rssi = 0, noise = 0, type; 9387 uint16_t phytype, phystat0, phystat3, chanstat; 9388 unsigned char *mp = mtod(m, unsigned char *); 9389 static int rx_mac_dec_rpt = 0; 9390 9391 BWN_ASSERT_LOCKED(sc); 9392 9393 phystat0 = le16toh(rxhdr->phy_status0); 9394 phystat3 = le16toh(rxhdr->phy_status3); 9395 macstat = le32toh(rxhdr->mac_status); 9396 chanstat = le16toh(rxhdr->channel); 9397 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9398 9399 if (macstat & BWN_RX_MAC_FCSERR) 9400 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9401 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9402 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9403 if (phystat0 & BWN_RX_PHYST0_SHORTPRMBL) 9404 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_SHORTPRE\n"); 9405 if (macstat & BWN_RX_MAC_DECERR) 9406 goto drop; 9407 9408 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9409 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9410 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9411 m->m_pkthdr.len); 9412 goto drop; 9413 } 9414 plcp = (struct bwn_plcp6 *)(mp + padding); 9415 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9416 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9417 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9418 m->m_pkthdr.len); 9419 goto drop; 9420 } 9421 wh = mtod(m, struct ieee80211_frame_min *); 9422 9423 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9424 device_printf(sc->sc_dev, 9425 "RX decryption attempted (old %d keyidx %#x)\n", 9426 BWN_ISOLDFMT(mac), 9427 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9428 9429 /* XXX calculating RSSI & noise & antenna */ 9430 9431 if (phystat0 & BWN_RX_PHYST0_OFDM) 9432 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9433 phytype == BWN_PHYTYPE_A); 9434 else 9435 rate = bwn_plcp_get_cckrate(mac, plcp); 9436 if (rate == -1) { 9437 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9438 goto drop; 9439 } 9440 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9441 9442 /* RX radio tap */ 9443 if (ieee80211_radiotap_active(ic)) 9444 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9445 m_adj(m, -IEEE80211_CRC_LEN); 9446 9447 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9448 noise = mac->mac_stats.link_noise; 9449 9450 BWN_UNLOCK(sc); 9451 9452 ni = ieee80211_find_rxnode(ic, wh); 9453 if (ni != NULL) { 9454 type = ieee80211_input(ni, m, rssi, noise); 9455 ieee80211_free_node(ni); 9456 } else 9457 type = ieee80211_input_all(ic, m, rssi, noise); 9458 9459 BWN_LOCK(sc); 9460 return; 9461drop: 9462 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9463} 9464 9465static void 9466bwn_dma_handle_txeof(struct bwn_mac *mac, 9467 const struct bwn_txstatus *status) 9468{ 9469 struct bwn_dma *dma = &mac->mac_method.dma; 9470 struct bwn_dma_ring *dr; 9471 struct bwn_dmadesc_generic *desc; 9472 struct bwn_dmadesc_meta *meta; 9473 struct bwn_softc *sc = mac->mac_sc; 9474 struct ieee80211_node *ni; 9475 struct ifnet *ifp = sc->sc_ifp; 9476 struct mbuf *m; 9477 int slot; 9478 9479 BWN_ASSERT_LOCKED(sc); 9480 9481 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9482 if (dr == NULL) { 9483 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9484 return; 9485 } 9486 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9487 9488 while (1) { 9489 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9490 ("%s:%d: fail", __func__, __LINE__)); 9491 dr->getdesc(dr, slot, &desc, &meta); 9492 9493 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9494 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9495 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9496 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9497 9498 if (meta->mt_islast) { 9499 KASSERT(meta->mt_m != NULL, 9500 ("%s:%d: fail", __func__, __LINE__)); 9501 9502 ni = meta->mt_ni; 9503 m = meta->mt_m; 9504 if (ni != NULL) { 9505 /* 9506 * Do any tx complete callback. Note this must 9507 * be done before releasing the node reference. 9508 */ 9509 if (m->m_flags & M_TXCB) 9510 ieee80211_process_callback(ni, m, 0); 9511 ieee80211_free_node(ni); 9512 meta->mt_ni = NULL; 9513 } 9514 m_freem(m); 9515 meta->mt_m = NULL; 9516 } else { 9517 KASSERT(meta->mt_m == NULL, 9518 ("%s:%d: fail", __func__, __LINE__)); 9519 } 9520 9521 dr->dr_usedslot--; 9522 if (meta->mt_islast) { 9523 ifp->if_opackets++; 9524 break; 9525 } 9526 slot = bwn_dma_nextslot(dr, slot); 9527 } 9528 sc->sc_watchdog_timer = 0; 9529 if (dr->dr_stop) { 9530 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9531 ("%s:%d: fail", __func__, __LINE__)); 9532 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9533 dr->dr_stop = 0; 9534 } 9535} 9536 9537static void 9538bwn_pio_handle_txeof(struct bwn_mac *mac, 9539 const struct bwn_txstatus *status) 9540{ 9541 struct bwn_pio_txqueue *tq; 9542 struct bwn_pio_txpkt *tp = NULL; 9543 struct bwn_softc *sc = mac->mac_sc; 9544 struct ifnet *ifp = sc->sc_ifp; 9545 9546 BWN_ASSERT_LOCKED(sc); 9547 9548 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9549 if (tq == NULL) 9550 return; 9551 9552 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9553 tq->tq_free++; 9554 9555 if (tp->tp_ni != NULL) { 9556 /* 9557 * Do any tx complete callback. Note this must 9558 * be done before releasing the node reference. 9559 */ 9560 if (tp->tp_m->m_flags & M_TXCB) 9561 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9562 ieee80211_free_node(tp->tp_ni); 9563 tp->tp_ni = NULL; 9564 } 9565 m_freem(tp->tp_m); 9566 tp->tp_m = NULL; 9567 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9568 9569 ifp->if_opackets++; 9570 9571 sc->sc_watchdog_timer = 0; 9572 if (tq->tq_stop) { 9573 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9574 tq->tq_stop = 0; 9575 } 9576} 9577 9578static void 9579bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9580{ 9581 struct bwn_softc *sc = mac->mac_sc; 9582 struct bwn_phy *phy = &mac->mac_phy; 9583 struct ifnet *ifp = sc->sc_ifp; 9584 struct ieee80211com *ic = ifp->if_l2com; 9585 struct siba_softc *siba = mac->mac_sd->sd_bus; 9586 unsigned long now; 9587 int result; 9588 9589 BWN_GETTIME(now); 9590 9591 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9592 return; 9593 phy->nexttime = now + 2 * 1000; 9594 9595 if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM && 9596 siba->siba_board_type == SIBA_BOARD_BU4306) 9597 return; 9598 9599 if (phy->recalc_txpwr != NULL) { 9600 result = phy->recalc_txpwr(mac, 9601 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9602 if (result == BWN_TXPWR_RES_DONE) 9603 return; 9604 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9605 ("%s: fail", __func__)); 9606 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9607 9608 ieee80211_runtask(ic, &mac->mac_txpower); 9609 } 9610} 9611 9612static uint16_t 9613bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9614{ 9615 9616 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9617} 9618 9619static uint32_t 9620bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9621{ 9622 9623 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9624} 9625 9626static void 9627bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9628{ 9629 9630 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9631} 9632 9633static void 9634bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9635{ 9636 9637 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9638} 9639 9640static int 9641bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9642{ 9643 9644 switch (rate) { 9645 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9646 case 12: 9647 return (BWN_OFDM_RATE_6MB); 9648 case 18: 9649 return (BWN_OFDM_RATE_9MB); 9650 case 24: 9651 return (BWN_OFDM_RATE_12MB); 9652 case 36: 9653 return (BWN_OFDM_RATE_18MB); 9654 case 48: 9655 return (BWN_OFDM_RATE_24MB); 9656 case 72: 9657 return (BWN_OFDM_RATE_36MB); 9658 case 96: 9659 return (BWN_OFDM_RATE_48MB); 9660 case 108: 9661 return (BWN_OFDM_RATE_54MB); 9662 /* CCK rates (NB: not IEEE std, device-specific) */ 9663 case 2: 9664 return (BWN_CCK_RATE_1MB); 9665 case 4: 9666 return (BWN_CCK_RATE_2MB); 9667 case 11: 9668 return (BWN_CCK_RATE_5MB); 9669 case 22: 9670 return (BWN_CCK_RATE_11MB); 9671 } 9672 9673 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9674 return (BWN_CCK_RATE_1MB); 9675} 9676 9677static int 9678bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9679 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9680{ 9681 const struct bwn_phy *phy = &mac->mac_phy; 9682 struct bwn_softc *sc = mac->mac_sc; 9683 struct ieee80211_frame *wh; 9684 struct ieee80211_frame *protwh; 9685 struct ieee80211_frame_cts *cts; 9686 struct ieee80211_frame_rts *rts; 9687 const struct ieee80211_txparam *tp; 9688 struct ieee80211vap *vap = ni->ni_vap; 9689 struct ifnet *ifp = sc->sc_ifp; 9690 struct ieee80211com *ic = ifp->if_l2com; 9691 struct mbuf *mprot; 9692 unsigned int len; 9693 uint32_t macctl = 0; 9694 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9695 uint16_t phyctl = 0; 9696 uint8_t rate, rate_fb; 9697 9698 wh = mtod(m, struct ieee80211_frame *); 9699 memset(txhdr, 0, sizeof(*txhdr)); 9700 9701 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9702 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9703 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9704 9705 /* 9706 * Find TX rate 9707 */ 9708 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9709 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9710 rate = rate_fb = tp->mgmtrate; 9711 else if (ismcast) 9712 rate = rate_fb = tp->mcastrate; 9713 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9714 rate = rate_fb = tp->ucastrate; 9715 else { 9716 rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn); 9717 rate = ni->ni_txrate; 9718 9719 if (rix > 0) 9720 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9721 IEEE80211_RATE_VAL; 9722 else 9723 rate_fb = rate; 9724 } 9725 9726 sc->sc_tx_rate = rate; 9727 9728 rate = bwn_ieeerate2hwrate(sc, rate); 9729 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9730 9731 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9732 bwn_plcp_getcck(rate); 9733 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9734 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9735 9736 if ((rate_fb == rate) || 9737 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9738 (*(u_int16_t *)wh->i_dur == htole16(0))) 9739 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9740 else 9741 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9742 m->m_pkthdr.len, rate, isshort); 9743 9744 /* XXX TX encryption */ 9745 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9746 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9747 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9748 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9749 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9750 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9751 9752 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9753 BWN_TX_EFT_FB_CCK; 9754 txhdr->chan = phy->chan; 9755 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9756 BWN_TX_PHY_ENC_CCK; 9757 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9758 rate == BWN_CCK_RATE_11MB)) 9759 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9760 9761 /* XXX TX antenna selection */ 9762 9763 switch (bwn_antenna_sanitize(mac, 0)) { 9764 case 0: 9765 phyctl |= BWN_TX_PHY_ANT01AUTO; 9766 break; 9767 case 1: 9768 phyctl |= BWN_TX_PHY_ANT0; 9769 break; 9770 case 2: 9771 phyctl |= BWN_TX_PHY_ANT1; 9772 break; 9773 case 3: 9774 phyctl |= BWN_TX_PHY_ANT2; 9775 break; 9776 case 4: 9777 phyctl |= BWN_TX_PHY_ANT3; 9778 break; 9779 default: 9780 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9781 } 9782 9783 if (!ismcast) 9784 macctl |= BWN_TX_MAC_ACK; 9785 9786 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9787 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9788 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9789 macctl |= BWN_TX_MAC_LONGFRAME; 9790 9791 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9792 /* XXX RTS rate is always 1MB??? */ 9793 rts_rate = BWN_CCK_RATE_1MB; 9794 rts_rate_fb = bwn_get_fbrate(rts_rate); 9795 9796 protdur = ieee80211_compute_duration(ic->ic_rt, 9797 m->m_pkthdr.len, rate, isshort) + 9798 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9799 9800 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9801 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9802 (txhdr->body.old.rts_frame) : 9803 (txhdr->body.new.rts_frame)); 9804 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9805 protdur); 9806 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9807 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9808 mprot->m_pkthdr.len); 9809 m_freem(mprot); 9810 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9811 len = sizeof(struct ieee80211_frame_cts); 9812 } else { 9813 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9814 (txhdr->body.old.rts_frame) : 9815 (txhdr->body.new.rts_frame)); 9816 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9817 isshort); 9818 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9819 wh->i_addr2, protdur); 9820 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9821 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9822 mprot->m_pkthdr.len); 9823 m_freem(mprot); 9824 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9825 len = sizeof(struct ieee80211_frame_rts); 9826 } 9827 len += IEEE80211_CRC_LEN; 9828 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9829 &txhdr->body.old.rts_plcp : 9830 &txhdr->body.new.rts_plcp), len, rts_rate); 9831 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9832 rts_rate_fb); 9833 9834 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9835 (&txhdr->body.old.rts_frame) : 9836 (&txhdr->body.new.rts_frame)); 9837 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9838 9839 if (BWN_ISOFDMRATE(rts_rate)) { 9840 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9841 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9842 } else { 9843 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9844 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9845 } 9846 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9847 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9848 } 9849 9850 if (BWN_ISOLDFMT(mac)) 9851 txhdr->body.old.cookie = htole16(cookie); 9852 else 9853 txhdr->body.new.cookie = htole16(cookie); 9854 9855 txhdr->macctl = htole32(macctl); 9856 txhdr->phyctl = htole16(phyctl); 9857 9858 /* 9859 * TX radio tap 9860 */ 9861 if (ieee80211_radiotap_active_vap(vap)) { 9862 sc->sc_tx_th.wt_flags = 0; 9863 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9864 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9865 if (isshort && 9866 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9867 rate == BWN_CCK_RATE_11MB)) 9868 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9869 sc->sc_tx_th.wt_rate = rate; 9870 9871 ieee80211_radiotap_tx(vap, m); 9872 } 9873 9874 return (0); 9875} 9876 9877static void 9878bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9879 const uint8_t rate) 9880{ 9881 uint32_t d, plen; 9882 uint8_t *raw = plcp->o.raw; 9883 9884 if (BWN_ISOFDMRATE(rate)) { 9885 d = bwn_plcp_getofdm(rate); 9886 KASSERT(!(octets & 0xf000), 9887 ("%s:%d: fail", __func__, __LINE__)); 9888 d |= (octets << 5); 9889 plcp->o.data = htole32(d); 9890 } else { 9891 plen = octets * 16 / rate; 9892 if ((octets * 16 % rate) > 0) { 9893 plen++; 9894 if ((rate == BWN_CCK_RATE_11MB) 9895 && ((octets * 8 % 11) < 4)) { 9896 raw[1] = 0x84; 9897 } else 9898 raw[1] = 0x04; 9899 } else 9900 raw[1] = 0x04; 9901 plcp->o.data |= htole32(plen << 16); 9902 raw[0] = bwn_plcp_getcck(rate); 9903 } 9904} 9905 9906static uint8_t 9907bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9908{ 9909 uint8_t mask; 9910 9911 if (n == 0) 9912 return (0); 9913 if (mac->mac_phy.gmode) 9914 mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg; 9915 else 9916 mask = mac->mac_sd->sd_bus->siba_sprom.ant_a; 9917 if (!(mask & (1 << (n - 1)))) 9918 return (0); 9919 return (n); 9920} 9921 9922static uint8_t 9923bwn_get_fbrate(uint8_t bitrate) 9924{ 9925 switch (bitrate) { 9926 case BWN_CCK_RATE_1MB: 9927 return (BWN_CCK_RATE_1MB); 9928 case BWN_CCK_RATE_2MB: 9929 return (BWN_CCK_RATE_1MB); 9930 case BWN_CCK_RATE_5MB: 9931 return (BWN_CCK_RATE_2MB); 9932 case BWN_CCK_RATE_11MB: 9933 return (BWN_CCK_RATE_5MB); 9934 case BWN_OFDM_RATE_6MB: 9935 return (BWN_CCK_RATE_5MB); 9936 case BWN_OFDM_RATE_9MB: 9937 return (BWN_OFDM_RATE_6MB); 9938 case BWN_OFDM_RATE_12MB: 9939 return (BWN_OFDM_RATE_9MB); 9940 case BWN_OFDM_RATE_18MB: 9941 return (BWN_OFDM_RATE_12MB); 9942 case BWN_OFDM_RATE_24MB: 9943 return (BWN_OFDM_RATE_18MB); 9944 case BWN_OFDM_RATE_36MB: 9945 return (BWN_OFDM_RATE_24MB); 9946 case BWN_OFDM_RATE_48MB: 9947 return (BWN_OFDM_RATE_36MB); 9948 case BWN_OFDM_RATE_54MB: 9949 return (BWN_OFDM_RATE_48MB); 9950 } 9951 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9952 return (0); 9953} 9954 9955static uint32_t 9956bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9957 uint32_t ctl, const void *_data, int len) 9958{ 9959 uint32_t value = 0; 9960 const uint8_t *data = _data; 9961 9962 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9963 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9964 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9965 9966 siba_write_multi_4(mac->mac_sd, data, (len & ~3), 9967 tq->tq_base + BWN_PIO8_TXDATA); 9968 if (len & 3) { 9969 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9970 BWN_PIO8_TXCTL_24_31); 9971 data = &(data[len - 1]); 9972 switch (len & 3) { 9973 case 3: 9974 ctl |= BWN_PIO8_TXCTL_16_23; 9975 value |= (uint32_t)(*data) << 16; 9976 data--; 9977 case 2: 9978 ctl |= BWN_PIO8_TXCTL_8_15; 9979 value |= (uint32_t)(*data) << 8; 9980 data--; 9981 case 1: 9982 value |= (uint32_t)(*data); 9983 } 9984 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9985 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9986 } 9987 9988 return (ctl); 9989} 9990 9991static void 9992bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9993 uint16_t offset, uint32_t value) 9994{ 9995 9996 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9997} 9998 9999static uint16_t 10000bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 10001 uint16_t ctl, const void *_data, int len) 10002{ 10003 const uint8_t *data = _data; 10004 10005 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10006 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10007 10008 siba_write_multi_2(mac->mac_sd, data, (len & ~1), 10009 tq->tq_base + BWN_PIO_TXDATA); 10010 if (len & 1) { 10011 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10012 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10013 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 10014 } 10015 10016 return (ctl); 10017} 10018 10019static uint16_t 10020bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 10021 uint16_t ctl, struct mbuf *m0) 10022{ 10023 int i, j = 0; 10024 uint16_t data = 0; 10025 const uint8_t *buf; 10026 struct mbuf *m = m0; 10027 10028 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 10029 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10030 10031 for (; m != NULL; m = m->m_next) { 10032 buf = mtod(m, const uint8_t *); 10033 for (i = 0; i < m->m_len; i++) { 10034 if (!((j++) % 2)) 10035 data |= buf[i]; 10036 else { 10037 data |= (buf[i] << 8); 10038 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10039 data = 0; 10040 } 10041 } 10042 } 10043 if (m0->m_pkthdr.len % 2) { 10044 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 10045 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 10046 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 10047 } 10048 10049 return (ctl); 10050} 10051 10052static void 10053bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 10054{ 10055 10056 if (mac->mac_phy.type != BWN_PHYTYPE_G) 10057 return; 10058 BWN_WRITE_2(mac, 0x684, 510 + time); 10059 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 10060} 10061 10062static struct bwn_dma_ring * 10063bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 10064{ 10065 10066 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 10067 return (mac->mac_method.dma.wme[WME_AC_BE]); 10068 10069 switch (prio) { 10070 case 3: 10071 return (mac->mac_method.dma.wme[WME_AC_VO]); 10072 case 2: 10073 return (mac->mac_method.dma.wme[WME_AC_VI]); 10074 case 0: 10075 return (mac->mac_method.dma.wme[WME_AC_BE]); 10076 case 1: 10077 return (mac->mac_method.dma.wme[WME_AC_BK]); 10078 } 10079 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10080 return (NULL); 10081} 10082 10083static int 10084bwn_dma_getslot(struct bwn_dma_ring *dr) 10085{ 10086 int slot; 10087 10088 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10089 10090 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10091 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10092 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10093 10094 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10095 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10096 dr->dr_curslot = slot; 10097 dr->dr_usedslot++; 10098 10099 return (slot); 10100} 10101 10102static int 10103bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10104{ 10105 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10106 unsigned int a, b, c, d; 10107 unsigned int avg; 10108 uint32_t tmp; 10109 10110 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10111 a = tmp & 0xff; 10112 b = (tmp >> 8) & 0xff; 10113 c = (tmp >> 16) & 0xff; 10114 d = (tmp >> 24) & 0xff; 10115 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10116 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10117 return (ENOENT); 10118 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10119 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10120 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10121 10122 if (ofdm) { 10123 a = (a + 32) & 0x3f; 10124 b = (b + 32) & 0x3f; 10125 c = (c + 32) & 0x3f; 10126 d = (d + 32) & 0x3f; 10127 } 10128 10129 avg = (a + b + c + d + 2) / 4; 10130 if (ofdm) { 10131 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10132 & BWN_HF_4DB_CCK_POWERBOOST) 10133 avg = (avg >= 13) ? (avg - 13) : 0; 10134 } 10135 return (avg); 10136} 10137 10138static void 10139bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10140{ 10141 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10142 int rfatt = *rfattp; 10143 int bbatt = *bbattp; 10144 10145 while (1) { 10146 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10147 break; 10148 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10149 break; 10150 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10151 break; 10152 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10153 break; 10154 if (bbatt > lo->bbatt.max) { 10155 bbatt -= 4; 10156 rfatt += 1; 10157 continue; 10158 } 10159 if (bbatt < lo->bbatt.min) { 10160 bbatt += 4; 10161 rfatt -= 1; 10162 continue; 10163 } 10164 if (rfatt > lo->rfatt.max) { 10165 rfatt -= 1; 10166 bbatt += 4; 10167 continue; 10168 } 10169 if (rfatt < lo->rfatt.min) { 10170 rfatt += 1; 10171 bbatt -= 4; 10172 continue; 10173 } 10174 break; 10175 } 10176 10177 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10178 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10179} 10180 10181static void 10182bwn_phy_lock(struct bwn_mac *mac) 10183{ 10184 struct bwn_softc *sc = mac->mac_sc; 10185 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10186 10187 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10188 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10189 10190 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10191 bwn_psctl(mac, BWN_PS_AWAKE); 10192} 10193 10194static void 10195bwn_phy_unlock(struct bwn_mac *mac) 10196{ 10197 struct bwn_softc *sc = mac->mac_sc; 10198 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10199 10200 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10201 ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev)); 10202 10203 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10204 bwn_psctl(mac, 0); 10205} 10206 10207static void 10208bwn_rf_lock(struct bwn_mac *mac) 10209{ 10210 10211 BWN_WRITE_4(mac, BWN_MACCTL, 10212 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10213 BWN_READ_4(mac, BWN_MACCTL); 10214 DELAY(10); 10215} 10216 10217static void 10218bwn_rf_unlock(struct bwn_mac *mac) 10219{ 10220 10221 BWN_READ_2(mac, BWN_PHYVER); 10222 BWN_WRITE_4(mac, BWN_MACCTL, 10223 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10224} 10225 10226static struct bwn_pio_txqueue * 10227bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10228 struct bwn_pio_txpkt **pack) 10229{ 10230 struct bwn_pio *pio = &mac->mac_method.pio; 10231 struct bwn_pio_txqueue *tq = NULL; 10232 unsigned int index; 10233 10234 switch (cookie & 0xf000) { 10235 case 0x1000: 10236 tq = &pio->wme[WME_AC_BK]; 10237 break; 10238 case 0x2000: 10239 tq = &pio->wme[WME_AC_BE]; 10240 break; 10241 case 0x3000: 10242 tq = &pio->wme[WME_AC_VI]; 10243 break; 10244 case 0x4000: 10245 tq = &pio->wme[WME_AC_VO]; 10246 break; 10247 case 0x5000: 10248 tq = &pio->mcast; 10249 break; 10250 } 10251 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10252 if (tq == NULL) 10253 return (NULL); 10254 index = (cookie & 0x0fff); 10255 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10256 if (index >= N(tq->tq_pkts)) 10257 return (NULL); 10258 *pack = &tq->tq_pkts[index]; 10259 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10260 return (tq); 10261} 10262 10263static void 10264bwn_txpwr(void *arg, int npending) 10265{ 10266 struct bwn_mac *mac = arg; 10267 struct bwn_softc *sc = mac->mac_sc; 10268 10269 BWN_LOCK(sc); 10270 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10271 mac->mac_phy.set_txpwr != NULL) 10272 mac->mac_phy.set_txpwr(mac); 10273 BWN_UNLOCK(sc); 10274} 10275 10276static void 10277bwn_task_15s(struct bwn_mac *mac) 10278{ 10279 uint16_t reg; 10280 10281 if (mac->mac_fw.opensource) { 10282 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10283 if (reg) { 10284 bwn_restart(mac, "fw watchdog"); 10285 return; 10286 } 10287 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10288 } 10289 if (mac->mac_phy.task_15s) 10290 mac->mac_phy.task_15s(mac); 10291 10292 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10293} 10294 10295static void 10296bwn_task_30s(struct bwn_mac *mac) 10297{ 10298 10299 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10300 return; 10301 mac->mac_noise.noi_running = 1; 10302 mac->mac_noise.noi_nsamples = 0; 10303 10304 bwn_noise_gensample(mac); 10305} 10306 10307static void 10308bwn_task_60s(struct bwn_mac *mac) 10309{ 10310 10311 if (mac->mac_phy.task_60s) 10312 mac->mac_phy.task_60s(mac); 10313 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10314} 10315 10316static void 10317bwn_tasks(void *arg) 10318{ 10319 struct bwn_mac *mac = arg; 10320 struct bwn_softc *sc = mac->mac_sc; 10321 10322 BWN_ASSERT_LOCKED(sc); 10323 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10324 return; 10325 10326 if (mac->mac_task_state % 4 == 0) 10327 bwn_task_60s(mac); 10328 if (mac->mac_task_state % 2 == 0) 10329 bwn_task_30s(mac); 10330 bwn_task_15s(mac); 10331 10332 mac->mac_task_state++; 10333 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10334} 10335 10336static int 10337bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10338{ 10339 struct bwn_softc *sc = mac->mac_sc; 10340 10341 KASSERT(a == 0, ("not support APHY\n")); 10342 10343 switch (plcp->o.raw[0] & 0xf) { 10344 case 0xb: 10345 return (BWN_OFDM_RATE_6MB); 10346 case 0xf: 10347 return (BWN_OFDM_RATE_9MB); 10348 case 0xa: 10349 return (BWN_OFDM_RATE_12MB); 10350 case 0xe: 10351 return (BWN_OFDM_RATE_18MB); 10352 case 0x9: 10353 return (BWN_OFDM_RATE_24MB); 10354 case 0xd: 10355 return (BWN_OFDM_RATE_36MB); 10356 case 0x8: 10357 return (BWN_OFDM_RATE_48MB); 10358 case 0xc: 10359 return (BWN_OFDM_RATE_54MB); 10360 } 10361 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10362 plcp->o.raw[0] & 0xf); 10363 return (-1); 10364} 10365 10366static int 10367bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10368{ 10369 struct bwn_softc *sc = mac->mac_sc; 10370 10371 switch (plcp->o.raw[0]) { 10372 case 0x0a: 10373 return (BWN_CCK_RATE_1MB); 10374 case 0x14: 10375 return (BWN_CCK_RATE_2MB); 10376 case 0x37: 10377 return (BWN_CCK_RATE_5MB); 10378 case 0x6e: 10379 return (BWN_CCK_RATE_11MB); 10380 } 10381 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10382 return (-1); 10383} 10384 10385static void 10386bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10387 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10388 int rssi, int noise) 10389{ 10390 struct bwn_softc *sc = mac->mac_sc; 10391 const struct ieee80211_frame_min *wh; 10392 uint64_t tsf; 10393 uint16_t low_mactime_now; 10394 10395 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10396 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10397 10398 wh = mtod(m, const struct ieee80211_frame_min *); 10399 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10400 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10401 10402 bwn_tsf_read(mac, &tsf); 10403 low_mactime_now = tsf; 10404 tsf = tsf & ~0xffffULL; 10405 tsf += le16toh(rxhdr->mac_time); 10406 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10407 tsf -= 0x10000; 10408 10409 sc->sc_rx_th.wr_tsf = tsf; 10410 sc->sc_rx_th.wr_rate = rate; 10411 sc->sc_rx_th.wr_antsignal = rssi; 10412 sc->sc_rx_th.wr_antnoise = noise; 10413} 10414 10415static void 10416bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10417{ 10418 uint32_t low, high; 10419 10420 KASSERT(mac->mac_sd->sd_id.sd_rev >= 3, 10421 ("%s:%d: fail", __func__, __LINE__)); 10422 10423 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10424 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10425 *tsf = high; 10426 *tsf <<= 32; 10427 *tsf |= low; 10428} 10429 10430static int 10431bwn_dma_attach(struct bwn_mac *mac) 10432{ 10433 struct bwn_dma *dma = &mac->mac_method.dma; 10434 struct bwn_softc *sc = mac->mac_sc; 10435 struct siba_dev_softc *sd = mac->mac_sd; 10436 struct siba_softc *siba = sd->sd_bus; 10437 bus_addr_t lowaddr = 0; 10438 int error; 10439 10440 if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10441 return (0); 10442 10443 KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__)); 10444 10445 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10446 10447 dma->dmatype = bwn_dma_gettype(mac); 10448 if (dma->dmatype == BWN_DMA_30BIT) 10449 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10450 else if (dma->dmatype == BWN_DMA_32BIT) 10451 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10452 else 10453 lowaddr = BUS_SPACE_MAXADDR; 10454 10455 /* 10456 * Create top level DMA tag 10457 */ 10458 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10459 BWN_ALIGN, 0, /* alignment, bounds */ 10460 lowaddr, /* lowaddr */ 10461 BUS_SPACE_MAXADDR, /* highaddr */ 10462 NULL, NULL, /* filter, filterarg */ 10463 MAXBSIZE, /* maxsize */ 10464 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10465 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10466 0, /* flags */ 10467 NULL, NULL, /* lockfunc, lockarg */ 10468 &dma->parent_dtag); 10469 if (error) { 10470 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10471 return (error); 10472 } 10473 10474 /* 10475 * Create TX/RX mbuf DMA tag 10476 */ 10477 error = bus_dma_tag_create(dma->parent_dtag, 10478 1, 10479 0, 10480 BUS_SPACE_MAXADDR, 10481 BUS_SPACE_MAXADDR, 10482 NULL, NULL, 10483 MCLBYTES, 10484 1, 10485 BUS_SPACE_MAXSIZE_32BIT, 10486 0, 10487 NULL, NULL, 10488 &dma->rxbuf_dtag); 10489 if (error) { 10490 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10491 goto fail0; 10492 } 10493 error = bus_dma_tag_create(dma->parent_dtag, 10494 1, 10495 0, 10496 BUS_SPACE_MAXADDR, 10497 BUS_SPACE_MAXADDR, 10498 NULL, NULL, 10499 MCLBYTES, 10500 1, 10501 BUS_SPACE_MAXSIZE_32BIT, 10502 0, 10503 NULL, NULL, 10504 &dma->txbuf_dtag); 10505 if (error) { 10506 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10507 goto fail1; 10508 } 10509 10510 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10511 if (!dma->wme[WME_AC_BK]) 10512 goto fail2; 10513 10514 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10515 if (!dma->wme[WME_AC_BE]) 10516 goto fail3; 10517 10518 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10519 if (!dma->wme[WME_AC_VI]) 10520 goto fail4; 10521 10522 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10523 if (!dma->wme[WME_AC_VO]) 10524 goto fail5; 10525 10526 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10527 if (!dma->mcast) 10528 goto fail6; 10529 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10530 if (!dma->rx) 10531 goto fail7; 10532 10533 return (error); 10534 10535fail7: bwn_dma_ringfree(&dma->mcast); 10536fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10537fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10538fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10539fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10540fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10541fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10542fail0: bus_dma_tag_destroy(dma->parent_dtag); 10543 return (error); 10544} 10545 10546static struct bwn_dma_ring * 10547bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10548 uint16_t cookie, int *slot) 10549{ 10550 struct bwn_dma *dma = &mac->mac_method.dma; 10551 struct bwn_dma_ring *dr; 10552 struct bwn_softc *sc = mac->mac_sc; 10553 10554 BWN_ASSERT_LOCKED(mac->mac_sc); 10555 10556 switch (cookie & 0xf000) { 10557 case 0x1000: 10558 dr = dma->wme[WME_AC_BK]; 10559 break; 10560 case 0x2000: 10561 dr = dma->wme[WME_AC_BE]; 10562 break; 10563 case 0x3000: 10564 dr = dma->wme[WME_AC_VI]; 10565 break; 10566 case 0x4000: 10567 dr = dma->wme[WME_AC_VO]; 10568 break; 10569 case 0x5000: 10570 dr = dma->mcast; 10571 break; 10572 default: 10573 dr = NULL; 10574 KASSERT(0 == 1, 10575 ("invalid cookie value %d", cookie & 0xf000)); 10576 } 10577 *slot = (cookie & 0x0fff); 10578 if (*slot < 0 || *slot >= dr->dr_numslots) { 10579 /* 10580 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10581 * that it occurs events which have same H/W sequence numbers. 10582 * When it's occurred just prints a WARNING msgs and ignores. 10583 */ 10584 KASSERT(status->seq == dma->lastseq, 10585 ("%s:%d: fail", __func__, __LINE__)); 10586 device_printf(sc->sc_dev, 10587 "out of slot ranges (0 < %d < %d)\n", *slot, 10588 dr->dr_numslots); 10589 return (NULL); 10590 } 10591 dma->lastseq = status->seq; 10592 return (dr); 10593} 10594 10595static void 10596bwn_dma_stop(struct bwn_mac *mac) 10597{ 10598 struct bwn_dma *dma; 10599 10600 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10601 return; 10602 dma = &mac->mac_method.dma; 10603 10604 bwn_dma_ringstop(&dma->rx); 10605 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10606 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10607 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10608 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10609 bwn_dma_ringstop(&dma->mcast); 10610} 10611 10612static void 10613bwn_dma_ringstop(struct bwn_dma_ring **dr) 10614{ 10615 10616 if (dr == NULL) 10617 return; 10618 10619 bwn_dma_cleanup(*dr); 10620} 10621 10622static void 10623bwn_pio_stop(struct bwn_mac *mac) 10624{ 10625 struct bwn_pio *pio; 10626 10627 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10628 return; 10629 pio = &mac->mac_method.pio; 10630 10631 bwn_destroy_queue_tx(&pio->mcast); 10632 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10633 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10634 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10635 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10636} 10637 10638static void 10639bwn_led_attach(struct bwn_mac *mac) 10640{ 10641 struct bwn_softc *sc = mac->mac_sc; 10642 struct siba_softc *siba = mac->mac_sd->sd_bus; 10643 const uint8_t *led_act = NULL; 10644 uint16_t val[BWN_LED_MAX]; 10645 int i; 10646 10647 sc->sc_led_idle = (2350 * hz) / 1000; 10648 sc->sc_led_blink = 1; 10649 10650 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10651 if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) { 10652 led_act = bwn_vendor_led_act[i].led_act; 10653 break; 10654 } 10655 } 10656 if (led_act == NULL) 10657 led_act = bwn_default_led_act; 10658 10659 val[0] = siba->siba_sprom.gpio0; 10660 val[1] = siba->siba_sprom.gpio1; 10661 val[2] = siba->siba_sprom.gpio2; 10662 val[3] = siba->siba_sprom.gpio3; 10663 10664 for (i = 0; i < BWN_LED_MAX; ++i) { 10665 struct bwn_led *led = &sc->sc_leds[i]; 10666 10667 if (val[i] == 0xff) { 10668 led->led_act = led_act[i]; 10669 } else { 10670 if (val[i] & BWN_LED_ACT_LOW) 10671 led->led_flags |= BWN_LED_F_ACTLOW; 10672 led->led_act = val[i] & BWN_LED_ACT_MASK; 10673 } 10674 led->led_mask = (1 << i); 10675 10676 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10677 led->led_act == BWN_LED_ACT_BLINK_POLL || 10678 led->led_act == BWN_LED_ACT_BLINK) { 10679 led->led_flags |= BWN_LED_F_BLINK; 10680 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10681 led->led_flags |= BWN_LED_F_POLLABLE; 10682 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10683 led->led_flags |= BWN_LED_F_SLOW; 10684 10685 if (sc->sc_blink_led == NULL) { 10686 sc->sc_blink_led = led; 10687 if (led->led_flags & BWN_LED_F_SLOW) 10688 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10689 } 10690 } 10691 10692 DPRINTF(sc, BWN_DEBUG_LED, 10693 "%dth led, act %d, lowact %d\n", i, 10694 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10695 } 10696 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10697} 10698 10699static __inline uint16_t 10700bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10701{ 10702 10703 if (led->led_flags & BWN_LED_F_ACTLOW) 10704 on = !on; 10705 if (on) 10706 val |= led->led_mask; 10707 else 10708 val &= ~led->led_mask; 10709 return val; 10710} 10711 10712static void 10713bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10714{ 10715 struct bwn_softc *sc = mac->mac_sc; 10716 struct ifnet *ifp = sc->sc_ifp; 10717 struct ieee80211com *ic = ifp->if_l2com; 10718 uint16_t val; 10719 int i; 10720 10721 if (nstate == IEEE80211_S_INIT) { 10722 callout_stop(&sc->sc_led_blink_ch); 10723 sc->sc_led_blinking = 0; 10724 } 10725 10726 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10727 return; 10728 10729 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10730 for (i = 0; i < BWN_LED_MAX; ++i) { 10731 struct bwn_led *led = &sc->sc_leds[i]; 10732 int on; 10733 10734 if (led->led_act == BWN_LED_ACT_UNKN || 10735 led->led_act == BWN_LED_ACT_NULL) 10736 continue; 10737 10738 if ((led->led_flags & BWN_LED_F_BLINK) && 10739 nstate != IEEE80211_S_INIT) 10740 continue; 10741 10742 switch (led->led_act) { 10743 case BWN_LED_ACT_ON: /* Always on */ 10744 on = 1; 10745 break; 10746 case BWN_LED_ACT_OFF: /* Always off */ 10747 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10748 on = 0; 10749 break; 10750 default: 10751 on = 1; 10752 switch (nstate) { 10753 case IEEE80211_S_INIT: 10754 on = 0; 10755 break; 10756 case IEEE80211_S_RUN: 10757 if (led->led_act == BWN_LED_ACT_11G && 10758 ic->ic_curmode != IEEE80211_MODE_11G) 10759 on = 0; 10760 break; 10761 default: 10762 if (led->led_act == BWN_LED_ACT_ASSOC) 10763 on = 0; 10764 break; 10765 } 10766 break; 10767 } 10768 10769 val = bwn_led_onoff(led, val, on); 10770 } 10771 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10772} 10773 10774static void 10775bwn_led_event(struct bwn_mac *mac, int event) 10776{ 10777 struct bwn_softc *sc = mac->mac_sc; 10778 struct bwn_led *led = sc->sc_blink_led; 10779 int rate; 10780 10781 if (event == BWN_LED_EVENT_POLL) { 10782 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10783 return; 10784 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10785 return; 10786 } 10787 10788 sc->sc_led_ticks = ticks; 10789 if (sc->sc_led_blinking) 10790 return; 10791 10792 switch (event) { 10793 case BWN_LED_EVENT_RX: 10794 rate = sc->sc_rx_rate; 10795 break; 10796 case BWN_LED_EVENT_TX: 10797 rate = sc->sc_tx_rate; 10798 break; 10799 case BWN_LED_EVENT_POLL: 10800 rate = 0; 10801 break; 10802 default: 10803 panic("unknown LED event %d\n", event); 10804 break; 10805 } 10806 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10807 bwn_led_duration[rate].off_dur); 10808} 10809 10810static void 10811bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10812{ 10813 struct bwn_softc *sc = mac->mac_sc; 10814 struct bwn_led *led = sc->sc_blink_led; 10815 uint16_t val; 10816 10817 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10818 val = bwn_led_onoff(led, val, 1); 10819 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10820 10821 if (led->led_flags & BWN_LED_F_SLOW) { 10822 BWN_LED_SLOWDOWN(on_dur); 10823 BWN_LED_SLOWDOWN(off_dur); 10824 } 10825 10826 sc->sc_led_blinking = 1; 10827 sc->sc_led_blink_offdur = off_dur; 10828 10829 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10830} 10831 10832static void 10833bwn_led_blink_next(void *arg) 10834{ 10835 struct bwn_mac *mac = arg; 10836 struct bwn_softc *sc = mac->mac_sc; 10837 uint16_t val; 10838 10839 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10840 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10841 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10842 10843 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10844 bwn_led_blink_end, mac); 10845} 10846 10847static void 10848bwn_led_blink_end(void *arg) 10849{ 10850 struct bwn_mac *mac = arg; 10851 struct bwn_softc *sc = mac->mac_sc; 10852 10853 sc->sc_led_blinking = 0; 10854} 10855 10856static int 10857bwn_suspend(device_t dev) 10858{ 10859 struct bwn_softc *sc = device_get_softc(dev); 10860 10861 bwn_stop(sc, 1); 10862 return (0); 10863} 10864 10865static int 10866bwn_resume(device_t dev) 10867{ 10868 struct bwn_softc *sc = device_get_softc(dev); 10869 struct ifnet *ifp = sc->sc_ifp; 10870 10871 if (ifp->if_flags & IFF_UP) 10872 bwn_init(sc); 10873 return (0); 10874} 10875 10876static void 10877bwn_rfswitch(void *arg) 10878{ 10879 struct bwn_softc *sc = arg; 10880 struct bwn_mac *mac = sc->sc_curmac; 10881 int cur = 0, prev = 0; 10882 10883 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10884 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10885 10886 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10887 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10888 & BWN_RF_HWENABLED_HI_MASK)) 10889 cur = 1; 10890 } else { 10891 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10892 & BWN_RF_HWENABLED_LO_MASK) 10893 cur = 1; 10894 } 10895 10896 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10897 prev = 1; 10898 10899 if (cur != prev) { 10900 if (cur) 10901 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10902 else 10903 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10904 10905 device_printf(sc->sc_dev, 10906 "status of RF switch is changed to %s\n", 10907 cur ? "ON" : "OFF"); 10908 if (cur != mac->mac_phy.rf_on) { 10909 if (cur) 10910 bwn_rf_turnon(mac); 10911 else 10912 bwn_rf_turnoff(mac); 10913 } 10914 } 10915 10916 callout_schedule(&sc->sc_rfswitch_ch, hz); 10917} 10918 10919static void 10920bwn_phy_lp_init_pre(struct bwn_mac *mac) 10921{ 10922 struct bwn_phy *phy = &mac->mac_phy; 10923 struct bwn_phy_lp *plp = &phy->phy_lp; 10924 10925 plp->plp_antenna = BWN_ANT_DEFAULT; 10926} 10927 10928static int 10929bwn_phy_lp_init(struct bwn_mac *mac) 10930{ 10931 static const struct bwn_stxtable tables[] = { 10932 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10933 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10934 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10935 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10936 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10937 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10938 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10939 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10940 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10941 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10942 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10943 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10944 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10945 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10946 { 2, 11, 0x40, 0, 0x0f } 10947 }; 10948 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10949 struct bwn_softc *sc = mac->mac_sc; 10950 const struct bwn_stxtable *st; 10951 struct ifnet *ifp = sc->sc_ifp; 10952 struct ieee80211com *ic = ifp->if_l2com; 10953 int i, error; 10954 uint16_t tmp; 10955 10956 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10957 bwn_phy_lp_bbinit(mac); 10958 10959 /* initialize RF */ 10960 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10961 DELAY(1); 10962 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10963 DELAY(1); 10964 10965 if (mac->mac_phy.rf_ver == 0x2062) 10966 bwn_phy_lp_b2062_init(mac); 10967 else { 10968 bwn_phy_lp_b2063_init(mac); 10969 10970 /* synchronize stx table. */ 10971 for (i = 0; i < N(tables); i++) { 10972 st = &tables[i]; 10973 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10974 tmp >>= st->st_rfshift; 10975 tmp <<= st->st_physhift; 10976 BWN_PHY_SETMASK(mac, 10977 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10978 ~(st->st_mask << st->st_physhift), tmp); 10979 } 10980 10981 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10982 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10983 } 10984 10985 /* calibrate RC */ 10986 if (mac->mac_phy.rev >= 2) 10987 bwn_phy_lp_rxcal_r2(mac); 10988 else if (!plp->plp_rccap) { 10989 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10990 bwn_phy_lp_rccal_r12(mac); 10991 } else 10992 bwn_phy_lp_set_rccap(mac); 10993 10994 error = bwn_phy_lp_switch_channel(mac, 7); 10995 if (error) 10996 device_printf(sc->sc_dev, 10997 "failed to change channel 7 (%d)\n", error); 10998 bwn_phy_lp_txpctl_init(mac); 10999 bwn_phy_lp_calib(mac); 11000 return (0); 11001} 11002 11003static uint16_t 11004bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 11005{ 11006 11007 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11008 return (BWN_READ_2(mac, BWN_PHYDATA)); 11009} 11010 11011static void 11012bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11013{ 11014 11015 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11016 BWN_WRITE_2(mac, BWN_PHYDATA, value); 11017} 11018 11019static void 11020bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 11021 uint16_t set) 11022{ 11023 11024 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 11025 BWN_WRITE_2(mac, BWN_PHYDATA, 11026 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 11027} 11028 11029static uint16_t 11030bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 11031{ 11032 11033 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11034 if (mac->mac_phy.rev < 2 && reg != 0x4001) 11035 reg |= 0x100; 11036 if (mac->mac_phy.rev >= 2) 11037 reg |= 0x200; 11038 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11039 return BWN_READ_2(mac, BWN_RFDATALO); 11040} 11041 11042static void 11043bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 11044{ 11045 11046 KASSERT(reg != 1, ("unaccessible register %d", reg)); 11047 BWN_WRITE_2(mac, BWN_RFCTL, reg); 11048 BWN_WRITE_2(mac, BWN_RFDATALO, value); 11049} 11050 11051static void 11052bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 11053{ 11054 11055 if (on) { 11056 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 11057 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 11058 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 11059 return; 11060 } 11061 11062 if (mac->mac_phy.rev >= 2) { 11063 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 11064 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11065 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 11066 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 11067 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 11068 return; 11069 } 11070 11071 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 11072 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11073 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 11074 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 11075} 11076 11077static int 11078bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11079{ 11080 struct bwn_phy *phy = &mac->mac_phy; 11081 struct bwn_phy_lp *plp = &phy->phy_lp; 11082 int error; 11083 11084 if (phy->rf_ver == 0x2063) { 11085 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11086 if (error) 11087 return (error); 11088 } else { 11089 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11090 if (error) 11091 return (error); 11092 bwn_phy_lp_set_anafilter(mac, chan); 11093 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11094 } 11095 11096 plp->plp_chan = chan; 11097 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11098 return (0); 11099} 11100 11101static uint32_t 11102bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11103{ 11104 struct bwn_softc *sc = mac->mac_sc; 11105 struct ifnet *ifp = sc->sc_ifp; 11106 struct ieee80211com *ic = ifp->if_l2com; 11107 11108 device_printf(sc->sc_dev, "correct?\n"); 11109 11110 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11111} 11112 11113static void 11114bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11115{ 11116 struct bwn_phy *phy = &mac->mac_phy; 11117 struct bwn_phy_lp *plp = &phy->phy_lp; 11118 11119 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11120 return; 11121 11122 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11123 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11124 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11125 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11126 plp->plp_antenna = antenna; 11127} 11128 11129static void 11130bwn_phy_lp_task_60s(struct bwn_mac *mac) 11131{ 11132 11133 bwn_phy_lp_calib(mac); 11134} 11135 11136static void 11137bwn_phy_lp_readsprom(struct bwn_mac *mac) 11138{ 11139 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11140 struct bwn_softc *sc = mac->mac_sc; 11141 struct ifnet *ifp = sc->sc_ifp; 11142 struct ieee80211com *ic = ifp->if_l2com; 11143 struct siba_dev_softc *sd = mac->mac_sd; 11144 struct siba_softc *siba = sd->sd_bus; 11145 struct siba_sprom *sprom = &siba->siba_sprom; 11146 11147 device_printf(sc->sc_dev, "XXX using %dghz\n", 11148 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5); 11149 11150 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11151 plp->plp_txisoband_m = sprom->tri2g; 11152 plp->plp_bxarch = sprom->bxa2g; 11153 plp->plp_rxpwroffset = sprom->rxpo2g; 11154 plp->plp_rssivf = sprom->rssismf2g; 11155 plp->plp_rssivc = sprom->rssismc2g; 11156 plp->plp_rssigs = sprom->rssisav2g; 11157 return; 11158 } 11159 11160 plp->plp_txisoband_l = sprom->tri5gl; 11161 plp->plp_txisoband_m = sprom->tri5g; 11162 plp->plp_txisoband_h = sprom->tri5gh; 11163 plp->plp_bxarch = sprom->bxa5g; 11164 plp->plp_rxpwroffset = sprom->rxpo5g; 11165 plp->plp_rssivf = sprom->rssismf5g; 11166 plp->plp_rssivc = sprom->rssismc5g; 11167 plp->plp_rssigs = sprom->rssisav5g; 11168} 11169 11170static void 11171bwn_phy_lp_bbinit(struct bwn_mac *mac) 11172{ 11173 11174 bwn_phy_lp_tblinit(mac); 11175 if (mac->mac_phy.rev >= 2) 11176 bwn_phy_lp_bbinit_r2(mac); 11177 else 11178 bwn_phy_lp_bbinit_r01(mac); 11179} 11180 11181static void 11182bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11183{ 11184 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11185 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11186 struct bwn_softc *sc = mac->mac_sc; 11187 struct ifnet *ifp = sc->sc_ifp; 11188 struct ieee80211com *ic = ifp->if_l2com; 11189 11190 bwn_phy_lp_set_txgain(mac, 11191 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11192 bwn_phy_lp_set_bbmult(mac, 150); 11193} 11194 11195static void 11196bwn_phy_lp_calib(struct bwn_mac *mac) 11197{ 11198 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11199 struct siba_dev_softc *sd = mac->mac_sd; 11200 struct siba_softc *siba = sd->sd_bus; 11201 struct bwn_softc *sc = mac->mac_sc; 11202 struct ifnet *ifp = sc->sc_ifp; 11203 struct ieee80211com *ic = ifp->if_l2com; 11204 const struct bwn_rxcompco *rc = NULL; 11205 struct bwn_txgain ogain; 11206 int i, omode, oafeovr, orf, obbmult; 11207 uint8_t mode, fc = 0; 11208 11209 if (plp->plp_chanfullcal != plp->plp_chan) { 11210 plp->plp_chanfullcal = plp->plp_chan; 11211 fc = 1; 11212 } 11213 11214 bwn_mac_suspend(mac); 11215 11216 /* BlueTooth Coexistance Override */ 11217 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11218 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11219 11220 if (mac->mac_phy.rev >= 2) 11221 bwn_phy_lp_digflt_save(mac); 11222 bwn_phy_lp_get_txpctlmode(mac); 11223 mode = plp->plp_txpctlmode; 11224 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11225 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11226 bwn_phy_lp_bugfix(mac); 11227 if (mac->mac_phy.rev >= 2 && fc == 1) { 11228 bwn_phy_lp_get_txpctlmode(mac); 11229 omode = plp->plp_txpctlmode; 11230 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11231 if (oafeovr) 11232 ogain = bwn_phy_lp_get_txgain(mac); 11233 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11234 obbmult = bwn_phy_lp_get_bbmult(mac); 11235 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11236 if (oafeovr) 11237 bwn_phy_lp_set_txgain(mac, &ogain); 11238 bwn_phy_lp_set_bbmult(mac, obbmult); 11239 bwn_phy_lp_set_txpctlmode(mac, omode); 11240 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11241 } 11242 bwn_phy_lp_set_txpctlmode(mac, mode); 11243 if (mac->mac_phy.rev >= 2) 11244 bwn_phy_lp_digflt_restore(mac); 11245 11246 /* do RX IQ Calculation; assumes that noise is true. */ 11247 if (siba->siba_chipid == 0x5354) { 11248 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11249 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11250 rc = &bwn_rxcompco_5354[i]; 11251 } 11252 } else if (mac->mac_phy.rev >= 2) 11253 rc = &bwn_rxcompco_r2; 11254 else { 11255 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11256 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11257 rc = &bwn_rxcompco_r12[i]; 11258 } 11259 } 11260 if (rc == NULL) 11261 goto fail; 11262 11263 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11264 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11265 11266 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11267 11268 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11269 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11270 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11271 } else { 11272 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11273 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11274 } 11275 11276 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11277 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11278 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11279 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11280 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11281 bwn_phy_lp_set_deaf(mac, 0); 11282 /* XXX no checking return value? */ 11283 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11284 bwn_phy_lp_clear_deaf(mac, 0); 11285 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11286 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11287 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11288 11289 /* disable RX GAIN override. */ 11290 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11293 if (mac->mac_phy.rev >= 2) { 11294 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11295 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11296 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11297 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11298 } 11299 } else { 11300 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11301 } 11302 11303 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11304 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11305fail: 11306 bwn_mac_enable(mac); 11307} 11308 11309static void 11310bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11311{ 11312 11313 if (on) { 11314 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11315 return; 11316 } 11317 11318 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11319 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11320} 11321 11322static int 11323bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11324{ 11325 struct siba_dev_softc *sd = mac->mac_sd; 11326 struct siba_softc *siba = sd->sd_bus; 11327 static const struct bwn_b206x_chan *bc = NULL; 11328 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11329 tmp[6]; 11330 uint16_t old, scale, tmp16; 11331 int i, div; 11332 11333 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11334 if (bwn_b2063_chantable[i].bc_chan == chan) { 11335 bc = &bwn_b2063_chantable[i]; 11336 break; 11337 } 11338 } 11339 if (bc == NULL) 11340 return (EINVAL); 11341 11342 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11343 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11344 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11345 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11346 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11347 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11348 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11349 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11350 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11351 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11352 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11353 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11354 11355 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11356 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11357 11358 freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11359 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11360 freqref = freqxtal * 3; 11361 div = (freqxtal <= 26000000 ? 1 : 2); 11362 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11363 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11364 999999) / 1000000) + 1; 11365 11366 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11367 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11368 0xfff8, timeout >> 2); 11369 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11370 0xff9f,timeout << 5); 11371 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11372 11373 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11374 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11375 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11376 11377 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11378 (timeoutref + 1)) - 1; 11379 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11380 0xf0, count >> 8); 11381 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11382 11383 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11384 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11385 while (tmp[1] >= freqref) { 11386 tmp[0]++; 11387 tmp[1] -= freqref; 11388 } 11389 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11390 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11391 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11392 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11393 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11394 11395 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11396 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11397 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11398 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11399 11400 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11401 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11402 11403 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11404 scale = 1; 11405 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11406 } else { 11407 scale = 0; 11408 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11409 } 11410 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11411 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11412 11413 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11414 (scale + 1); 11415 if (tmp[5] > 150) 11416 tmp[5] = 0; 11417 11418 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11419 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11420 11421 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11422 if (freqxtal > 26000000) 11423 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11424 else 11425 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11426 11427 if (val[0] == 45) 11428 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11429 else 11430 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11431 11432 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11433 DELAY(1); 11434 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11435 11436 /* VCO Calibration */ 11437 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11438 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11439 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11440 DELAY(1); 11441 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11442 DELAY(1); 11443 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11444 DELAY(1); 11445 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11446 DELAY(300); 11447 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11448 11449 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11450 return (0); 11451} 11452 11453static int 11454bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11455{ 11456 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11457 struct siba_dev_softc *sd = mac->mac_sd; 11458 struct siba_softc *siba = sd->sd_bus; 11459 const struct bwn_b206x_chan *bc = NULL; 11460 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 11461 uint32_t tmp[9]; 11462 int i; 11463 11464 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11465 if (bwn_b2062_chantable[i].bc_chan == chan) { 11466 bc = &bwn_b2062_chantable[i]; 11467 break; 11468 } 11469 } 11470 11471 if (bc == NULL) 11472 return (EINVAL); 11473 11474 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11475 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11476 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11477 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11478 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11479 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11480 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11481 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11482 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11483 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11484 11485 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11486 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11487 bwn_phy_lp_b2062_reset_pllbias(mac); 11488 tmp[0] = freqxtal / 1000; 11489 tmp[1] = plp->plp_div * 1000; 11490 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11491 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11492 tmp[2] *= 2; 11493 tmp[3] = 48 * tmp[0]; 11494 tmp[5] = tmp[2] / tmp[3]; 11495 tmp[6] = tmp[2] % tmp[3]; 11496 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11497 tmp[4] = tmp[6] * 0x100; 11498 tmp[5] = tmp[4] / tmp[3]; 11499 tmp[6] = tmp[4] % tmp[3]; 11500 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11501 tmp[4] = tmp[6] * 0x100; 11502 tmp[5] = tmp[4] / tmp[3]; 11503 tmp[6] = tmp[4] % tmp[3]; 11504 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11505 tmp[4] = tmp[6] * 0x100; 11506 tmp[5] = tmp[4] / tmp[3]; 11507 tmp[6] = tmp[4] % tmp[3]; 11508 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11509 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11510 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11511 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11512 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11513 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11514 11515 bwn_phy_lp_b2062_vco_calib(mac); 11516 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11517 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11518 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11519 bwn_phy_lp_b2062_reset_pllbias(mac); 11520 bwn_phy_lp_b2062_vco_calib(mac); 11521 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11522 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11523 return (EIO); 11524 } 11525 } 11526 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11527 return (0); 11528} 11529 11530static void 11531bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11532{ 11533 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11534 uint16_t tmp = (channel == 14); 11535 11536 if (mac->mac_phy.rev < 2) { 11537 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11538 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11539 bwn_phy_lp_set_rccap(mac); 11540 return; 11541 } 11542 11543 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11544} 11545 11546static void 11547bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11548{ 11549 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11550 struct bwn_softc *sc = mac->mac_sc; 11551 struct ifnet *ifp = sc->sc_ifp; 11552 struct ieee80211com *ic = ifp->if_l2com; 11553 uint16_t iso, tmp[3]; 11554 11555 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11556 11557 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11558 iso = plp->plp_txisoband_m; 11559 else if (freq <= 5320) 11560 iso = plp->plp_txisoband_l; 11561 else if (freq <= 5700) 11562 iso = plp->plp_txisoband_m; 11563 else 11564 iso = plp->plp_txisoband_h; 11565 11566 tmp[0] = ((iso - 26) / 12) << 12; 11567 tmp[1] = tmp[0] + 0x1000; 11568 tmp[2] = tmp[0] + 0x2000; 11569 11570 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11571 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11572} 11573 11574static void 11575bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11576{ 11577 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11578 int i; 11579 static const uint16_t addr[] = { 11580 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11581 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11582 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11583 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11584 BWN_PHY_OFDM(0xcf), 11585 }; 11586 static const uint16_t val[] = { 11587 0xde5e, 0xe832, 0xe331, 0x4d26, 11588 0x0026, 0x1420, 0x0020, 0xfe08, 11589 0x0008, 11590 }; 11591 11592 for (i = 0; i < N(addr); i++) { 11593 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11594 BWN_PHY_WRITE(mac, addr[i], val[i]); 11595 } 11596} 11597 11598static void 11599bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11600{ 11601 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11602 struct bwn_softc *sc = mac->mac_sc; 11603 uint16_t ctl; 11604 11605 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11606 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11607 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11608 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11609 break; 11610 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11611 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11612 break; 11613 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11614 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11615 break; 11616 default: 11617 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11618 device_printf(sc->sc_dev, "unknown command mode\n"); 11619 break; 11620 } 11621} 11622 11623static void 11624bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11625{ 11626 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11627 uint16_t ctl; 11628 uint8_t old; 11629 11630 bwn_phy_lp_get_txpctlmode(mac); 11631 old = plp->plp_txpctlmode; 11632 if (old == mode) 11633 return; 11634 plp->plp_txpctlmode = mode; 11635 11636 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11637 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11638 plp->plp_tssiidx); 11639 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11640 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11641 11642 /* disable TX GAIN override */ 11643 if (mac->mac_phy.rev < 2) 11644 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11645 else { 11646 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11647 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11648 } 11649 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11650 11651 plp->plp_txpwridx = -1; 11652 } 11653 if (mac->mac_phy.rev >= 2) { 11654 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11655 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11656 else 11657 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11658 } 11659 11660 /* writes TX Power Control mode */ 11661 switch (plp->plp_txpctlmode) { 11662 case BWN_PHYLP_TXPCTL_OFF: 11663 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11664 break; 11665 case BWN_PHYLP_TXPCTL_ON_HW: 11666 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11667 break; 11668 case BWN_PHYLP_TXPCTL_ON_SW: 11669 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11670 break; 11671 default: 11672 ctl = 0; 11673 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11674 } 11675 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11676 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11677} 11678 11679static void 11680bwn_phy_lp_bugfix(struct bwn_mac *mac) 11681{ 11682 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11683 struct bwn_softc *sc = mac->mac_sc; 11684 const unsigned int size = 256; 11685 struct bwn_txgain tg; 11686 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11687 uint16_t tssinpt, tssiidx, value[2]; 11688 uint8_t mode; 11689 int8_t txpwridx; 11690 11691 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11692 M_NOWAIT | M_ZERO); 11693 if (tabs == NULL) { 11694 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11695 return; 11696 } 11697 11698 bwn_phy_lp_get_txpctlmode(mac); 11699 mode = plp->plp_txpctlmode; 11700 txpwridx = plp->plp_txpwridx; 11701 tssinpt = plp->plp_tssinpt; 11702 tssiidx = plp->plp_tssiidx; 11703 11704 bwn_tab_read_multi(mac, 11705 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11706 BWN_TAB_4(7, 0x140), size, tabs); 11707 11708 bwn_phy_lp_tblinit(mac); 11709 bwn_phy_lp_bbinit(mac); 11710 bwn_phy_lp_txpctl_init(mac); 11711 bwn_phy_lp_rf_onoff(mac, 1); 11712 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11713 11714 bwn_tab_write_multi(mac, 11715 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11716 BWN_TAB_4(7, 0x140), size, tabs); 11717 11718 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11719 plp->plp_tssinpt = tssinpt; 11720 plp->plp_tssiidx = tssiidx; 11721 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11722 if (txpwridx != -1) { 11723 /* set TX power by index */ 11724 plp->plp_txpwridx = txpwridx; 11725 bwn_phy_lp_get_txpctlmode(mac); 11726 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11727 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11728 if (mac->mac_phy.rev >= 2) { 11729 rxcomp = bwn_tab_read(mac, 11730 BWN_TAB_4(7, txpwridx + 320)); 11731 txgain = bwn_tab_read(mac, 11732 BWN_TAB_4(7, txpwridx + 192)); 11733 tg.tg_pad = (txgain >> 16) & 0xff; 11734 tg.tg_gm = txgain & 0xff; 11735 tg.tg_pga = (txgain >> 8) & 0xff; 11736 tg.tg_dac = (rxcomp >> 28) & 0xff; 11737 bwn_phy_lp_set_txgain(mac, &tg); 11738 } else { 11739 rxcomp = bwn_tab_read(mac, 11740 BWN_TAB_4(10, txpwridx + 320)); 11741 txgain = bwn_tab_read(mac, 11742 BWN_TAB_4(10, txpwridx + 192)); 11743 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11744 0xf800, (txgain >> 4) & 0x7fff); 11745 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11746 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11747 } 11748 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11749 11750 /* set TX IQCC */ 11751 value[0] = (rxcomp >> 10) & 0x3ff; 11752 value[1] = rxcomp & 0x3ff; 11753 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11754 11755 coeff = bwn_tab_read(mac, 11756 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11757 BWN_TAB_4(10, txpwridx + 448)); 11758 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11759 if (mac->mac_phy.rev >= 2) { 11760 rfpwr = bwn_tab_read(mac, 11761 BWN_TAB_4(7, txpwridx + 576)); 11762 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11763 rfpwr & 0xffff); 11764 } 11765 bwn_phy_lp_set_txgain_override(mac); 11766 } 11767 if (plp->plp_rccap) 11768 bwn_phy_lp_set_rccap(mac); 11769 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11770 bwn_phy_lp_set_txpctlmode(mac, mode); 11771 free(tabs, M_DEVBUF); 11772} 11773 11774static void 11775bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11776{ 11777 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11778 int i; 11779 static const uint16_t addr[] = { 11780 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11781 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11782 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11783 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11784 BWN_PHY_OFDM(0xcf), 11785 }; 11786 11787 for (i = 0; i < N(addr); i++) 11788 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11789} 11790 11791static void 11792bwn_phy_lp_tblinit(struct bwn_mac *mac) 11793{ 11794 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11795 11796 if (mac->mac_phy.rev < 2) { 11797 bwn_phy_lp_tblinit_r01(mac); 11798 bwn_phy_lp_tblinit_txgain(mac); 11799 bwn_phy_lp_set_gaintbl(mac, freq); 11800 return; 11801 } 11802 11803 bwn_phy_lp_tblinit_r2(mac); 11804 bwn_phy_lp_tblinit_txgain(mac); 11805} 11806 11807struct bwn_wpair { 11808 uint16_t reg; 11809 uint16_t value; 11810}; 11811 11812struct bwn_smpair { 11813 uint16_t offset; 11814 uint16_t mask; 11815 uint16_t set; 11816}; 11817 11818static void 11819bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11820{ 11821 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11822 struct siba_dev_softc *sd = mac->mac_sd; 11823 struct siba_softc *siba = sd->sd_bus; 11824 struct bwn_softc *sc = mac->mac_sc; 11825 struct ifnet *ifp = sc->sc_ifp; 11826 struct ieee80211com *ic = ifp->if_l2com; 11827 static const struct bwn_wpair v1[] = { 11828 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11829 { BWN_PHY_AFE_CTL, 0x8800 }, 11830 { BWN_PHY_AFE_CTL_OVR, 0 }, 11831 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11832 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11833 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11834 { BWN_PHY_OFDM(0xf9), 0 }, 11835 { BWN_PHY_TR_LOOKUP_1, 0 } 11836 }; 11837 static const struct bwn_smpair v2[] = { 11838 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11839 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11840 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11841 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11842 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11843 }; 11844 static const struct bwn_smpair v3[] = { 11845 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11846 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11847 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11848 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11849 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11850 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11851 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11852 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11853 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11854 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11855 11856 }; 11857 int i; 11858 11859 for (i = 0; i < N(v1); i++) 11860 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11861 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11862 for (i = 0; i < N(v2); i++) 11863 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11864 11865 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11866 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11867 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11868 if (siba->siba_board_rev >= 0x18) { 11869 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11870 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11871 } else { 11872 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11873 } 11874 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11875 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11876 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11877 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11878 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11879 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11880 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11881 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11882 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11883 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11884 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11885 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11886 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11887 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11888 } else { 11889 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11890 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11891 } 11892 for (i = 0; i < N(v3); i++) 11893 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11894 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11895 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11896 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11897 } 11898 11899 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11900 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11901 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11902 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11903 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11904 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11905 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11906 } else 11907 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11908 11909 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11910 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11911 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11912 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11913 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11914 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11915 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11916 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11917 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11918 11919 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 11920 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11921 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11922 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11923 } 11924 11925 bwn_phy_lp_digflt_save(mac); 11926} 11927 11928static void 11929bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11930{ 11931 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11932 struct siba_dev_softc *sd = mac->mac_sd; 11933 struct siba_softc *siba = sd->sd_bus; 11934 struct bwn_softc *sc = mac->mac_sc; 11935 struct ifnet *ifp = sc->sc_ifp; 11936 struct ieee80211com *ic = ifp->if_l2com; 11937 static const struct bwn_smpair v1[] = { 11938 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11939 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11940 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11941 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11942 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11943 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11944 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11945 }; 11946 static const struct bwn_smpair v2[] = { 11947 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11948 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11949 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11950 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11951 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11952 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11953 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11954 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11955 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11956 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11957 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11958 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11959 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11960 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11961 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11962 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11963 }; 11964 static const struct bwn_smpair v3[] = { 11965 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11966 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11967 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11968 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11969 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11970 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11971 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11972 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11973 }; 11974 static const struct bwn_smpair v4[] = { 11975 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11976 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11977 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11978 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11979 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11980 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11981 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11982 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11983 }; 11984 static const struct bwn_smpair v5[] = { 11985 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11986 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11987 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11988 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11989 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11990 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11991 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11992 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11993 }; 11994 int i; 11995 uint16_t tmp, tmp2; 11996 11997 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11998 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11999 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 12000 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 12001 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 12002 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 12003 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 12004 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 12005 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 12006 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 12007 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 12008 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 12009 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 12010 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 12011 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 12012 for (i = 0; i < N(v1); i++) 12013 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 12014 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 12015 0xff00, plp->plp_rxpwroffset); 12016 if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) && 12017 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 12018 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) { 12019 siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28); 12020 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1); 12021 if (mac->mac_phy.rev == 0) 12022 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 12023 0xffcf, 0x0010); 12024 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 12025 } else { 12026 siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0); 12027 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 12028 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 12029 } 12030 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 12031 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 12032 if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV) 12033 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 12034 else 12035 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 12036 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 12037 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 12038 0xfff9, (plp->plp_bxarch << 1)); 12039 if (mac->mac_phy.rev == 1 && 12040 (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) { 12041 for (i = 0; i < N(v2); i++) 12042 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 12043 v2[i].set); 12044 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 12045 (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) && 12046 (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) { 12047 for (i = 0; i < N(v3); i++) 12048 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 12049 v3[i].set); 12050 } else if (mac->mac_phy.rev == 1 || 12051 (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) { 12052 for (i = 0; i < N(v4); i++) 12053 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 12054 v4[i].set); 12055 } else { 12056 for (i = 0; i < N(v5); i++) 12057 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 12058 v5[i].set); 12059 } 12060 if (mac->mac_phy.rev == 1 && 12061 (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) { 12062 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 12063 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 12064 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 12065 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 12066 } 12067 if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) && 12068 (siba->siba_chipid == 0x5354) && 12069 (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) { 12070 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 12071 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 12072 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 12073 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 12074 } 12075 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12076 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 12077 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 12078 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 12079 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 12080 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 12081 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 12082 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 12083 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 12084 } else { 12085 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 12086 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 12087 } 12088 if (mac->mac_phy.rev == 1) { 12089 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12090 tmp2 = (tmp & 0x03e0) >> 5; 12091 tmp2 |= tmp2 << 5; 12092 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12093 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12094 tmp2 = (tmp & 0x1f00) >> 8; 12095 tmp2 |= tmp2 << 5; 12096 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12097 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12098 tmp2 = tmp & 0x00ff; 12099 tmp2 |= tmp << 8; 12100 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12101 } 12102} 12103 12104struct bwn_b2062_freq { 12105 uint16_t freq; 12106 uint8_t value[6]; 12107}; 12108 12109static void 12110bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12111{ 12112#define CALC_CTL7(freq, div) \ 12113 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12114#define CALC_CTL18(freq, div) \ 12115 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12116#define CALC_CTL19(freq, div) \ 12117 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12118 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12119 struct siba_dev_softc *sd = mac->mac_sd; 12120 struct siba_softc *siba = sd->sd_bus; 12121 struct bwn_softc *sc = mac->mac_sc; 12122 struct ifnet *ifp = sc->sc_ifp; 12123 struct ieee80211com *ic = ifp->if_l2com; 12124 static const struct bwn_b2062_freq freqdata_tab[] = { 12125 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12126 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12127 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12128 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12129 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12130 { 19200, { 1, 1, 1, 1, 14, 9 } } 12131 }; 12132 static const struct bwn_wpair v1[] = { 12133 { BWN_B2062_N_TXCTL3, 0 }, 12134 { BWN_B2062_N_TXCTL4, 0 }, 12135 { BWN_B2062_N_TXCTL5, 0 }, 12136 { BWN_B2062_N_TXCTL6, 0 }, 12137 { BWN_B2062_N_PDNCTL0, 0x40 }, 12138 { BWN_B2062_N_PDNCTL0, 0 }, 12139 { BWN_B2062_N_CALIB_TS, 0x10 }, 12140 { BWN_B2062_N_CALIB_TS, 0 } 12141 }; 12142 const struct bwn_b2062_freq *f = NULL; 12143 uint32_t xtalfreq, ref; 12144 unsigned int i; 12145 12146 bwn_phy_lp_b2062_tblinit(mac); 12147 12148 for (i = 0; i < N(v1); i++) 12149 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12150 if (mac->mac_phy.rev > 0) 12151 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12152 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12153 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12154 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12155 else 12156 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12157 12158 KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU, 12159 ("%s:%d: fail", __func__, __LINE__)); 12160 xtalfreq = siba->siba_cc.scc_pmu.freq * 1000; 12161 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12162 12163 if (xtalfreq <= 30000000) { 12164 plp->plp_div = 1; 12165 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12166 } else { 12167 plp->plp_div = 2; 12168 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12169 } 12170 12171 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12172 CALC_CTL7(xtalfreq, plp->plp_div)); 12173 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12174 CALC_CTL18(xtalfreq, plp->plp_div)); 12175 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12176 CALC_CTL19(xtalfreq, plp->plp_div)); 12177 12178 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12179 ref &= 0xffff; 12180 for (i = 0; i < N(freqdata_tab); i++) { 12181 if (ref < freqdata_tab[i].freq) { 12182 f = &freqdata_tab[i]; 12183 break; 12184 } 12185 } 12186 if (f == NULL) 12187 f = &freqdata_tab[N(freqdata_tab) - 1]; 12188 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12189 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12190 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12191 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12192 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12193 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12194#undef CALC_CTL7 12195#undef CALC_CTL18 12196#undef CALC_CTL19 12197} 12198 12199static void 12200bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12201{ 12202 12203 bwn_phy_lp_b2063_tblinit(mac); 12204 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12205 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12206 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12207 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12208 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12209 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12210 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12211 if (mac->mac_phy.rev == 2) { 12212 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12213 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12214 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12215 } else { 12216 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12217 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12218 } 12219} 12220 12221static void 12222bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12223{ 12224 struct siba_dev_softc *sd = mac->mac_sd; 12225 struct siba_softc *siba = sd->sd_bus; 12226 static const struct bwn_wpair v1[] = { 12227 { BWN_B2063_RX_BB_SP8, 0x0 }, 12228 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12229 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12230 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12231 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12232 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12233 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12234 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12235 }; 12236 static const struct bwn_wpair v2[] = { 12237 { BWN_B2063_TX_BB_SP3, 0x0 }, 12238 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12239 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12240 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12241 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12242 }; 12243 uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000; 12244 int i; 12245 uint8_t tmp; 12246 12247 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12248 12249 for (i = 0; i < 2; i++) 12250 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12251 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12252 for (i = 2; i < N(v1); i++) 12253 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12254 for (i = 0; i < 10000; i++) { 12255 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12256 break; 12257 DELAY(1000); 12258 } 12259 12260 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12261 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12262 12263 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12264 12265 for (i = 0; i < N(v2); i++) 12266 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12267 if (freqxtal == 24000000) { 12268 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12269 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12270 } else { 12271 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12272 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12273 } 12274 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12275 for (i = 0; i < 10000; i++) { 12276 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12277 break; 12278 DELAY(1000); 12279 } 12280 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12281 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12282 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12283} 12284 12285static void 12286bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12287{ 12288 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12289 struct bwn_softc *sc = mac->mac_sc; 12290 struct bwn_phy_lp_iq_est ie; 12291 struct bwn_txgain tx_gains; 12292 static const uint32_t pwrtbl[21] = { 12293 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12294 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12295 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12296 0x0004c, 0x0002c, 0x0001a, 12297 }; 12298 uint32_t npwr, ipwr, sqpwr, tmp; 12299 int loopback, i, j, sum, error; 12300 uint16_t save[7]; 12301 uint8_t txo, bbmult, txpctlmode; 12302 12303 error = bwn_phy_lp_switch_channel(mac, 7); 12304 if (error) 12305 device_printf(sc->sc_dev, 12306 "failed to change channel to 7 (%d)\n", error); 12307 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12308 bbmult = bwn_phy_lp_get_bbmult(mac); 12309 if (txo) 12310 tx_gains = bwn_phy_lp_get_txgain(mac); 12311 12312 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12313 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12314 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12315 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12316 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12317 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12318 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12319 12320 bwn_phy_lp_get_txpctlmode(mac); 12321 txpctlmode = plp->plp_txpctlmode; 12322 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12323 12324 /* disable CRS */ 12325 bwn_phy_lp_set_deaf(mac, 1); 12326 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12327 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12328 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12329 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12330 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12331 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12332 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12333 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12334 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12335 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12336 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12337 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12338 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12339 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12340 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12341 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12342 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12343 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12344 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12345 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12346 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12347 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12348 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12349 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12350 12351 loopback = bwn_phy_lp_loopback(mac); 12352 if (loopback == -1) 12353 goto done; 12354 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12355 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12356 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12357 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12358 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12359 12360 tmp = 0; 12361 memset(&ie, 0, sizeof(ie)); 12362 for (i = 128; i <= 159; i++) { 12363 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12364 sum = 0; 12365 for (j = 5; j <= 25; j++) { 12366 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12367 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12368 goto done; 12369 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12370 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12371 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12372 12); 12373 sum += ((ipwr - npwr) * (ipwr - npwr)); 12374 if ((i == 128) || (sum < tmp)) { 12375 plp->plp_rccap = i; 12376 tmp = sum; 12377 } 12378 } 12379 } 12380 bwn_phy_lp_ddfs_turnoff(mac); 12381done: 12382 /* restore CRS */ 12383 bwn_phy_lp_clear_deaf(mac, 1); 12384 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12385 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12386 12387 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12388 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12389 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12390 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12391 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12392 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12393 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12394 12395 bwn_phy_lp_set_bbmult(mac, bbmult); 12396 if (txo) 12397 bwn_phy_lp_set_txgain(mac, &tx_gains); 12398 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12399 if (plp->plp_rccap) 12400 bwn_phy_lp_set_rccap(mac); 12401} 12402 12403static void 12404bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12405{ 12406 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12407 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12408 12409 if (mac->mac_phy.rev == 1) 12410 rc_cap = MIN(rc_cap + 5, 15); 12411 12412 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12413 MAX(plp->plp_rccap - 4, 0x80)); 12414 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12415 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12416 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12417} 12418 12419static uint32_t 12420bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12421{ 12422 uint32_t i, q, r; 12423 12424 if (div == 0) 12425 return (0); 12426 12427 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12428 q <<= 1; 12429 if (r << 1 >= div) { 12430 q++; 12431 r = (r << 1) - div; 12432 } 12433 } 12434 if (r << 1 >= div) 12435 q++; 12436 return (q); 12437} 12438 12439static void 12440bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12441{ 12442 struct siba_dev_softc *sd = mac->mac_sd; 12443 struct siba_softc *siba = sd->sd_bus; 12444 12445 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12446 DELAY(20); 12447 if (siba->siba_chipid == 0x5354) { 12448 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12449 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12450 } else { 12451 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12452 } 12453 DELAY(5); 12454} 12455 12456static void 12457bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12458{ 12459 12460 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12461 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12462 DELAY(200); 12463} 12464 12465static void 12466bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12467{ 12468#define FLAG_A 0x01 12469#define FLAG_G 0x02 12470 struct bwn_softc *sc = mac->mac_sc; 12471 struct ifnet *ifp = sc->sc_ifp; 12472 struct ieee80211com *ic = ifp->if_l2com; 12473 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12474 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12475 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12476 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12477 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12478 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12479 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12480 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12481 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12482 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12483 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12484 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12485 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12486 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12487 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12488 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12489 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12490 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12491 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12492 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12493 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12494 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12495 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12496 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12497 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12498 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12499 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12500 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12501 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12502 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12503 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12504 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12505 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12506 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12507 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12508 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12509 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12510 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12511 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12512 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12513 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12514 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12515 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12516 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12517 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12518 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12519 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12520 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12521 }; 12522 const struct bwn_b206x_rfinit_entry *br; 12523 unsigned int i; 12524 12525 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12526 br = &bwn_b2062_init_tab[i]; 12527 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12528 if (br->br_flags & FLAG_G) 12529 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12530 } else { 12531 if (br->br_flags & FLAG_A) 12532 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12533 } 12534 } 12535#undef FLAG_A 12536#undef FLAG_B 12537} 12538 12539static void 12540bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12541{ 12542#define FLAG_A 0x01 12543#define FLAG_G 0x02 12544 struct bwn_softc *sc = mac->mac_sc; 12545 struct ifnet *ifp = sc->sc_ifp; 12546 struct ieee80211com *ic = ifp->if_l2com; 12547 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12548 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12549 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12550 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12551 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12552 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12553 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12554 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12555 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12556 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12557 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12558 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12559 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12560 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12561 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12562 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12563 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12564 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12565 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12566 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12567 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12568 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12569 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12570 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12571 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12572 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12573 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12574 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12575 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12576 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12577 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12578 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12579 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12580 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12581 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12582 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12583 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12584 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12585 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12586 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12587 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12588 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12589 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12590 }; 12591 const struct bwn_b206x_rfinit_entry *br; 12592 unsigned int i; 12593 12594 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12595 br = &bwn_b2063_init_tab[i]; 12596 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12597 if (br->br_flags & FLAG_G) 12598 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12599 } else { 12600 if (br->br_flags & FLAG_A) 12601 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12602 } 12603 } 12604#undef FLAG_A 12605#undef FLAG_B 12606} 12607 12608static void 12609bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12610 int count, void *_data) 12611{ 12612 unsigned int i; 12613 uint32_t offset, type; 12614 uint8_t *data = _data; 12615 12616 type = BWN_TAB_GETTYPE(typenoffset); 12617 offset = BWN_TAB_GETOFFSET(typenoffset); 12618 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12619 12620 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12621 12622 for (i = 0; i < count; i++) { 12623 switch (type) { 12624 case BWN_TAB_8BIT: 12625 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12626 data++; 12627 break; 12628 case BWN_TAB_16BIT: 12629 *((uint16_t *)data) = BWN_PHY_READ(mac, 12630 BWN_PHY_TABLEDATALO); 12631 data += 2; 12632 break; 12633 case BWN_TAB_32BIT: 12634 *((uint32_t *)data) = BWN_PHY_READ(mac, 12635 BWN_PHY_TABLEDATAHI); 12636 *((uint32_t *)data) <<= 16; 12637 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12638 BWN_PHY_TABLEDATALO); 12639 data += 4; 12640 break; 12641 default: 12642 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12643 } 12644 } 12645} 12646 12647static void 12648bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12649 int count, const void *_data) 12650{ 12651 uint32_t offset, type, value; 12652 const uint8_t *data = _data; 12653 unsigned int i; 12654 12655 type = BWN_TAB_GETTYPE(typenoffset); 12656 offset = BWN_TAB_GETOFFSET(typenoffset); 12657 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12658 12659 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12660 12661 for (i = 0; i < count; i++) { 12662 switch (type) { 12663 case BWN_TAB_8BIT: 12664 value = *data; 12665 data++; 12666 KASSERT(!(value & ~0xff), 12667 ("%s:%d: fail", __func__, __LINE__)); 12668 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12669 break; 12670 case BWN_TAB_16BIT: 12671 value = *((const uint16_t *)data); 12672 data += 2; 12673 KASSERT(!(value & ~0xffff), 12674 ("%s:%d: fail", __func__, __LINE__)); 12675 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12676 break; 12677 case BWN_TAB_32BIT: 12678 value = *((const uint32_t *)data); 12679 data += 4; 12680 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12681 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12682 break; 12683 default: 12684 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12685 } 12686 } 12687} 12688 12689static struct bwn_txgain 12690bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12691{ 12692 struct bwn_txgain tg; 12693 uint16_t tmp; 12694 12695 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12696 if (mac->mac_phy.rev < 2) { 12697 tmp = BWN_PHY_READ(mac, 12698 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12699 tg.tg_gm = tmp & 0x0007; 12700 tg.tg_pga = (tmp & 0x0078) >> 3; 12701 tg.tg_pad = (tmp & 0x780) >> 7; 12702 return (tg); 12703 } 12704 12705 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12706 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12707 tg.tg_gm = tmp & 0xff; 12708 tg.tg_pga = (tmp >> 8) & 0xff; 12709 return (tg); 12710} 12711 12712static uint8_t 12713bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12714{ 12715 12716 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12717} 12718 12719static void 12720bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12721{ 12722 uint16_t pa; 12723 12724 if (mac->mac_phy.rev < 2) { 12725 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12726 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12727 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12728 bwn_phy_lp_set_txgain_override(mac); 12729 return; 12730 } 12731 12732 pa = bwn_phy_lp_get_pa_gain(mac); 12733 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12734 (tg->tg_pga << 8) | tg->tg_gm); 12735 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12736 tg->tg_pad | (pa << 6)); 12737 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12738 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12739 tg->tg_pad | (pa << 8)); 12740 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12741 bwn_phy_lp_set_txgain_override(mac); 12742} 12743 12744static void 12745bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12746{ 12747 12748 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12749} 12750 12751static void 12752bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12753{ 12754 uint16_t trsw = (tx << 1) | rx; 12755 12756 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12757 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12758} 12759 12760static void 12761bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12762{ 12763 struct bwn_softc *sc = mac->mac_sc; 12764 struct ifnet *ifp = sc->sc_ifp; 12765 struct ieee80211com *ic = ifp->if_l2com; 12766 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12767 12768 if (mac->mac_phy.rev < 2) { 12769 trsw = gain & 0x1; 12770 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12771 ext_lna = (gain & 2) >> 1; 12772 12773 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12774 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12775 0xfbff, ext_lna << 10); 12776 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12777 0xf7ff, ext_lna << 11); 12778 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12779 } else { 12780 low_gain = gain & 0xffff; 12781 high_gain = (gain >> 16) & 0xf; 12782 ext_lna = (gain >> 21) & 0x1; 12783 trsw = ~(gain >> 20) & 0x1; 12784 12785 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12786 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12787 0xfdff, ext_lna << 9); 12788 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12789 0xfbff, ext_lna << 10); 12790 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12791 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12792 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12793 tmp = (gain >> 2) & 0x3; 12794 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12795 0xe7ff, tmp<<11); 12796 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12797 tmp << 3); 12798 } 12799 } 12800 12801 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12802 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12803 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12804 if (mac->mac_phy.rev >= 2) { 12805 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12806 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12807 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12808 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12809 } 12810 return; 12811 } 12812 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12813} 12814 12815static void 12816bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12817{ 12818 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12819 12820 if (user) 12821 plp->plp_crsusr_off = 1; 12822 else 12823 plp->plp_crssys_off = 1; 12824 12825 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12826} 12827 12828static void 12829bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12830{ 12831 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12832 struct bwn_softc *sc = mac->mac_sc; 12833 struct ifnet *ifp = sc->sc_ifp; 12834 struct ieee80211com *ic = ifp->if_l2com; 12835 12836 if (user) 12837 plp->plp_crsusr_off = 0; 12838 else 12839 plp->plp_crssys_off = 0; 12840 12841 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12842 return; 12843 12844 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12845 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12846 else 12847 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12848} 12849 12850static unsigned int 12851bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12852{ 12853 struct bwn_softc *sc = mac->mac_sc; 12854 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12855 static uint8_t sqrt_table[256] = { 12856 10, 14, 17, 20, 22, 24, 26, 28, 12857 30, 31, 33, 34, 36, 37, 38, 40, 12858 41, 42, 43, 44, 45, 46, 47, 48, 12859 50, 50, 51, 52, 53, 54, 55, 56, 12860 57, 58, 59, 60, 60, 61, 62, 63, 12861 64, 64, 65, 66, 67, 67, 68, 69, 12862 70, 70, 71, 72, 72, 73, 74, 74, 12863 75, 76, 76, 77, 78, 78, 79, 80, 12864 80, 81, 81, 82, 83, 83, 84, 84, 12865 85, 86, 86, 87, 87, 88, 88, 89, 12866 90, 90, 91, 91, 92, 92, 93, 93, 12867 94, 94, 95, 95, 96, 96, 97, 97, 12868 98, 98, 99, 100, 100, 100, 101, 101, 12869 102, 102, 103, 103, 104, 104, 105, 105, 12870 106, 106, 107, 107, 108, 108, 109, 109, 12871 110, 110, 110, 111, 111, 112, 112, 113, 12872 113, 114, 114, 114, 115, 115, 116, 116, 12873 117, 117, 117, 118, 118, 119, 119, 120, 12874 120, 120, 121, 121, 122, 122, 122, 123, 12875 123, 124, 124, 124, 125, 125, 126, 126, 12876 126, 127, 127, 128, 128, 128, 129, 129, 12877 130, 130, 130, 131, 131, 131, 132, 132, 12878 133, 133, 133, 134, 134, 134, 135, 135, 12879 136, 136, 136, 137, 137, 137, 138, 138, 12880 138, 139, 139, 140, 140, 140, 141, 141, 12881 141, 142, 142, 142, 143, 143, 143, 144, 12882 144, 144, 145, 145, 145, 146, 146, 146, 12883 147, 147, 147, 148, 148, 148, 149, 149, 12884 150, 150, 150, 150, 151, 151, 151, 152, 12885 152, 152, 153, 153, 153, 154, 154, 154, 12886 155, 155, 155, 156, 156, 156, 157, 157, 12887 157, 158, 158, 158, 159, 159, 159, 160 12888 }; 12889 12890 if (x == 0) 12891 return (0); 12892 if (x >= 256) { 12893 device_printf(sc->sc_dev, 12894 "out of bounds of the square-root table (%d)\n", x); 12895 return (16); 12896 } 12897 return (sqrt_table[x - 1] / 10); 12898} 12899 12900static int 12901bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12902{ 12903#define CALC_COEFF(_v, _x, _y, _z) do { \ 12904 int _t; \ 12905 _t = _x - 20; \ 12906 if (_t >= 0) { \ 12907 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12908 } else { \ 12909 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12910 } \ 12911} while (0) 12912#define CALC_COEFF2(_v, _x, _y, _z) do { \ 12913 int _t; \ 12914 _t = _x - 11; \ 12915 if (_t >= 0) \ 12916 tmp[3] = (_y << (31 - _x)) / (_z >> _t); \ 12917 else \ 12918 tmp[3] = (_y << (31 - _x)) / (_z << -_t); \ 12919} while (0) 12920 struct bwn_phy_lp_iq_est ie; 12921 uint16_t v0, v1; 12922 int tmp[2], ret; 12923 12924 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12925 v0 = v1 >> 8; 12926 v1 |= 0xff; 12927 12928 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12929 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12930 12931 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12932 if (ret == 0) 12933 goto done; 12934 12935 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12936 ret = 0; 12937 goto done; 12938 } 12939 12940 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12941 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12942 12943 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12944 v0 = tmp[0] >> 3; 12945 v1 = tmp[1] >> 4; 12946done: 12947 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12948 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12949 return ret; 12950#undef CALC_COEFF 12951#undef CALC_COEFF2 12952} 12953 12954static void 12955bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12956{ 12957 static const uint16_t noisescale[] = { 12958 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12959 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12960 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12961 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12962 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12963 }; 12964 static const uint16_t crsgainnft[] = { 12965 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12966 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12967 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12968 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12969 0x013d, 12970 }; 12971 static const uint16_t filterctl[] = { 12972 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12973 0xff53, 0x0127, 12974 }; 12975 static const uint32_t psctl[] = { 12976 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12977 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12978 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12979 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12980 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12981 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12982 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12983 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12984 }; 12985 static const uint16_t ofdmcckgain_r0[] = { 12986 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12987 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12988 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12989 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12990 0x755d, 12991 }; 12992 static const uint16_t ofdmcckgain_r1[] = { 12993 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12994 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12995 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12996 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12997 0x755d, 12998 }; 12999 static const uint16_t gaindelta[] = { 13000 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13001 0x0000, 13002 }; 13003 static const uint32_t txpwrctl[] = { 13004 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 13005 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 13006 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 13007 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 13008 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 13009 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 13010 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 13011 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 13012 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 13013 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 13014 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 13015 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 13016 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 13017 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13018 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13019 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13020 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13021 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13022 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13023 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13024 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13025 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13026 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13027 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13028 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13029 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13030 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13031 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13032 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13033 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13034 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13037 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13039 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13040 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13041 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13042 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 13043 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 13044 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 13045 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 13046 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 13047 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 13048 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 13049 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 13050 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 13051 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 13052 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 13053 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 13054 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 13055 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 13056 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 13057 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 13058 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 13059 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 13060 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 13061 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 13062 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 13063 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 13064 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 13065 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 13066 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 13067 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 13068 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13069 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13070 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13071 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13072 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13073 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13074 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13075 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13076 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13077 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13078 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13079 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13080 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13081 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13082 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13083 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13084 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13085 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13086 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13087 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13088 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13089 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13090 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13091 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13092 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13093 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13094 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13095 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13096 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13097 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13098 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13099 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13100 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13101 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13102 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13103 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13104 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13105 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13106 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13107 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13108 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13109 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13110 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13111 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13112 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13113 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13114 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13115 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13116 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13117 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13118 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13119 0x00000702, 13120 }; 13121 13122 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13123 13124 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13125 bwn_tab_sigsq_tbl); 13126 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13127 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13128 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13129 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13130 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13131 bwn_tab_pllfrac_tbl); 13132 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13133 bwn_tabl_iqlocal_tbl); 13134 if (mac->mac_phy.rev == 0) { 13135 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13136 ofdmcckgain_r0); 13137 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13138 ofdmcckgain_r0); 13139 } else { 13140 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13141 ofdmcckgain_r1); 13142 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13143 ofdmcckgain_r1); 13144 } 13145 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13146 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13147} 13148 13149static void 13150bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13151{ 13152 struct siba_dev_softc *sd = mac->mac_sd; 13153 struct siba_softc *siba = sd->sd_bus; 13154 int i; 13155 static const uint16_t noisescale[] = { 13156 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13157 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13158 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13159 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13160 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13161 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13162 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13163 }; 13164 static const uint32_t filterctl[] = { 13165 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13166 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13167 }; 13168 static const uint32_t psctl[] = { 13169 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13170 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13171 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13172 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13173 }; 13174 static const uint32_t gainidx[] = { 13175 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13176 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13177 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13178 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13179 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13180 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13181 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13182 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13183 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13184 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13185 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13186 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13187 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13188 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13189 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13190 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13191 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13192 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13193 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13194 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13195 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13196 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13197 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13198 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13199 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13200 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13201 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13202 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13203 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13204 0x0000001a, 0x64ca55ad, 0x0000001a 13205 }; 13206 static const uint16_t auxgainidx[] = { 13207 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13208 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13209 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13210 0x0004, 0x0016 13211 }; 13212 static const uint16_t swctl[] = { 13213 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13214 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13215 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13216 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13217 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13218 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13219 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13220 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13221 }; 13222 static const uint8_t hf[] = { 13223 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13224 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13225 }; 13226 static const uint32_t gainval[] = { 13227 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13228 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13229 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13230 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13231 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13232 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13233 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13235 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13237 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13238 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13239 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13240 0x000000f1, 0x00000000, 0x00000000 13241 }; 13242 static const uint16_t gain[] = { 13243 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13244 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13245 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13246 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13247 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13248 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13251 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13253 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13254 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13255 }; 13256 static const uint32_t papdeps[] = { 13257 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13258 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13259 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13260 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13261 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13262 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13263 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13264 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13265 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13266 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13267 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13268 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13269 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13270 }; 13271 static const uint32_t papdmult[] = { 13272 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13273 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13274 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13275 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13276 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13277 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13278 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13279 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13280 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13281 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13282 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13283 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13284 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13285 }; 13286 static const uint32_t gainidx_a0[] = { 13287 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13288 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13289 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13290 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13291 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13292 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13293 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13294 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13295 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13296 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13297 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13298 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13299 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13300 }; 13301 static const uint16_t auxgainidx_a0[] = { 13302 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13303 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13304 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13305 0x0002, 0x0014 13306 }; 13307 static const uint32_t gainval_a0[] = { 13308 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13309 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13310 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13311 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13312 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13313 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13314 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13315 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13316 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13317 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13318 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13319 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13320 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13321 0x000000f7, 0x00000000, 0x00000000 13322 }; 13323 static const uint16_t gain_a0[] = { 13324 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13325 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13326 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13327 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13328 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13329 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13330 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13331 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13332 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13333 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13334 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13335 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13336 }; 13337 13338 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13339 13340 for (i = 0; i < 704; i++) 13341 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13342 13343 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13344 bwn_tab_sigsq_tbl); 13345 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13346 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13347 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13348 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13349 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13350 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13351 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13352 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13353 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13354 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13355 bwn_tab_pllfrac_tbl); 13356 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13357 bwn_tabl_iqlocal_tbl); 13358 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13359 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13360 13361 if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) { 13362 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13363 gainidx_a0); 13364 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13365 auxgainidx_a0); 13366 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13367 gainval_a0); 13368 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13369 } 13370} 13371 13372static void 13373bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13374{ 13375 struct siba_dev_softc *sd = mac->mac_sd; 13376 struct siba_softc *siba = sd->sd_bus; 13377 struct bwn_softc *sc = mac->mac_sc; 13378 struct ifnet *ifp = sc->sc_ifp; 13379 struct ieee80211com *ic = ifp->if_l2com; 13380 static struct bwn_txgain_entry txgain_r2[] = { 13381 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13382 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13383 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13384 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13385 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13386 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13387 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13388 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13389 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13390 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13391 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13392 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13393 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13394 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13395 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13396 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13397 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13398 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13399 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13400 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13401 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13402 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13403 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13404 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13405 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13406 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13407 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13408 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13409 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13410 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13411 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13412 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13413 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13414 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13415 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13416 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13417 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13418 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13419 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13420 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13421 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13422 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13423 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13424 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13425 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13426 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13427 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13428 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13429 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13430 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13431 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13432 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13433 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13434 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13435 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13436 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13437 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13438 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13439 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13440 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13441 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13442 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13443 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13444 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13445 }; 13446 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13447 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13448 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13449 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13450 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13451 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13452 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13453 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13454 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13455 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13456 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13457 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13458 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13459 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13460 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13461 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13462 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13463 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13464 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13465 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13466 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13467 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13468 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13469 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13470 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13471 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13472 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13473 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13474 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13475 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13476 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13477 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13478 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13479 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13480 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13481 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13482 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13483 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13484 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13485 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13486 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13487 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13488 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13489 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13490 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13491 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13492 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13493 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13494 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13495 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13496 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13497 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13498 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13499 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13500 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13501 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13502 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13503 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13504 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13505 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13506 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13507 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13508 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13509 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13510 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13511 }; 13512 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13513 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13514 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13515 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13516 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13517 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13518 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13519 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13520 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13521 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13522 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13523 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13524 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13525 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13526 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13527 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13528 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13529 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13530 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13531 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13532 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13533 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13534 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13535 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13536 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13537 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13538 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13539 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13540 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13541 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13542 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13543 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13544 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13545 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13546 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13547 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13548 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13549 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13550 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13551 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13552 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13553 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13554 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13555 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13556 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13557 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13558 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13559 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13560 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13561 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13562 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13563 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13564 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13565 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13566 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13567 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13568 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13569 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13570 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13571 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13572 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13573 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13574 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13575 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13576 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13577 }; 13578 static struct bwn_txgain_entry txgain_r0[] = { 13579 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13580 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13581 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13582 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13583 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13584 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13585 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13586 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13587 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13588 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13589 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13590 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13591 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13592 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13593 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13594 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13595 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13596 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13597 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13598 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13599 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13600 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13601 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13602 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13603 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13604 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13605 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13606 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13607 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13608 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13609 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13610 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13611 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13612 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13613 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13614 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13615 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13616 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13617 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13618 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13619 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13620 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13621 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13622 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13623 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13624 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13625 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13626 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13627 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13628 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13629 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13630 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13631 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13632 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13633 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13634 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13635 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13636 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13637 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13638 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13639 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13640 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13641 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13642 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13643 }; 13644 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13645 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13646 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13647 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13648 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13649 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13650 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13651 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13652 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13653 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13654 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13655 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13656 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13657 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13658 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13659 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13660 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13661 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13662 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13663 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13664 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13665 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13666 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13667 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13668 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13669 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13670 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13671 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13672 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13673 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13674 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13675 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13676 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13677 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13678 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13679 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13680 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13681 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13682 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13683 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13684 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13685 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13686 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13687 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13688 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13689 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13690 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13691 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13692 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13693 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13694 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13695 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13696 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13697 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13698 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13699 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13700 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13701 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13702 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13703 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13704 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13705 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13706 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13707 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13708 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13709 }; 13710 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13711 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13712 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13713 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13714 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13715 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13716 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13717 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13718 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13719 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13720 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13721 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13722 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13723 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13724 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13725 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13726 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13727 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13728 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13729 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13730 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13731 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13732 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13733 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13734 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13735 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13736 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13737 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13738 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13739 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13740 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13741 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13742 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13743 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13744 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13745 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13746 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13747 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13748 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13749 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13750 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13751 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13752 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13753 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13754 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13755 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13756 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13757 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13758 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13759 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13760 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13761 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13762 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13763 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13764 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13765 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13766 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13767 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13768 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13769 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13770 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13771 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13772 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13773 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13774 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13775 }; 13776 static struct bwn_txgain_entry txgain_r1[] = { 13777 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13778 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13779 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13780 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13781 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13782 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13783 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13784 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13785 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13786 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13787 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13788 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13789 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13790 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13791 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13792 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13793 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13794 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13795 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13796 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13797 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13798 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13799 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13800 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13801 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13802 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13803 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13804 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13805 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13806 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13807 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13808 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13809 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13810 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13811 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13812 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13813 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13814 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13815 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13816 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13817 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13818 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13819 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13820 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13821 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13822 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13823 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13824 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13825 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13826 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13827 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13828 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13829 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13830 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13831 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13832 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13833 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13834 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13835 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13836 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13837 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13838 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13839 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13840 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13841 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13842 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13843 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13844 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13845 { 7, 11, 6, 0, 71 } 13846 }; 13847 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13848 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13849 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13850 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13851 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13852 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13853 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13854 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13855 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13856 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13857 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13858 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13859 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13860 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13861 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13862 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13863 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13864 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13865 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13866 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13867 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13868 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13869 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13870 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13871 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13872 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13873 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13874 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13875 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13876 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13877 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13878 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13879 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13880 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13881 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13882 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13883 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13884 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13885 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13886 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13887 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13888 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13889 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13890 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13891 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13892 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13893 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13894 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13895 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13896 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13897 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13898 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13899 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13900 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13901 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13902 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13903 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13904 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13905 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13906 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13907 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13908 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13909 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13910 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13911 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13912 }; 13913 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13914 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13915 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13916 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13917 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13918 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13919 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13920 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13921 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13922 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13923 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13924 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13925 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13926 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13927 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13928 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13929 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13930 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13931 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13932 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13933 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13934 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13935 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13936 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13937 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13938 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13939 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13940 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13941 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13942 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13943 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13944 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13945 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13946 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13947 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13948 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13949 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13950 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13951 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13952 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13953 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13954 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13955 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13956 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13957 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13958 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13959 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13960 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13961 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13962 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13963 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13964 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13965 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13966 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13967 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13968 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13969 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13970 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13971 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13972 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13973 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13974 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13975 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13976 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13977 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13978 }; 13979 13980 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13981 if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA) 13982 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13983 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13984 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13985 txgain_2ghz_r2); 13986 else 13987 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13988 txgain_5ghz_r2); 13989 return; 13990 } 13991 13992 if (mac->mac_phy.rev == 0) { 13993 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 13994 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 13995 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13996 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13997 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13998 txgain_2ghz_r0); 13999 else 14000 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 14001 txgain_5ghz_r0); 14002 return; 14003 } 14004 14005 if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) || 14006 (siba->siba_sprom.bf_lo & BWN_BFL_HGPA)) 14007 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 14008 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 14009 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 14010 else 14011 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 14012} 14013 14014static void 14015bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 14016{ 14017 uint32_t offset, type; 14018 14019 type = BWN_TAB_GETTYPE(typeoffset); 14020 offset = BWN_TAB_GETOFFSET(typeoffset); 14021 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14022 14023 switch (type) { 14024 case BWN_TAB_8BIT: 14025 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 14026 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14027 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14028 break; 14029 case BWN_TAB_16BIT: 14030 KASSERT(!(value & ~0xffff), 14031 ("%s:%d: fail", __func__, __LINE__)); 14032 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14033 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14034 break; 14035 case BWN_TAB_32BIT: 14036 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14037 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 14038 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 14039 break; 14040 default: 14041 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14042 } 14043} 14044 14045static int 14046bwn_phy_lp_loopback(struct bwn_mac *mac) 14047{ 14048 struct bwn_phy_lp_iq_est ie; 14049 int i, index = -1; 14050 uint32_t tmp; 14051 14052 memset(&ie, 0, sizeof(ie)); 14053 14054 bwn_phy_lp_set_trsw_over(mac, 1, 1); 14055 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 14056 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 14057 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 14058 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 14059 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 14060 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 14061 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 14062 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 14063 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 14064 for (i = 0; i < 32; i++) { 14065 bwn_phy_lp_set_rxgain_idx(mac, i); 14066 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 14067 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 14068 continue; 14069 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 14070 if ((tmp > 4000) && (tmp < 10000)) { 14071 index = i; 14072 break; 14073 } 14074 } 14075 bwn_phy_lp_ddfs_turnoff(mac); 14076 return (index); 14077} 14078 14079static void 14080bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 14081{ 14082 14083 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 14084} 14085 14086static void 14087bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 14088 int incr1, int incr2, int scale_idx) 14089{ 14090 14091 bwn_phy_lp_ddfs_turnoff(mac); 14092 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 14093 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 14094 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14095 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14096 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14097 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14098 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14099 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14100 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14101 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14102} 14103 14104static uint8_t 14105bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14106 struct bwn_phy_lp_iq_est *ie) 14107{ 14108 int i; 14109 14110 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14111 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14112 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14113 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14114 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14115 14116 for (i = 0; i < 500; i++) { 14117 if (!(BWN_PHY_READ(mac, 14118 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14119 break; 14120 DELAY(1000); 14121 } 14122 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14123 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14124 return 0; 14125 } 14126 14127 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14128 ie->ie_iqprod <<= 16; 14129 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14130 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14131 ie->ie_ipwr <<= 16; 14132 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14133 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14134 ie->ie_qpwr <<= 16; 14135 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14136 14137 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14138 return 1; 14139} 14140 14141static uint32_t 14142bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14143{ 14144 uint32_t offset, type, value; 14145 14146 type = BWN_TAB_GETTYPE(typeoffset); 14147 offset = BWN_TAB_GETOFFSET(typeoffset); 14148 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14149 14150 switch (type) { 14151 case BWN_TAB_8BIT: 14152 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14153 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14154 break; 14155 case BWN_TAB_16BIT: 14156 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14157 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14158 break; 14159 case BWN_TAB_32BIT: 14160 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14161 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14162 value <<= 16; 14163 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14164 break; 14165 default: 14166 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14167 value = 0; 14168 } 14169 14170 return (value); 14171} 14172 14173static void 14174bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14175{ 14176 14177 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14178 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14179} 14180 14181static void 14182bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14183{ 14184 uint16_t ctl; 14185 14186 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14187 ctl |= dac << 7; 14188 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14189} 14190 14191static void 14192bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14193{ 14194 14195 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14196 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14197} 14198 14199static void 14200bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14201{ 14202 14203 if (mac->mac_phy.rev < 2) 14204 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14205 else { 14206 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14207 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14208 } 14209 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14210} 14211 14212static uint16_t 14213bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14214{ 14215 14216 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14217} 14218 14219static uint8_t 14220bwn_nbits(int32_t val) 14221{ 14222 uint32_t tmp; 14223 uint8_t nbits = 0; 14224 14225 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14226 nbits++; 14227 return (nbits); 14228} 14229 14230static void 14231bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14232 struct bwn_txgain_entry *table) 14233{ 14234 int i; 14235 14236 for (i = offset; i < count; i++) 14237 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14238} 14239 14240static void 14241bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14242 struct bwn_txgain_entry data) 14243{ 14244 14245 if (mac->mac_phy.rev >= 2) 14246 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14247 else 14248 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14249} 14250 14251static void 14252bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14253 struct bwn_txgain_entry te) 14254{ 14255 struct bwn_softc *sc = mac->mac_sc; 14256 struct ifnet *ifp = sc->sc_ifp; 14257 struct ieee80211com *ic = ifp->if_l2com; 14258 uint32_t tmp; 14259 14260 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14261 14262 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14263 if (mac->mac_phy.rev >= 3) { 14264 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14265 (0x10 << 24) : (0x70 << 24)); 14266 } else { 14267 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14268 (0x14 << 24) : (0x7f << 24)); 14269 } 14270 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14271 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14272 te.te_bbmult << 20 | te.te_dac << 28); 14273} 14274 14275static void 14276bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14277 struct bwn_txgain_entry te) 14278{ 14279 14280 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14281 14282 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14283 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14284 te.te_dac); 14285 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14286} 14287 14288static void 14289bwn_identify(driver_t *driver, device_t parent) 14290{ 14291 14292 BUS_ADD_CHILD(parent, 0, "bwn", -1); 14293} 14294 14295static device_method_t bwn_methods[] = { 14296 /* Device interface */ 14297 DEVMETHOD(device_identify, bwn_identify), 14298 DEVMETHOD(device_probe, bwn_probe), 14299 DEVMETHOD(device_attach, bwn_attach), 14300 DEVMETHOD(device_detach, bwn_detach), 14301 DEVMETHOD(device_suspend, bwn_suspend), 14302 DEVMETHOD(device_resume, bwn_resume), 14303 { 0,0 } 14304}; 14305static driver_t bwn_driver = { 14306 "bwn", 14307 bwn_methods, 14308 sizeof(struct bwn_softc) 14309}; 14310static devclass_t bwn_devclass; 14311DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14312MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14313MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14314MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14315MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14316